/* Bubble Shooter
   The canvas is sized entirely here; layout() in script.js only syncs the
   backing store to whatever size CSS settled on.

   Flat periwinkle surround, pale lavender play field, and a purple stats rail
   on the right carrying the title, the yellow star for the level and the golden
   cup for the high score. Everything here is opaque on purpose: a translucent
   panel over the board just muddies it.

   The three surfaces are one hue at three lightnesses -- page, rail, board,
   lightest last -- so keep them in that order if you retune them. The board has
   to stay the lightest thing on screen or the bubbles stop reading as sitting
   on top of it. */

:root {
    /* Saturated periwinkle surround, pale lavender play field. Three steps of
       one purple: the page is deepest, the rail sits between, the board is
       lightest. That ordering is what makes the rail read as part of the frame
       around the board rather than as a second, competing panel. */
    --page: #a49cf4;
    --board: #e8e6f9;
    --board-glow: rgba(80, 60, 160, 0.22);

    --rail: #b7aef5;
    --rail-slot: #8b82e8;
    --rail-line: rgba(76, 54, 152, 0.30);
    --rail-glow: rgba(80, 60, 160, 0.22);

    --ink: #241a4d;
    --ink-2: #4a4079;
    --ink-3: #7b74a4;

    --gold: #fcff3d;
    --gold-deep: #ffc94c;

    /* These six mirror the ball palette in script.js. They are what the rainbow
       chip sweeps through, so if the balls move, move these with them or the
       booster stops looking like it is made of the board's bubbles. */
    --red: #f04432;
    --yellow: #f5b817;
    --green: #0d9668;
    --cyan: #06b6d4;
    --blue: #1d4ed8;
    --purple: #b52bd3;

    --teal: #0cc0df;
    --accent: #8b5cf6;

    --white: #fcfbfb;
    --shadow-sm: 0 2px 4px rgba(10, 20, 50, 0.25);
    --shadow-md: 0 6px 20px rgba(10, 20, 50, 0.30);
    --shadow-lg: 0 18px 48px rgba(5, 10, 30, 0.45);

    --tap: 46px;
    --radius: 18px;
}

* { box-sizing: border-box; }

html { color-scheme: light; }

/* --- Background --------------------------------------------------------- */
/* Flat light purple. The animated teal gradient and the bokeh/facet overlays
   that used to sit on top of it are gone: against a white play field they read
   as noise, and the spec calls for one solid colour behind the board. */
body {
    margin: 0;
    min-height: 100svh;
    background: var(--page);
    color: var(--ink);
    font-family: Nunito, system-ui, -apple-system, "Segoe UI", sans-serif;
    font-weight: 700;
    -webkit-font-smoothing: antialiased;
    -webkit-tap-highlight-color: transparent;
    overflow-x: hidden;
}

.sprite { position: absolute; width: 0; height: 0; overflow: hidden; }

svg { width: 1em; height: 1em; fill: currentColor; display: block; }

/* --- Shell ------------------------------------------------------------- */
.app {
    position: relative;
    z-index: 1;
    min-height: 100svh;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: clamp(14px, 3vw, 40px);

    /* Named, because --shell-h below has to subtract exactly this twice. It used
       to subtract a hard 32px against a padding that clamps up to 26px a side,
       so on any wide window the shell came out 20px taller than the viewport and
       the whole page scrolled by that much. */
    --pad: clamp(10px, 2vw, 26px);
    padding: var(--pad);

    /* The board and the rail MUST resolve to the same height, and both must be
       centred the same way. They used to compute it separately, and the rail
       also stretched: a stretched flex item that hits a max-height stops
       filling and pins to the TOP, so on any viewport taller than the cap the
       rail sat high while the board stayed centred -- visibly out of line, with
       the gap growing as the window got taller. One value, read by both.

       Three limits, smallest wins:
         1. the viewport height, less padding -- the usual case, and what makes
            fullscreen actually FILL the screen instead of floating a small
            board in the middle of it;
         2. the width left over once the rail and the gaps are paid for. The
            board is portrait (804/468 = 1.718 tall per wide), so height drives
            width; without this a tall narrow window grows the canvas until it
            shoves the rail off the side;
         3. a generous absolute cap, so a 4K panel does not scale the art past
            what the sprites were rendered for. */
    --rail-space: 340px;        /* rail + gap + .app padding */
    --shell-h: min(
        calc(100svh - var(--pad) * 2),
        calc((100vw - var(--rail-space)) * 1.718),
        1200px
    );
}

