/* =========================================================
   mobile.css — responsive layout for pages that opt-in via
                `class="mobile-friendly"` on the <body>.

   All rules in this file are scoped to `body.mobile-friendly`
   AND only apply below 800 px viewport width. Above 800 px the
   page renders identically to before — desktop is untouched.

   Pages currently opted-in:
     - index.html (landing)

   Other pages can opt-in by:
     1. adding `class="mobile-friendly"` on <body>
     2. linking this stylesheet in their <head>
     3. adding any page-specific mobile rules below
   ========================================================= */


/* ----------------------------------------------------------
   Shared mobile baseline (any opted-in page)
   ---------------------------------------------------------- */
@media (max-width: 799px) {

    body.mobile-friendly {
        /* Reset the desktop "fixed viewport" feel — mobile scrolls. */
        overflow-y: auto;
        overflow-x: hidden;
    }

    /* The mobile gate stays in DOM but never shows on opted-in pages */
    body.mobile-friendly .mobile-gate {
        display: none !important;
    }

    /* Top bar — already compact, just trim padding for narrow viewports */
    body.mobile-friendly .top-bar {
        padding: 12px 16px;
    }
    body.mobile-friendly .top-bar-right {
        gap: 10px;
    }
    body.mobile-friendly .version-tag {
        display: none;  /* low-value chrome, free up space */
    }
}


/* ----------------------------------------------------------
   Landing page — index.html
   ---------------------------------------------------------- */
