    /* ════════════════════════════════════════════════════════════
       PHONES & SMALL TABLETS
       ════════════════════════════════════════════════════════════

       The tenth stylesheet, and the only one that is NOT a chunk of the
       original main.css. It is linked LAST, after glass.css, on purpose:
       every other sheet was written for a 1280-wide window, several of
       them with `!important`, and a media query does not outrank a plain
       rule from a later file. Last link = last word, which is what a
       responsive layer needs. Nothing in here applies above 820px, so
       the desktop cascade is untouched.

       What was actually broken before this existed (measured at 390x844):

       1. `#dynamic-island` is a centred pill holding all eight tabs in one
          un-wrapping row. It measured 819px wide, so ~215px hung off each
          edge and Street, Drive, Badges, Talk and Help could not be tapped
          at all — Playwright reported "element is outside of the viewport"
          and gave up. That, not the styling, is why "not all features work"
          on a phone.
       2. `#hud` is a single flex row with no shrink: the read-aloud and
          mute buttons sat 26-125px past the right edge, and on a 320 screen
          the evolution bar went with them.
       3. `#stats` is a five-column grid whose items default to
          `min-width:auto`, so the Rest bar was pushed under the ▶ arrow.
       4. `.screen { height: 100vh }` is taller than the visible area on a
          phone browser, so the bottom row hid behind the URL bar.

       The tab bar wraps to two rows rather than scrolling sideways: a
       scroller hides tabs behind a gesture five-year-olds do not know to
       make, which is the same bug in a nicer coat. Two rows is also a
       FIXED height, which is what lets the panels below use one padding. */

    @media (max-width: 820px) {

      /* Viewport units: dvh follows the phone chrome as it slides away.
         100vh is left as the fallback for anything that lacks it. */
      .screen {
        height: 100dvh;
      }

      /* Taps: no 300ms delay, no double-tap zoom on a button, no grey
         flash, and no rubber-band scroll behind the game. */
      button,
      .top-nav-btn,
      .stat,
      .menu-card,
      .edu-opt,
      .dest-card,
      .pic-icon,
      .talk-q {
        touch-action: manipulation;
        -webkit-tap-highlight-color: transparent;
      }

      html,
      body {
        overscroll-behavior: none;
      }

      /* ── TOP NAV ── full width, wrapped, every tab reachable ── */
      #dynamic-island {
        left: 6px;
        right: 6px;
        transform: none;
        top: 58px;
        border-radius: 22px;
      }

      .top-nav-bar {
        flex-wrap: wrap;
        justify-content: center;
        gap: 2px;
        padding: 5px 4px;
      }

      /* Icon over label, so a tab is a square target instead of a wide one.
         `flex: 1 1 78px` puts four on a 390 row and three on a 320 one, and
         44px min-height is the smallest comfortable touch target. */
      .top-nav-btn {
        flex: 1 1 78px;
        flex-direction: column;
        gap: 1px;
        min-height: 44px;
        padding: 5px 4px;
        font-size: 10.5px;
        border-radius: 14px;
      }

      .top-nav-btn .top-nav-icon svg {
        width: 19px;
        height: 19px;
      }

      .top-nav-label {
        line-height: 1;
      }

      /* The message line under the tabs shares the island, so it wraps with
         it rather than forcing the pill wider. */
      #di-notif {
        padding: 0 12px;
        font-size: 12px;
      }

      #dynamic-island.notif-show #di-notif {
        padding: 8px 12px 11px;
      }

      /* Panels start below a two-row island (58 top + ~96 tabs + breathing
         room) instead of the desktop's one-row 120px. */
      #tab-work,
      #tab-ai,
      #tab-leaderboard {
        padding-top: 168px;
      }

      /* ── HUD ── one row that shrinks, never a row that overflows ── */
      #hud {
        padding: 8px;
        padding-top: max(8px, env(safe-area-inset-top, 8px));
        gap: 5px;
      }

      .coinbox {
        font-size: 14px;
        padding: 5px 9px;
        gap: 4px;
      }

      .coinbox .c {
        width: 18px;
        height: 18px;
        font-size: 10px;
      }

      .savebox {
        font-size: 12.5px;
        padding: 4px 8px;
      }

      .petbadge {
        padding: 4px 8px 4px 4px;
        gap: 5px;
        min-width: 0;
      }

      .petbadge .av {
        width: 26px;
        height: 26px;
        font-size: 15px;
      }

      .petbadge .pn {
        font-size: 12px;
        min-width: 0;
        max-width: 84px;
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
      }

      /* The district name repeats in the street signage and the shop bar,
         so it is the one HUD item that can go to keep the row on one line. */
      .petbadge .pn small {
        display: none;
      }

      .evo-bar-wrap {
        min-width: 0;
      }

      .evobadge {
        font-size: 12px;
        padding: 5px 8px;
        border-radius: 14px;
      }

      .evobar {
        width: 56px;
      }

      .evobar-label {
        max-width: 60px;
      }

      #streak-chip {
        font-size: 11px;
        padding: 6px 7px;
      }

      #read-btn,
      #mute-btn {
        width: 34px;
        height: 34px;
        font-size: 15px;
        border-radius: 11px;
      }

      /* ── BOTTOM ROW ── the five stats, all five of them ──
         Grid children are `min-width: auto` by default, which is what let
         the Rest bar push out under the ▶ arrow. */
      #bottom-container {
        left: 6px;
        right: 6px;
        gap: 6px;
      }

      #stats {
        gap: 4px;
      }

      .stat {
        min-width: 0;
        padding: 5px 4px;
        border-radius: 10px;
      }

      .stat .lab {
        font-size: 10px;
        white-space: nowrap;
        overflow: hidden;
        text-overflow: ellipsis;
      }

      .stat .bar {
        height: 7px;
        margin-top: 4px;
      }

      .nav-arrow-btn {
        width: 46px !important;
        height: 46px !important;
        font-size: 18px !important;
      }

      /* A long shop name used to run off both sides of this button — and at
         26% of a short screen it slid up behind the two-row tab bar, so it
         is pinned just under the island instead of to a percentage. */
      #enter-now,
      #game-screen.stats-hidden #enter-now {
        top: 178px;
        font-size: 14px;
        padding: 10px 18px;
        max-width: calc(100vw - 28px);
        white-space: normal;
        text-align: center;
        line-height: 1.2;
      }

      /* ── INSIDE A SHOP ── */
      #inside-bar {
        padding: 8px;
        padding-top: max(8px, env(safe-area-inset-top, 8px));
        gap: 6px;
      }

      #inside-title {
        font-size: 14px;
        min-width: 0;
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
      }

      .leavebtn {
        font-size: 12.5px;
        padding: 7px 11px;
        min-height: 38px;
      }

      /* ── SHEETS & OVERLAYS ── clear the home indicator, follow dvh ── */
      .sheet {
        max-height: 88dvh;
        padding-bottom: env(safe-area-inset-bottom, 0px);
      }

      .overlay {
        padding-bottom: 0;
      }

      /* ── MINI-GAMES ── the arenas are fixed-height boxes; on a short
         phone in landscape they would otherwise run off the bottom. */
      .mg-card {
        width: min(96vw, 460px);
        max-height: 92dvh;
        overflow-y: auto;
      }

      /* ── TEACHER DASHBOARD ── ten tabs on a phone: one scrolling row,
         which is fine here because a teacher is not five. */
      .td-tabs {
        overflow-x: auto;
        flex-wrap: nowrap;
        /* flex-start, NOT the desktop's centre: a centred flex row that
           overflows spills equally off both ends, and the left spill cannot
           be scrolled back to — the first tabs become unreachable. */
        justify-content: flex-start;
        /* The desktop strip is full-bleed via `margin: 8px -22px`, which on a
           phone put the first tab four pixels past the left edge. Match the
           narrower gutter instead. */
        margin-left: -10px;
        margin-right: -10px;
        -webkit-overflow-scrolling: touch;
        scrollbar-width: none;
      }

      .td-tabs::-webkit-scrollbar {
        display: none;
      }

      .td-tab {
        flex: 0 0 auto;
      }

      .td-wrap {
        padding-left: 10px;
        padding-right: 10px;
      }

      /* Tables are the one thing that genuinely cannot reflow — let them
         scroll inside their own box instead of widening the page. */
      .td-panel table {
        display: block;
        overflow-x: auto;
        white-space: nowrap;
      }
    }

    /* ── PHONES, one item at a time ──
       The HUD is a single row, so making it fit is a question of which item
       leaves first, not of shrinking everything at once — that is what the
       first pass did, and a 320 screen came back with a pet badge crushed to
       a sliver and "Health" clipped to "Healt". Each item below steps aside
       at the width where it stops fitting, and each one has somewhere else
       to live. ── */

    /* The streak chip goes first: it is a motivator, not a control, and the
       daily popup and the Badges panel both still show it. */
    @media (max-width: 430px) {
      #streak-chip {
        display: none;
      }
    }

    /* iPhone SE and the 320-wide school Chromebooks in portrait. */
    @media (max-width: 360px) {

      .top-nav-btn {
        flex: 1 1 66px;
        font-size: 9.5px;
      }

      /* The name goes, the avatar stays — it is the button that opens the
         profile, where the name is written in full. */
      .petbadge .pn {
        display: none;
      }

      .petbadge {
        padding: 4px;
      }

      /* The evolution NUMBER stays (that is the badge); the progress bar and
         its caption are the part that will not fit, and the same progress is
         on the Badges sheet in full. */
      .evobar,
      .evobar-label {
        display: none;
      }

      /* Headroom for a four-digit coin count. The HUD does not wrap, so an
         item that cannot shrink pushes the row off the edge; leaving ~30px
         spare here is what keeps a rich player's screen intact. */
      .savebox {
        font-size: 11.5px;
        padding: 4px 6px;
      }

      .evobadge {
        font-size: 11px;
        padding: 4px 6px;
      }

      #read-btn,
      #mute-btn {
        width: 30px;
        height: 30px;
        font-size: 13px;
      }

      /* "Health" is the longest label and the one that was showing as
         "Healt" — 8.5px plus a tighter gutter is what fits it whole in a
         fifth of a 320 screen. */
      .stat {
        padding: 5px 3px;
      }

      .stat .lab {
        font-size: 8.5px;
        letter-spacing: 0;
        gap: 2px;
      }

      /* …and the arrows and gutters give up the rest of what the labels
         needed: the five stats only get what is left of the row after both
         arrows have taken their share. */
      .nav-arrow-btn {
        width: 38px !important;
        height: 38px !important;
        font-size: 16px !important;
      }

      #bottom-container {
        left: 4px;
        right: 4px;
        gap: 4px;
      }

      #stats {
        gap: 3px;
      }

      /* Narrower buttons mean more tab rows; the panels start lower to match. */
      #tab-work,
      #tab-ai,
      #tab-leaderboard {
        padding-top: 172px;
      }
    }

    /* ── LANDSCAPE PHONE ── height, not width, is the scarce axis here:
       a 390x844 phone turned sideways is 844x390, so the island and the
       stats row would eat the whole scene. ── */
    @media (max-width: 920px) and (max-height: 460px) {

      #dynamic-island {
        top: 50px;
      }

      /* Back to icon-BESIDE-label: sideways there is width to spare and
         height to save. Wrapping stays ON — an SE in landscape is only 568
         wide, and `nowrap` there would shrink the buttons until their labels
         spilled out of them rather than moving to a second row. */
      .top-nav-btn {
        flex: 0 1 auto;
        flex-direction: row;
        min-height: 36px;
        gap: 5px;
        font-size: 9.5px;
        padding: 4px 8px;
      }

      /* Sized for two short rows, because 568-wide landscape wraps and
         844-wide does not. The cost on the wide one is a few spare pixels. */
      #tab-work,
      #tab-ai,
      #tab-leaderboard {
        padding-top: 128px;
      }

      #stats {
        max-height: 62px;
      }

      #enter-now,
      #game-screen.stats-hidden #enter-now {
        top: 108px;
      }

      .stat .bar {
        height: 6px;
      }
    }