.board {
    display: flex;
    flex-direction: column;
    /* centre, do NOT stretch: the stage sizes its own width from its aspect
       ratio, and stretching it would overwrite that. */
    align-items: center;
    gap: 10px;
    height: var(--shell-h);
}

/* --- Board -------------------------------------------------------------- */
/* Solid white, no blur or pulsing glow: the canvas paints its own white field
   and any translucency here would let the purple page bleed through it. */
.stage {
    position: relative;
    flex: 1 1 auto;
    min-height: 0;
    /* The board's shape lives HERE, not on the canvas. The canvas is a replaced
       element whose intrinsic width is its backing store, and layout() sets that
       backing store from the canvas's own CSS width -- so sizing the canvas with
       width:auto + max-width:100% made .board content-width itself from the
       canvas and then clamp the canvas back to it. That loop pinned the width at
       468px while height:100% kept growing, which silently stretched the render
       (setTransform scales x and y independently, so bubbles turn into ovals).
       The stage takes its height from flex and derives width from this ratio,
       which depends on nothing downstream, and the canvas just fills it. */
    aspect-ratio: 468 / 804;
    border-radius: var(--radius);
    background: var(--board);
    box-shadow: var(--shadow-lg), 0 0 32px var(--board-glow);
    border: 1.5px solid rgba(255, 255, 255, 0.9);
    overflow: hidden;
}

#viewport {
    display: block;
    /* Fill the stage exactly. Percentages, so the canvas never feeds its own
       intrinsic size back into the layout -- see the note on .stage. */
    width: 100%;
    height: 100%;
    cursor: crosshair;
    touch-action: none;
}

/* --- Dock: shot progress and boosters ---------------------------------- */
.dock {
    /* .board is shrink-to-fit, so its width is whichever child is widest. The
       dock's buttons don't shrink, so on a short window -- where the stage is
       driven down to ~300px by the height -- the dock was the widest child and
       the board grew to fit IT, leaving the dock hanging past both edges of the
       play field. width:0 keeps the dock out of that measurement so the stage
       alone sets the width, and min-width:100% then fills whatever the stage
       settled on. */
    width: 0;
    min-width: 100%;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    padding: 8px 14px;
    border-radius: var(--radius);
    background: var(--rail);
    box-shadow: var(--shadow-md);
    border: 1px solid var(--rail-line);
    flex: none;
}

/* Shot counter: sleek progress dots.
   This is the one thing in the dock that may shrink: the boosters are tap
   targets and must keep their size, so on a narrow board the dots give up the
   room instead. Spent dots are the ones on the RIGHT (see syncHud), so what
   gets clipped is always the part that has already been used up. */
.dots {
    display: flex;
    flex: 0 1 auto;
    min-width: 0;
    overflow: hidden;
    gap: 7px;
    align-items: center;
}

/* Unspent dots are white and spent ones sink into the purple, which is the
   opposite of the old dark dock but keeps the same "filled vs used" read. */
.dot {
    width: 14px;
    height: 14px;
    flex: none;              /* clip the row rather than squash dots into ovals */
    border-radius: 50%;
    background: #ffffff;
    box-shadow: inset 0 -2px 0 rgba(90, 66, 168, .18), 0 1px 2px rgba(60, 40, 120, .2);
    transition: all 0.3s ease;
}

.dot.is-spent {
    background: rgba(120, 100, 180, 0.35);
    box-shadow: inset 0 -2px 0 rgba(60, 40, 120, .2);
    transform: scale(0.85);
}