@media (max-width: 799px) {

    /* The menu-stage was a 3-column flex (panel · wheel · panel)
       — convert to a vertical stack on mobile. `flex: none` is the
       key bit: without it, menu-stage inherits the desktop `flex: 1`
       and grows to fill the viewport, leaving a tall empty gap
       between the content and the scope-bar at the bottom. */
    body.mobile-friendly .menu-stage {
        flex: none;
        flex-direction: column;
        align-items: stretch;
        justify-content: flex-start;
        padding: 24px 20px 16px;
        gap: 28px;
    }

    /* Side panels are already hidden by grading-ui.css at ≤ 880px,
       but force-hide here in case anyone reverts the upstream rule. */
    body.mobile-friendly .side-panel { display: none; }

    /* The chromatic wheel was the desktop hero. On mobile we hide
       it — touch interactions don't pair well with hover-driven
       polar menus, and the labels would overflow narrow viewports.
       The site identity is carried by the brand mark in the top bar
       and the H1 in the hero card below. */
    body.mobile-friendly .wheel-wrap { display: none; }


    /* ─── Hero card (visible only on mobile) ─── */
    body.mobile-friendly .mobile-hero {
        display: flex;
        flex-direction: column;
        gap: 14px;
        padding: 26px 22px 22px;
        background: var(--bg-elev-1);
        border: 1px solid var(--border-subtle);
        border-radius: 4px;
    }

    body.mobile-friendly .mobile-hero-eyebrow {
        font-family: var(--font-mono);
        font-size: 10px;
        color: var(--accent);
        text-transform: uppercase;
        letter-spacing: var(--tracking-wide);
    }

    body.mobile-friendly .mobile-hero h1 {
        font-family: var(--font-ui);
        font-size: 28px;
        font-weight: 500;
        line-height: 1.15;
        letter-spacing: -0.02em;
        color: var(--text-primary);
        margin: 0;
    }
    body.mobile-friendly .mobile-hero h1 .accent {
        color: var(--accent);
    }

    body.mobile-friendly .mobile-hero-tagline {
        font-family: var(--font-ui);
        font-size: 14px;
        line-height: 1.55;
        color: var(--text-secondary);
        margin: 0;
    }
    body.mobile-friendly .mobile-hero-tagline strong {
        color: var(--text-primary);
        font-weight: 500;
    }

    /* Desktop-only callout — explicit, friendly, links to mobile-OK pages */
    body.mobile-friendly .mobile-hero-callout {
        margin-top: 6px;
        padding: 12px 14px;
        font-family: var(--font-mono);
        font-size: 11px;
        color: var(--text-tertiary);
        background: var(--bg-elev-2);
        border-left: 2px solid var(--accent);
        border-radius: 2px;
        line-height: 1.5;
    }
    body.mobile-friendly .mobile-hero-callout strong {
        color: var(--text-secondary);
        font-weight: 500;
    }


    /* ─── Mobile nav cards (replaces the orbital menu) ─── */
    body.mobile-friendly .mobile-nav {
        display: flex;
        flex-direction: column;
        gap: 8px;
    }

    body.mobile-friendly .mobile-nav-item {
        display: flex;
        align-items: center;
        gap: 14px;
        padding: 16px 18px;
        background: var(--bg-elev-1);
        border: 1px solid var(--border-subtle);
        border-radius: 3px;
        text-decoration: none;
        color: inherit;
        transition:
            border-color var(--t-fast),
            background var(--t-fast),
            transform var(--t-fast);
        text-align: left;
    }
    body.mobile-friendly .mobile-nav-item:active {
        transform: scale(0.98);
        border-color: var(--accent);
        background: var(--accent-soft);
    }

    body.mobile-friendly .mobile-nav-num {
        font-family: var(--font-mono);
        font-size: 10px;
        color: var(--accent);
        letter-spacing: var(--tracking-mono);
        flex-shrink: 0;
        width: 22px;
    }

    body.mobile-friendly .mobile-nav-text {
        flex: 1;
        display: flex;
        flex-direction: column;
        gap: 2px;
        min-width: 0;
    }
    body.mobile-friendly .mobile-nav-label {
        font-family: var(--font-ui);
        font-size: 16px;
        font-weight: 500;
        color: var(--text-primary);
        letter-spacing: -0.005em;
        text-transform: lowercase;
    }
    body.mobile-friendly .mobile-nav-desc {
        font-family: var(--font-mono);
        font-size: 10px;
        color: var(--text-tertiary);
        text-transform: uppercase;
        letter-spacing: var(--tracking-wide);
    }

    /* Arrow chevron on the right of each nav card */
    body.mobile-friendly .mobile-nav-arrow {
        font-family: var(--font-mono);
        font-size: 14px;
        color: var(--text-quaternary);
        flex-shrink: 0;
    }


    /* ─── Nickname input on mobile (full width below nav) ─── */
    body.mobile-friendly .mobile-nick {
        display: flex;
        flex-direction: column;
        gap: 8px;
        padding: 18px 18px 16px;
        background: var(--bg-elev-1);
        border: 1px solid var(--border-subtle);
        border-radius: 3px;
    }
    body.mobile-friendly .mobile-nick-label {
        font-family: var(--font-mono);
        font-size: 10px;
        text-transform: uppercase;
        letter-spacing: var(--tracking-wide);
        color: var(--text-tertiary);
    }
    body.mobile-friendly .mobile-nick input {
        width: 100%;
        background: transparent;
        border: none;
        border-bottom: 1px solid var(--border-subtle);
        color: var(--text-primary);
        font-family: var(--font-mono);
        font-size: 15px;
        padding: 6px 0;
        outline: none;
        letter-spacing: var(--tracking-mono);
        /* 16px+ prevents iOS Safari from zooming on focus */
    }
    body.mobile-friendly .mobile-nick input:focus {
        border-bottom-color: var(--accent);
    }
    body.mobile-friendly .mobile-nick-hint {
        font-family: var(--font-mono);
        font-size: 10px;
        color: var(--text-quaternary);
        text-transform: uppercase;
        letter-spacing: var(--tracking-wide);
        margin-top: 2px;
    }


    /* ─── Scope bar simplified ─── */
    body.mobile-friendly .scope-bar {
        flex-direction: column;
        align-items: stretch;
        gap: 16px;
        padding: 16px 20px 24px;
    }
    /* Hide the live scopes + tone curve on mobile — they're
       decorative without the grading workflow behind them. */
    body.mobile-friendly .scope-group { display: none; }
    body.mobile-friendly .scope-cta {
        /* Override the desktop "push right on row" pattern — on mobile
           we want the CTAs centered full-width below the (hidden) scopes. */
        margin-left: 0;
        align-self: stretch;
        justify-content: center;
        flex-wrap: wrap;
        gap: 10px;
    }
    body.mobile-friendly .scope-cta .cta-link {
        flex: 1;
        justify-content: center;
        min-width: 120px;
        /* Slightly larger tap target than the desktop chip */
        padding: 12px 22px;
        font-size: 13px;
    }


    /* The decorative SVG filter, background layers, overlays —
       keep them for visual continuity, no layout changes needed. */
}


/* ----------------------------------------------------------
   Solo setup page — solo.html
   ----------------------------------------------------------
   The desktop layout is already a single column under 980 px
   (see setup.css). At < 800 px we just trim padding, scale the
   giant "20:00" duration display, make the duration ticks
   touch-friendlier, and stack the back-link + summary footer. */
@media (max-width: 799px) {

    body.mobile-friendly .setup-stage {
        flex: none;             /* don't expand vertically, see landing notes */
        padding: 24px 20px 24px;
        overflow: visible;       /* let the page scroll naturally */
    }

    body.mobile-friendly .setup-title {
        font-size: 24px;
        margin-bottom: 28px;
    }

    body.mobile-friendly .setup-grid {
        gap: 0;                  /* single column already on mobile */
    }
    body.mobile-friendly .setup-grid--single {
        grid-template-columns: 1fr;
    }
    body.mobile-friendly .setup-controls {
        max-width: none;
        gap: 24px;
    }

    /* Duration display — was 56 px, way too big for narrow viewports. */
    body.mobile-friendly .duration-display {
        font-size: 42px;
    }
    body.mobile-friendly .duration-display .unit {
        font-size: 10px;
        margin-left: 8px;
    }

    /* Duration ticks — they're flex:1 so they auto-distribute width.
       At 7 ticks across ~335 px (375 - 2×20 padding) that's ~48 px
       each, plenty for a touch target. Just bump the label slightly
       so it stays legible at the small width. */
    body.mobile-friendly .duration-track {
        height: 48px;
    }
    body.mobile-friendly .dur-tick-label {
        font-size: 11px;
    }

    /* Native <select>s on iOS Safari zoom the viewport on focus when
       the font-size is < 16 px — explicit 16 px prevents that. */
    body.mobile-friendly .challenge-select {
        font-size: 16px;
        padding: 12px 36px 12px 14px;
        max-width: none;
    }

    /* Toggle — slightly bigger tap target on the slider itself */
    body.mobile-friendly .toggle {
        gap: 14px;
        padding: 6px 0;
    }
    body.mobile-friendly .toggle-text {
        font-size: 14px;
        flex: 1;
    }

    /* Start button — full width is fine on desktop already; just
       bump the touch target on mobile. */
    body.mobile-friendly .btn-start {
        padding: 20px 22px;
        font-size: 13px;
    }

    /* Footer — stack "back to menu" and the summary chips instead
       of fighting for width on a narrow row. */
    body.mobile-friendly .setup-footer {
        flex-direction: column;
        align-items: flex-start;
        gap: 16px;
        margin-top: 28px;
    }
    body.mobile-friendly .setup-summary {
        flex-wrap: wrap;
        gap: 8px 12px;
        font-size: 11px;
    }
    body.mobile-friendly .setup-summary .dot-sep {
        display: none;   /* the wrap takes care of separation */
    }
}


/* ----------------------------------------------------------
   Game / session page — game.html
   ----------------------------------------------------------
   Desktop is a 2-column grid (preview · 360 px rail). On mobile
   we collapse to a single column and let the page scroll
   naturally: preview → timer bar → time + challenge + download
   + upload, all stacked. The preview frame gets a fixed
   aspect ratio so it doesn't try to fill the full viewport
   height (which would push everything else below the fold). */
@media (max-width: 799px) {

    /* Top-bar pills on game.html — squeeze them so they fit at 375 px.
       The "challenge XXX" pill is hidden because the same id is shown
       again in the challenge rail block below — no info lost, and
       the row stays on a single line with the brand. */
    body.mobile-friendly .game-header-pills {
        gap: 6px;
        flex-wrap: wrap;
        justify-content: flex-end;
    }
    body.mobile-friendly .game-header-pills .pill {
        padding: 5px 9px;
        font-size: 9px;
        gap: 6px;
    }
    body.mobile-friendly .game-header-pills #pill-challenge,
    body.mobile-friendly .game-header-pills .pill:has(#pill-challenge) {
        display: none;
    }

    /* On pages with a dense pill row (game.html / room.html), the
       brand text + pills + auth widget no longer fit on a 375 px row
       and the brand wraps onto two lines. Hide the
       text part — the logo mark is enough identity once the user is
       inside a session. Other pages keep the full "grading-game"
       wordmark. */
    body.mobile-friendly .top-bar:has(.game-header-pills) .brand-name {
        display: none;
    }
    body.mobile-friendly .top-bar .brand-mark svg {
        width: 18px;
        height: 18px;
    }

    /* Game stage: grid → single column, scroll naturally */
    body.mobile-friendly .game-stage {
        flex: none;
        display: flex;
        flex-direction: column;
        gap: 20px;
        padding: 16px 16px 24px;
        overflow: visible;
        min-height: 0;
    }

    /* Preview area — fixed aspect ratio frame so it doesn't eat
       the whole viewport on a tall phone. 4:3 is a good fit for
       most landscape RAWs without over-cropping. */
    body.mobile-friendly .preview-area {
        gap: 10px;
    }
    body.mobile-friendly .preview-frame {
        flex: none;
        aspect-ratio: 4 / 3;
        min-height: 200px;
    }
    body.mobile-friendly .preview-header {
        flex-wrap: wrap;
        gap: 4px 12px;
    }
    body.mobile-friendly .preview-meta { font-size: 9px; }

    /* Timer bar — keep, just trim a touch */
    body.mobile-friendly .timer-bar-wrap { height: 40px; }

    /* Right rail collapses into a normal column */
    body.mobile-friendly .game-rail {
        gap: 20px;
        overflow-y: visible;
    }
    body.mobile-friendly .rail-block {
        padding-bottom: 18px;
        gap: 8px;
    }

    /* Time remaining — reduce to keep it from dominating */
    body.mobile-friendly .timer-display {
        font-size: 36px;
    }

    /* Action buttons (download + submit) — keep them touch-friendly */
    body.mobile-friendly .action-btn,
    body.mobile-friendly .btn-submit {
        padding: 16px 18px;
        font-size: 12px;
    }

    /* Drop zone — slightly more compact on mobile */
    body.mobile-friendly .drop-zone {
        padding: 22px 16px;
    }
    body.mobile-friendly .drop-icon { font-size: 28px; }
    body.mobile-friendly .drop-text { font-size: 13px; }
    body.mobile-friendly .drop-sub  { font-size: 10px; }

    /* Challenge title gets cramped on a small viewport — drop the
       size a bit so it doesn't wrap awkwardly. */
    body.mobile-friendly .challenge-title { font-size: 15px; }
    body.mobile-friendly .challenge-meta  { font-size: 10px; }

    /* Attribution mini block — stack rows tighter */
    body.mobile-friendly .attribution-mini { gap: 4px; }
}