.dots.is-urgent .dot:not(.is-spent) {
    background: linear-gradient(180deg, #ff6b7a, var(--red));
    box-shadow: 0 0 10px rgba(255,45,85,0.5);
    animation: pip 700ms ease-in-out infinite;
}

@keyframes pip {
    50% { transform: scale(1.25); box-shadow: 0 0 16px rgba(255,45,85,0.7); }
}

.dock__actions { display: flex; gap: 8px; }

/* --- Chips: boosters and swap ------------------------------------------ */
.chip {
    position: relative;
    min-width: var(--tap);
    min-height: var(--tap);
    padding: 4px 10px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 5px;
    font: inherit;
    font-size: 15px;
    color: var(--ink);
    background: #ffffff;
    border: 1px solid var(--rail-line);
    border-radius: 14px;
    box-shadow: var(--shadow-sm);
    cursor: pointer;
    transition: transform 120ms ease, box-shadow 120ms ease, opacity 120ms ease;
}

.chip:hover {
    transform: translateY(-2px);
    box-shadow: var(--shadow-md), 0 0 20px rgba(139,92,246,0.3);
}
.chip:active { transform: translateY(1px); box-shadow: var(--shadow-sm); }

.chip.is-empty { opacity: .35; cursor: default; }
.chip.is-empty:hover { transform: none; box-shadow: var(--shadow-sm); }

.chip.is-loaded {
    outline: 3px solid var(--gold);
    outline-offset: 1px;
    box-shadow: var(--shadow-sm), 0 0 18px rgba(255,214,10,0.4);
    animation: chipGlow 1.5s ease-in-out infinite alternate;
}

@keyframes chipGlow {
    0%   { box-shadow: var(--shadow-sm), 0 0 14px rgba(255,214,10,0.3); }
    100% { box-shadow: var(--shadow-sm), 0 0 24px rgba(255,214,10,0.6); }
}

.chip--swap { font-size: 20px; color: #0a9db4; }

.chip__ball {
    width: 26px;
    height: 26px;
    border-radius: 50%;
    flex: none;
    box-shadow: inset 0 -3px 5px rgba(0, 0, 0, .3), 0 1px 2px rgba(0, 0, 0, .3);
}

.chip__ball--rainbow {
    background:
        radial-gradient(circle at 34% 30%, rgba(255, 255, 255, .95), rgba(255, 255, 255, 0) 46%),
        conic-gradient(var(--red), var(--yellow), var(--green), var(--cyan), var(--blue), var(--purple), var(--red));
}

.chip__ball--bomb {
    background: radial-gradient(circle at 34% 30%, #8b93b5 0%, #3c4160 38%, #12162a 100%);
}

.chip__count {
    font-weight: 900;
    font-variant-numeric: tabular-nums;
    min-width: 1ch;
}

.chip__key {
    position: absolute;
    right: 4px;
    bottom: 2px;
    font-size: 9px;
    font-weight: 800;
    color: var(--ink-3);
}

/* --- Rail -------------------------------------------------------------- */
.rail {
    width: clamp(180px, 22vw, 240px);
    /* No align-self here: inherit .app's centring so this tracks the board. */
    height: var(--shell-h);
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 18px;
    padding: 22px 18px;
    border-radius: 22px;
    background: var(--rail);
    box-shadow: var(--shadow-lg), 0 0 32px var(--rail-glow);
    border: 1px solid var(--rail-line);
}

.logo {
    margin: 0;
    display: flex;
    flex-direction: column;
    align-items: center;
    line-height: .96;
    font-family: Fredoka, Nunito, sans-serif;
    font-weight: 700;
    font-size: clamp(22px, 2.4vw, 30px);
    letter-spacing: .5px;
    text-transform: uppercase;
    /* Gold fill, white keyline, then a deep purple drop. On the old dark rail
       the white stroke alone held the letters; against light purple it needs
       the dark offset underneath or the title dissolves into the panel. */
    color: var(--gold-deep);
    -webkit-text-stroke: 3px var(--white);
    paint-order: stroke fill;
    text-shadow:
        0 3px 0 #4b2f9e,
        0 5px 0 rgba(40, 22, 90, .45);
}

.stats {
    width: 100%;
    display: flex;
    flex-direction: column;
    gap: 16px;
}

.stat { display: flex; flex-direction: column; align-items: center; }

/* Yellow star marks the level, golden cup the high score. Both keep a white
   keyline and a purple drop so the gold still separates from the light panel. */
.stat__badge {
    position: relative;
    font-size: 46px;
    filter: drop-shadow(0 3px 0 rgba(75, 47, 158, .45));
    margin-bottom: -10px;
    z-index: 1;
}

.stat__badge--star { color: var(--gold); }
.stat__badge--trophy { color: var(--gold-deep); }
.stat__badge--coin { color: var(--gold); font-size: 28px; margin-bottom: 0; }

.stat__badge svg { stroke: var(--white); stroke-width: 1.4px; }

.stat__tag {
    position: absolute;
    right: -26px;
    bottom: 4px;
    font-size: 13px;
    font-weight: 800;
    color: var(--white);
    text-shadow: 0 2px 0 rgba(60, 38, 130, .75);
}

/* Sunken purple slot, a shade deeper than the rail, with the number knocked out
   in white. The old white-slot-with-dark-text version competed with the board
   for attention; recessing it keeps the eye on the play field. */
.stat__value {
    width: 100%;
    padding: 9px 10px;
    border-radius: 12px;
    background: var(--rail-slot);
    box-shadow: inset 0 2px 5px rgba(50, 32, 110, .35);
    border: 0;
    border-bottom: 4px solid #766fd5;
    text-align: center;
    font-size: 20px;
    font-weight: 900;
    font-variant-numeric: tabular-nums;
    color: var(--white);
    transition: transform 0.15s ease;
}

/* Gold, so the best score reads as the trophy's number rather than the level's */
.stat__value--best { color: #ffe259; }

/* Coin display */
.stat--coin {
    flex-direction: row;
    gap: 8px;
    padding: 8px 12px;
    border-radius: 12px;
    background: rgba(255, 255, 255, 0.28);
    border: 1px solid rgba(255, 226, 89, 0.45);
}

.stat--coin .stat__value {
    background: transparent;
    box-shadow: none;
    border: none;
    padding: 0;
    font-size: 17px;
    color: #ffe259;
    width: auto;
}

/* --- Combo Badge ------------------------------------------------------- */
.combo {
    padding: 6px 18px;
    border-radius: 999px;
    font-size: 16px;
    font-weight: 900;
    color: var(--white);
    background: linear-gradient(135deg, var(--accent), #6d28d9);
    box-shadow: 0 0 12px rgba(139,92,246,0.3);
    border: 1.5px solid rgba(255,255,255,0.25);
    opacity: 0;
    transform: scale(.6);
    transition: opacity 200ms ease, transform 300ms cubic-bezier(0.34, 1.56, 0.64, 1), box-shadow 200ms ease;
}

.combo.is-live {
    opacity: 1;
    transform: scale(1);
    animation: comboPulse 1.2s ease-in-out infinite;
}

@keyframes comboPulse {
    0%, 100% {
        box-shadow: 0 0 12px rgba(139,92,246,0.3);
        transform: scale(1);
    }
    50% {
        box-shadow: 0 0 28px rgba(139,92,246,0.6), 0 0 50px rgba(139,92,246,0.2);
        transform: scale(1.08);
    }
}

/* --- Volume: speaker + slider ------------------------------------------- */
/* The slider is collapsed to nothing until the control is hovered or something
   inside it takes focus, so the rail stays uncluttered but the level is one
   movement away -- the pattern a video player uses. It is NOT hidden with
   display:none: the width transition needs a box to animate, and a display flip
   would also drop it out of the tab order. */
.vol {
    display: flex;
    align-items: center;
    gap: 6px;
    padding: 4px;
    border-radius: 999px;
    background: rgba(255, 255, 255, .16);
    border: 1px solid var(--rail-line);
}

.vol__slider {
    -webkit-appearance: none;
    appearance: none;
    width: 0;
    min-width: 0;
    opacity: 0;
    height: 6px;
    margin: 0;
    border-radius: 999px;
    background: rgba(76, 54, 152, .28);
    cursor: pointer;
    transition: width .18s ease, opacity .18s ease;
}

.vol:hover .vol__slider,
.vol:focus-within .vol__slider { width: 84px; opacity: 1; }

.vol__slider::-webkit-slider-thumb {
    -webkit-appearance: none;
    appearance: none;
    width: 14px;
    height: 14px;
    border-radius: 50%;
    background: var(--white);
    border: 2px solid var(--accent);
    cursor: pointer;
}

.vol__slider::-moz-range-thumb {
    width: 14px;
    height: 14px;
    border: 2px solid var(--accent);
    border-radius: 50%;
    background: var(--white);
    cursor: pointer;
}

/* Muted or silent: the speaker reads off, and the wave stroke in the icon is
   dropped so the glyph itself says so rather than only the colour. */
.vol[data-level="off"] .vol__btn { color: var(--ink-3); }
.vol[data-level="off"] .vol__btn .wave { display: none; }
.vol[data-level="low"] .vol__btn .wave { opacity: .45; }
.vol[data-level="mid"] .vol__btn .wave { opacity: .75; }

/* No hover to reveal it with, so leave it out permanently. */
@media (hover: none) {
    .vol__slider { width: 76px; opacity: 1; }
}

.rail__actions {
    margin-top: auto;
    display: flex;
    gap: 12px;
}

.round {
    width: 56px;
    height: 56px;
    display: grid;
    place-items: center;
    font-size: 26px;
    color: var(--white);
    background: linear-gradient(180deg, #4a9eff, #2d6ed4);
    border: 2.5px solid rgba(255,255,255,0.5);
    border-radius: 15px;
    box-shadow: var(--shadow-md), 0 0 14px rgba(59,130,246,0.25);
    cursor: pointer;
    transition: transform 120ms ease, box-shadow 120ms ease;
}

.round:hover {
    transform: translateY(-2px);
    box-shadow: var(--shadow-md), 0 0 24px rgba(59,130,246,0.4);
}
.round:active { transform: translateY(1px); }

/* --- Panels ------------------------------------------------------------ */
.panel {
    position: absolute;
    inset: 0;
    display: none;
    align-items: center;
    justify-content: center;
    padding: 16px;
    background: rgba(10, 10, 30, .6);
    backdrop-filter: blur(6px);
    z-index: 5;
}

.panel.is-open { display: flex; }

.panel__card {
    position: relative;
    width: 100%;
    max-width: 380px;
    max-height: 100%;
    overflow-y: auto;
    padding: 24px 22px 22px;
    border-radius: 22px;
    background: var(--white);
    box-shadow: var(--shadow-lg), 0 0 40px rgba(139,92,246,0.15);
    border: 1px solid rgba(255,255,255,0.5);
}

.panel__x {
    position: absolute;
    top: 10px;
    right: 10px;
    width: var(--tap);
    height: var(--tap);
    display: grid;
    place-items: center;
    font-size: 17px;
    color: var(--ink-3);
    background: transparent;
    border: 0;
    border-radius: 12px;
    cursor: pointer;
}

.panel__x:hover { background: #f0f0f8; color: var(--ink); }

.panel__card h2 {
    margin: 0 0 8px;
    padding-right: 44px;
    font-family: Fredoka, Nunito, sans-serif;
    font-size: 25px;
    font-weight: 700;
    color: var(--accent);
}

.panel__lead { margin: 0 0 16px; font-size: 14.5px; font-weight: 600; color: var(--ink-2); }
.panel__lead b { color: var(--ink); }

.panel__note {
    margin: 16px 0;
    padding: 11px 13px;
    border-radius: 12px;
    background: #f2f2fb;
    font-size: 13px;
    font-weight: 600;
    color: var(--ink-2);
}

.keys {
    display: grid;
    grid-template-columns: auto 1fr;
    gap: 8px 14px;
    margin: 0;
    font-size: 13.5px;
}

.keys dt { font-weight: 800; color: var(--ink); white-space: nowrap; }
.keys dd { margin: 0; font-weight: 600; color: var(--ink-2); }

kbd {
    display: inline-block;
    padding: 1px 7px;
    border-radius: 6px;
    background: #ececf8;
    box-shadow: inset 0 -2px 0 rgba(90, 88, 150, .2);
    font: inherit;
    font-size: 12px;
    font-weight: 800;
}

.toggles { display: flex; flex-direction: column; gap: 9px; }

.toggle {
    display: flex;
    align-items: center;
    gap: 11px;
    width: 100%;
    min-height: var(--tap);
    padding: 9px 13px;
    font: inherit;
    font-size: 14.5px;
    font-weight: 700;
    color: var(--ink);
    text-align: left;
    background: #f4f4fc;
    border: 2px solid transparent;
    border-radius: 13px;
    cursor: pointer;
}

.toggle svg { font-size: 20px; color: var(--ink-3); flex: none; }
.toggle__label { flex: 1; }

.toggle__state {
    position: relative;
    width: 42px;
    height: 24px;
    flex: none;
    border-radius: 999px;
    background: #c9cae0;
    transition: background 140ms ease;
}

.toggle__state::after {
    content: "";
    position: absolute;
    top: 3px;
    left: 3px;
    width: 18px;
    height: 18px;
    border-radius: 50%;
    background: var(--white);
    box-shadow: 0 1px 3px rgba(0, 0, 0, .3);
    transition: transform 140ms ease;
}

#hud-soundBtn:not(.is-off) .toggle__state,
#hud-symbolsBtn.is-on .toggle__state { background: #22c55e; }

#hud-soundBtn:not(.is-off) .toggle__state::after,
#hud-symbolsBtn.is-on .toggle__state::after { transform: translateX(18px); }

#hud-soundBtn:not(.is-off) svg,
#hud-symbolsBtn.is-on svg { color: var(--accent); }

#hud-soundBtn.is-off .wave { display: none; }

.btn {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    width: 100%;
    min-height: var(--tap);
    margin-top: 9px;
    padding: 11px 16px;
    font: inherit;
    font-size: 15px;
    font-weight: 800;
    color: var(--ink);
    background: #eeeef8;
    border: 0;
    border-radius: 13px;
    cursor: pointer;
    transition: transform 120ms ease, filter 120ms ease;
}

.btn svg { font-size: 18px; }
.btn:hover { transform: translateY(-1px); filter: brightness(.97); }
.btn:active { transform: translateY(1px); }

.btn--primary {
    color: var(--white);
    background: linear-gradient(180deg, #4a9eff, #2d6ed4);
    box-shadow: 0 0 14px rgba(59,130,246,0.25);
}
.btn--danger {
    color: var(--white);
    background: linear-gradient(180deg, #ff5a6e, #d4243c);
    box-shadow: 0 0 14px rgba(255,45,85,0.2);
}

/* --- Focus and motion --------------------------------------------------- */
button:focus-visible,
canvas:focus-visible {
    outline: 3px solid var(--accent);
    outline-offset: 2px;
}

@media (prefers-reduced-motion: reduce) {
    * { animation: none !important; transition: none !important; }
}

/* --- Short screens: the dock tightens up -------------------------------- */
/* Side by side, the board's width follows from its height, so a 720p-class
   laptop gets a ~290px board and the dock has to fit its dots and all three
   boosters into that. Trimming the paddings and a few pixels off each control
   is enough to keep the whole shot counter visible; the buttons stay well above
   40px, so they are still comfortable to hit. Scoped to the side-by-side
   layout: below it the board is a full 468px and none of this is needed. */
@media (min-width: 721px) and (min-height: 621px) and (max-height: 860px) {
    .dock { padding: 7px 10px; gap: 8px; }
    .dock__actions { gap: 6px; }

    .chip { min-width: 40px; min-height: 40px; padding: 3px 8px; gap: 4px; font-size: 14px; }
    .chip--swap { font-size: 18px; }
    .chip__ball { width: 22px; height: 22px; }

    .dots { gap: 5px; }
    .dot { width: 12px; height: 12px; }
}

/* --- Narrow screens: the rail moves under the board --------------------- */
@media (max-width: 720px), (max-height: 620px) {
    .app {
        flex-direction: column;
        justify-content: flex-start;
        gap: 10px;
    }

    .board { height: auto; width: 100%; max-width: 468px; }

    /* Stacked: width comes from the column, height follows from the ratio the
       stage still carries, so the canvas keeps filling it at 100%/100%. */
    .stage { flex: none; width: 100%; }

    .rail {
        width: 100%;
        max-width: 468px;
        height: auto;            /* stacked under the board, so no shared height */
        flex-direction: row;
        flex-wrap: wrap;
        align-items: center;
        justify-content: space-between;
        gap: 12px;
        padding: 12px 14px;
        border-radius: 18px;
    }

    .logo { flex-direction: row; gap: 7px; font-size: 19px; }

    .stats { flex: 1; flex-direction: row; width: auto; gap: 12px; }

    .stat { flex-direction: row; align-items: center; gap: 8px; }

    .stat__badge { font-size: 28px; margin: 0; }
    .stat__tag { position: static; margin-left: 3px; }

    .stat__value { width: auto; min-width: 74px; padding: 6px 10px; font-size: 16px; }

    .stat--coin { padding: 4px 10px; }

    .combo { order: 3; }

    /* Stacked, the rail is a single row, so the volume control sits with the
       other buttons at the end of it rather than on its own line. */
    .vol { order: 4; padding: 3px; }
    .vol__slider { width: 62px; opacity: 1; }

    .rail__actions { margin: 0; order: 5; }

    .round { width: var(--tap); height: var(--tap); font-size: 22px; border-width: 2px; }
}