/* ----------------------------------------------------------
   Result / comparison page — result.html
   ----------------------------------------------------------
   Desktop is a side-by-side 2-column grid OR a wipe overlay. On
   mobile we stack the two images vertically in side-by-side mode
   (each gets a 4:3 frame), keep the wipe layout intact (the
   container already aspect-locks), and stack the footer rows. */
@media (max-width: 799px) {

    body.mobile-friendly .result-stage {
        flex: none;
        padding: 16px 16px 24px;
        overflow: visible;
    }

    /* Header: stack title above meta on a narrow row */
    body.mobile-friendly .result-header {
        flex-direction: column;
        align-items: flex-start;
        gap: 10px;
        margin-bottom: 18px;
        padding-bottom: 14px;
    }
    body.mobile-friendly .result-title { font-size: 22px; }
    body.mobile-friendly .result-meta {
        flex-wrap: wrap;
        gap: 6px 14px;
        font-size: 10px;
    }
    body.mobile-friendly .result-meta .dot-sep { display: none; }

    /* View switcher — slightly bigger tap targets */
    body.mobile-friendly .view-switcher {
        align-self: stretch;
        justify-content: center;
        margin-bottom: 12px;
    }
    body.mobile-friendly .view-btn {
        flex: 1;
        justify-content: center;
        padding: 10px 12px;
        font-size: 11px;
    }

    /* Side-by-side: stack the two images vertically (single col) */
    body.mobile-friendly .compare-views {
        flex: none;
    }
    body.mobile-friendly .compare-grid.cols-2,
    body.mobile-friendly .compare-grid.cols-3 {
        grid-template-columns: 1fr;
        gap: 16px;
    }
    body.mobile-friendly .compare-cell {
        gap: 8px;
    }
    /* Without an explicit height the flex:1 collapses on a column
       grid — pin each frame to a 4:3 aspect ratio for a clean stack. */
    body.mobile-friendly .compare-frame {
        flex: none;
        aspect-ratio: 4 / 3;
        min-height: 200px;
    }

    /* Wipe view — the container already centers via aspect-lock.
       Just bump the handle slightly so it's easier to touch-drag. */
    body.mobile-friendly .wipe-stage {
        flex: none;
        min-height: 240px;
    }
    body.mobile-friendly .wipe-labels {
        flex-wrap: wrap;
        gap: 4px 12px;
        font-size: 10px;
    }
    body.mobile-friendly .wipe-handle {
        width: 36px;
        height: 36px;
        font-size: 16px;
    }

    /* Footer: stack back-link above the two action buttons */
    body.mobile-friendly .result-footer {
        flex-direction: column;
        align-items: stretch;
        gap: 14px;
        margin-top: 20px;
    }
    body.mobile-friendly .result-actions {
        flex-wrap: wrap;
        gap: 10px;
    }
    body.mobile-friendly .result-action {
        flex: 1;
        min-width: 140px;
        justify-content: center;
        padding: 12px 16px;
        font-size: 11px;
    }
}


/* ----------------------------------------------------------
   Multi lobby page — multi.html
   ----------------------------------------------------------
   Desktop lobby has a 2-column hero (title block · identity card)
   and a wide room grid. On mobile we collapse everything to a
   single readable column. The create-room modal also needs a
   gentler padding so it fits at 375 px. */
@media (max-width: 799px) {

    body.mobile-friendly .lobby-stage {
        flex: none;
        padding: 16px 16px 24px;
        gap: 24px;
    }

    /* Hero: title above identity card, no more 2-col grid */
    body.mobile-friendly .lobby-hero {
        display: flex;
        flex-direction: column;
        gap: 18px;
        padding-bottom: 18px;
    }
    body.mobile-friendly .hero-title { font-size: 26px; }
    body.mobile-friendly .identity-card { min-width: 0; }
    /* Native input zoom-on-focus on iOS is suppressed when font-size >= 16 px */
    body.mobile-friendly .identity-input { font-size: 16px; }

    /* Section heads: keep on one row but allow wrap */
    body.mobile-friendly .section-head {
        flex-wrap: wrap;
        gap: 4px 16px;
        margin-bottom: 12px;
    }

    /* Room grid: single column on narrow viewport (the desktop
       auto-fill already collapses well, but we trim the gap). */
    body.mobile-friendly .room-grid {
        grid-template-columns: 1fr;
        gap: 10px;
    }

    /* Join-by-code: stack input above the join button */
    body.mobile-friendly .join-section {
        grid-template-columns: 1fr;
        gap: 10px;
        max-width: none;
    }
    body.mobile-friendly .code-input {
        font-size: 22px;          /* already large enough, no iOS zoom issue */
        padding: 14px 16px;
        text-align: center;
    }
    body.mobile-friendly .btn-join {
        justify-content: center;
        padding: 14px 16px;
    }

    /* Demo banner (status) — keep one row but smaller font */
    body.mobile-friendly .demo-banner {
        font-size: 10px;
        padding: 8px 12px;
    }

    /* ----- Create-room modal ----- */
    body.mobile-friendly .modal-card {
        width: 100%;
        max-width: none;
        height: 100%;             /* full-screen on mobile */
        max-height: 100%;
        padding: 22px 18px;
        gap: 18px;
        border-radius: 0;
        overflow-y: auto;          /* scroll inside the modal if it overflows */
    }
    body.mobile-friendly .modal-title { font-size: 18px; }

    /* Radios fight for width — bump the gap down, tweak padding */
    body.mobile-friendly .radio-row {
        gap: 6px;
        flex-wrap: wrap;
    }
    body.mobile-friendly .radio-option {
        padding: 9px 8px;
        font-size: 10px;
        min-width: 0;
        flex: 1 1 calc(50% - 6px); /* let categories (3 items) wrap onto 2 rows */
    }
    body.mobile-friendly .radio-option .opt-sub {
        font-size: 8px;
    }

    /* Modal Start button (same .btn-start as solo) — covered by the
       solo block above; nothing extra needed here. */
}


/* ----------------------------------------------------------
   Multiplayer room — room.html (4 states)
   ----------------------------------------------------------
   The most complex page: 4 state panels (lobby / playing /
   gallery / result) share a single header (.room-bar) and a
   single page container. Each state has its own desktop grid
   that we collapse to single-column on mobile. */
@media (max-width: 799px) {

    /* ----- ROOM BAR (always visible) ---------------------- */
    /* Desktop: brand · player-chips · state · code · quit, all
       on a single grid row. At 375 px that breaks badly — we
       collapse to a flexible 2-row layout with code + leave on
       top and player chips scrolling horizontally below. */
    body.mobile-friendly .room-bar {
        display: flex;
        flex-wrap: wrap;
        gap: 10px;
        padding: 10px 12px;
        align-items: center;
        row-gap: 8px;
    }
    /* Brand mark only (text hidden) — same idea as game.html */
    body.mobile-friendly .room-bar .brand-name { display: none; }
    body.mobile-friendly .room-bar .brand-mark svg { width: 18px; height: 18px; }

    /* "state · lobby" pill drops a couple of px */
    body.mobile-friendly .room-bar-state { font-size: 9px; gap: 4px; }
    body.mobile-friendly .room-bar-code { padding: 3px 9px; gap: 6px; }
    body.mobile-friendly .room-bar-code-val { font-size: 13px; }
    body.mobile-friendly .room-bar-quit { font-size: 10px; padding: 5px 8px; }

    /* Player chips fight for the same row as everything else.
       Allow them to scroll horizontally on a second row so the
       header never wraps over more than 2 lines. */
    body.mobile-friendly .room-bar-players {
        flex: 1 1 100%;
        order: 99;                /* push to last position (= second row) */
        overflow-x: auto;
        -webkit-overflow-scrolling: touch;
        scrollbar-width: none;
        padding: 2px 0 4px;
    }
    body.mobile-friendly .room-bar-players::-webkit-scrollbar { display: none; }
    body.mobile-friendly .player-chip {
        flex-shrink: 0;
        font-size: 10px;
        padding: 3px 9px;
    }


    /* ----- STATE: LOBBY ---------------------------------- */
    body.mobile-friendly .state-lobby {
        flex: none;
        padding: 16px 16px 24px;
        gap: 18px;
        overflow: visible;
        align-items: stretch;
    }
    body.mobile-friendly .lobby-title {
        font-size: 22px;
        text-align: center;
    }
    body.mobile-friendly .lobby-code-display {
        align-self: stretch;
        text-align: center;
    }
    body.mobile-friendly .lobby-code-big {
        font-size: 38px;
        letter-spacing: 0.18em;
    }
    body.mobile-friendly .lobby-grid {
        grid-template-columns: 1fr;
        gap: 14px;
        max-width: none;
    }
    body.mobile-friendly .lobby-card { padding: 16px; }

    /* "start" button is wide on desktop; keep that and just bump
       the tap target on mobile */
    body.mobile-friendly .btn-room-start {
        width: 100%;
        padding: 18px 20px;
        font-size: 12px;
    }


    /* ----- STATE: PLAYING -------------------------------- */
    /* Same shape as game.html: 2-col grid → single column. */
    body.mobile-friendly .state-playing {
        grid-template-columns: 1fr;
        gap: 18px;
        padding: 16px 16px 24px;
        overflow: visible;
    }
    body.mobile-friendly .state-playing.is-active { display: flex; flex-direction: column; }
    body.mobile-friendly .play-preview-frame {
        flex: none;
        aspect-ratio: 4 / 3;
        min-height: 200px;
    }
    body.mobile-friendly .play-rail {
        gap: 18px;
        overflow-y: visible;
    }
    body.mobile-friendly .play-block { padding-bottom: 16px; }

    /* Player chips were also showing in the room-bar — drop the
       big timer-display height a touch */
    body.mobile-friendly #play-timer-display { font-size: 36px; }


    /* ----- STATE: GALLERY (voting) ----------------------- */
    body.mobile-friendly .state-gallery {
        padding: 16px 16px 20px;
        gap: 14px;
        overflow: visible;
        flex: none;
    }
    body.mobile-friendly .state-gallery.is-active {
        display: flex;
        flex-direction: column;
    }
    body.mobile-friendly .gallery-head {
        flex-direction: column;
        align-items: flex-start;
        gap: 8px;
    }
    body.mobile-friendly .gallery-title { font-size: 22px; }
    body.mobile-friendly .gallery-sub  { font-size: 11px; }
    body.mobile-friendly .gallery-grid {
        grid-template-columns: 1fr;
        gap: 14px;
        overflow: visible;
        padding-right: 0;
    }
    /* Stars: make them bigger touch targets — desktop's 22 px is
       too tight for a thumb. */
    body.mobile-friendly .star-btn {
        width: 32px;
        height: 32px;
        font-size: 22px;
    }
    body.mobile-friendly .submission-meta {
        padding: 14px 14px;
        gap: 12px;
        flex-wrap: wrap;
    }
    body.mobile-friendly .gallery-footer {
        flex-direction: column;
        align-items: stretch;
        gap: 10px;
    }
    body.mobile-friendly #finalize-votes {
        width: 100% !important;       /* overrides the inline style="width:auto" */
        justify-content: center;
    }


    /* ----- STATE: RESULT (podium + scoreboard) ----------- */
    body.mobile-friendly .state-result {
        padding: 16px 16px 24px;
        gap: 18px;
        overflow: visible;
        flex: none;
    }
    body.mobile-friendly .state-result.is-active {
        display: flex;
        flex-direction: column;
    }
    body.mobile-friendly .result-title-2 { font-size: 24px; }
    body.mobile-friendly .result-winner  { font-size: 14px; }

    /* Podium: 3 columns → vertical stack, winner first */
    body.mobile-friendly .podium {
        grid-template-columns: 1fr;
        gap: 14px;
        align-items: stretch;
        max-width: none;
    }
    /* All cells now have the same square-ish ratio (no taller-
       winner trick since they're stacked anyway). */
    body.mobile-friendly .podium-cell.is-first  .podium-cell-img,
    body.mobile-friendly .podium-cell.is-second .podium-cell-img,
    body.mobile-friendly .podium-cell.is-third  .podium-cell-img {
        aspect-ratio: 4 / 3;
    }

    /* Scoreboard: 4-column grid (rank · name · stars · votes)
       gets tight at 375 px. Drop the gap, smaller columns. */
    body.mobile-friendly .scoreboard {
        max-width: none;
        margin-top: 8px;
    }
    body.mobile-friendly .scoreboard-head,
    body.mobile-friendly .score-row {
        grid-template-columns: 28px 1fr 60px 60px;
        gap: 8px;
        font-size: 11px;
    }
    body.mobile-friendly .scoreboard-head { font-size: 8px; }

    body.mobile-friendly .result-actions {
        flex-direction: column;
        align-items: stretch;
        gap: 10px;
    }
    body.mobile-friendly .result-action {
        flex: 1;
        justify-content: center;
        padding: 14px 16px;
        font-size: 12px;
    }


    /* ----- Dev switcher (only when ?dev=1) -------------- */
    /* Make it scroll if the buttons overflow */
    body.mobile-friendly .dev-switcher {
        bottom: 8px;
        right: 8px;
        left: 8px;
        flex-wrap: wrap;
        justify-content: center;
    }
}


/* ----------------------------------------------------------
   Gallery page — gallery.html
   ----------------------------------------------------------
   The grid already collapses well thanks to auto-fill minmax(180 px).
   On a 375 px viewport that gives 2 columns naturally. We just trim
   padding, tighten the anonymous-sign-in banner, and bump tap
   targets a touch. */
@media (max-width: 799px) {

    body.mobile-friendly .gallery-stage {
        flex: none;
        padding: 24px 16px 24px;
        overflow: visible;
    }
    body.mobile-friendly .gallery-inner { gap: 20px; }
    body.mobile-friendly .gallery-title { font-size: 24px; }
    body.mobile-friendly .gallery-intro { font-size: 14px; max-width: none; }

    /* Anonymous banner stacks text above CTA on narrow rows */
    body.mobile-friendly .gallery-anon-banner {
        flex-direction: column;
        align-items: stretch;
        gap: 12px;
        padding: 14px 16px;
    }
    body.mobile-friendly .gallery-anon-cta {
        justify-content: center;
    }

    /* Gallery grid → vertical list of compact rows on mobile.
       Desktop's Pokédex (square thumb · id · photographer below) eats
       ~80% of the viewport for a single card on a 375 px phone, so
       we flip the card into a row: small 60×60 thumb on the left,
       id + photographer inline on the right. The whole grid becomes
       a tighter scrollable list. */
    body.mobile-friendly .gallery-grid {
        grid-template-columns: 1fr;
        gap: 8px;
    }
    body.mobile-friendly .gallery-card {
        flex-direction: row;
        align-items: center;
        gap: 12px;
        padding: 6px 12px 6px 6px;
    }
    body.mobile-friendly .gallery-card-frame {
        flex: none;
        width: 64px;
        height: 64px;
        aspect-ratio: auto;
        border-radius: 2px;
    }
    /* Lock icon scales down to fit the smaller thumbnail */
    body.mobile-friendly .gallery-card-lock {
        width: 22px !important;
        height: 22px !important;
    }
    /* Info row sits next to the thumb instead of below it */
    body.mobile-friendly .gallery-card-info {
        flex: 1;
        min-width: 0;
        padding: 0;
        border-top: none;
        gap: 12px;
    }
    body.mobile-friendly .gallery-card-id { font-size: 14px; }
    body.mobile-friendly .gallery-card-photographer {
        font-size: 10px;
        max-width: none;
    }
}


/* ----------------------------------------------------------
   Contributors page — contributors.html
   ----------------------------------------------------------
   The contributor grid is similar shape to gallery. The bigger
   change is the inline contribution form: the two-column "first
   name · last name" row collapses to a single column, all inputs
   get 16 px font (no iOS zoom on focus), and tap targets bump. */
@media (max-width: 799px) {

    body.mobile-friendly .contributors-stage {
        flex: none;
        padding: 24px 16px 24px;
        overflow: visible;
    }
    body.mobile-friendly .contributors-inner { gap: 20px; }
    body.mobile-friendly .contributors-title { font-size: 24px; }
    body.mobile-friendly .contributors-intro { font-size: 14px; }

    body.mobile-friendly .contributors-meta-row {
        flex-wrap: wrap;
        gap: 4px 14px;
        font-size: 11px;
    }

    /* Contributor grid: single column on narrow viewport */
    body.mobile-friendly .contributors-grid {
        grid-template-columns: 1fr;
        gap: 10px;
    }

    /* "Want to contribute?" CTA block */
    body.mobile-friendly .contributors-cta { padding: 22px 18px; }
    body.mobile-friendly .contributors-cta-title { font-size: 18px; }
    body.mobile-friendly .contributors-cta-body { font-size: 14px; }

    /* Form: stack the first-name / last-name row */
    body.mobile-friendly .contribute-row {
        grid-template-columns: 1fr;
        gap: 14px;
    }
    body.mobile-friendly .contribute-field input,
    body.mobile-friendly .contribute-field textarea {
        font-size: 16px;          /* prevents iOS Safari focus-zoom */
        padding: 10px 12px;
    }
    body.mobile-friendly .contribute-actions {
        flex-direction: column;
        align-items: stretch;
        gap: 10px;
    }
    body.mobile-friendly .contribute-submit {
        justify-content: center;
        padding: 14px 16px;
    }
    body.mobile-friendly .contribute-tip {
        font-size: 12px;
    }
    body.mobile-friendly .contribute-tip code {
        word-break: break-all;
        font-size: 11px;
    }
}


/* ----------------------------------------------------------
   About page — about.html
   ----------------------------------------------------------
   The page uses inline <style> for its layout, so we just need
   to shrink the title and trim the numbered-list indent so the
   numbers don't shove the body text off-screen. */
@media (max-width: 799px) {

    body.mobile-friendly .about-stage {
        flex: none;
        padding: 24px 16px 24px;
        align-items: stretch;
        justify-content: flex-start;
    }
    body.mobile-friendly .about-title { font-size: 26px; }
    body.mobile-friendly .about-body p { font-size: 14px; }

    /* Numbered rules: tighter indent on mobile */
    body.mobile-friendly .rules-list li {
        padding-left: 40px;
        font-size: 14px;
    }
}


/* ----------------------------------------------------------
   Info page — info.html (credits + patch notes)
   ----------------------------------------------------------
   The credit cards and patch-cols already collapse to single
   column at the 900 px breakpoint in info.css. We only need to
   trim outer padding + scale the hero title for narrow viewports. */
@media (max-width: 799px) {

    body.mobile-friendly .info-stage {
        flex: none;
        padding: 24px 16px 24px;
        overflow: visible;
    }
    body.mobile-friendly .info-title { font-size: 24px; }
    body.mobile-friendly .info-section-title { font-size: 22px; }
    body.mobile-friendly .info-section-intro { font-size: 14px; }

    /* TOC: keep 2-col (2 entries — fits) but tighten */
    body.mobile-friendly .info-toc { padding: 10px; gap: 8px; }
    body.mobile-friendly .info-toc-item { padding: 8px 10px; }

    /* Credit cards: padding shrink, links stack */
    body.mobile-friendly .credit-card { padding: 18px 16px; }
    body.mobile-friendly .credit-card-title { font-size: 18px; }

    /* Patch cards */
    body.mobile-friendly .patch-card { padding: 18px 16px; }
    body.mobile-friendly .patch-version { font-size: 22px; }
    body.mobile-friendly .patch-name { font-size: 15px; }
}


/* ----------------------------------------------------------
   Legal page — legal.html
   ----------------------------------------------------------
   Three-column sticky TOC + long-form text sections. The TOC
   3-col grid stays as it is (with smaller text); we trim outer
   padding and shrink section headings so they breathe better. */
@media (max-width: 799px) {

    body.mobile-friendly .legal-stage {
        flex: none;
        padding: 24px 16px 24px;
        overflow: visible;
    }
    body.mobile-friendly .legal-title { font-size: 24px; }
    body.mobile-friendly .legal-section-title { font-size: 20px; }
    body.mobile-friendly .legal-section-intro { font-size: 14px; }
    body.mobile-friendly .legal-section p,
    body.mobile-friendly .legal-section li { font-size: 13px; }

    /* TOC: 3 cols × 108 px @ 375 px is too narrow for the longest
       labels ("COPYRIGHT & DMCA") so they truncate to "COPYRI…".
       Stack to a single column on mobile — each row stays fully
       readable and tappable. */
    body.mobile-friendly .legal-toc {
        grid-template-columns: 1fr;
        padding: 10px;
        gap: 6px;
    }
    body.mobile-friendly .legal-toc-item { padding: 10px 12px; gap: 8px; }
    body.mobile-friendly .legal-toc-label { font-size: 10px; }

    body.mobile-friendly .legal-section h3 { font-size: 14px; }
}


/* ----------------------------------------------------------
   Profile page — profile.html
   ----------------------------------------------------------
   Stats grid already auto-fills to 1-2 cols on a 375 px viewport
   thanks to its minmax(160 px). We mostly trim the outer padding,
   shrink the giant 28 px display name + 88 px avatar, and stack
   the settings rows (sign-out / delete) for thumb-friendly tap. */
@media (max-width: 799px) {

    body.mobile-friendly .profile-stage {
        flex: none;
        padding: 24px 16px 24px;
        overflow: visible;
    }
    body.mobile-friendly .profile-inner { gap: 18px; }

    /* Anonymous state */
    body.mobile-friendly .profile-title-big { font-size: 24px; }
    body.mobile-friendly .profile-intro     { font-size: 14px; }
    body.mobile-friendly .profile-cta-signin {
        width: 100%;
        justify-content: center;
        padding: 14px 18px;
        font-size: 12px;
    }

    /* Authenticated hero: avatar + identity stay on one row but the
       avatar shrinks so the display name still fits before wrap. */
    body.mobile-friendly .profile-hero {
        gap: 16px;
        padding: 4px 0;
    }
    body.mobile-friendly .profile-avatar {
        width: 64px;
        height: 64px;
    }
    body.mobile-friendly .profile-avatar-fallback { font-size: 28px; }
    body.mobile-friendly .profile-display-name    { font-size: 22px; }
    body.mobile-friendly .profile-handle          { font-size: 12px; }

    /* Stats grid: tighten gap + bump tap targets a touch */
    body.mobile-friendly .profile-stats-grid {
        grid-template-columns: repeat(2, 1fr);
        gap: 10px;
    }
    body.mobile-friendly .stat-card    { padding: 14px 14px; }
    body.mobile-friendly .stat-value   { font-size: 22px; }

    /* Settings rows: stack label + button on narrow viewports.
       Each row keeps the same card style but the button drops
       full-width below the title/description. */
    body.mobile-friendly .setting-row {
        flex-direction: column;
        align-items: stretch;
        gap: 12px;
    }
    body.mobile-friendly .setting-row .setting-btn,
    body.mobile-friendly .setting-row > button {
        width: 100%;
        justify-content: center;
        padding: 12px 14px;
    }
}


/* ----------------------------------------------------------
   The mobile-only elements (mobile-hero, mobile-nav, mobile-nick)
   live in the DOM at all times but are hidden above 800 px so they
   don't interfere with the desktop layout.
   ---------------------------------------------------------- */
.mobile-hero,
.mobile-nav,
.mobile-nick {
    display: none;
}
