:root {
      /* -- Palette ------------------------------------------------------ */
      --bg:          rgb(10, 20, 30);
      --panel:       rgba(20, 30, 40, 1.0);
      --bar-bg:      rgba(6, 14, 22, 0.95);   /* tab bar / status bar / mobile nav chrome */
      --border:      rgba(180, 190, 200, 0.12);
      --white:       rgb(235, 245, 255);
      --faint:       rgb(180, 190, 200);
      --orange:      rgb(224, 137, 32);
      --green:       rgb(32, 224, 70);
      --blue:        rgb(32, 189, 224);
      --pink:        rgb(255, 86, 244);
      --red:         rgb(220, 70, 60);        /* stop / danger controls / error log text */
      --faint-orange:rgba(224, 137, 32, 0.15);
      --faint-green: rgba(32, 224, 70,  0.12);
      --faint-red:   rgba(220, 70, 60,  0.12);
      --faint-white: rgba(235, 245, 255, 0.5);
      --dim:         rgba(180, 190, 200, 0.4);

      /* Hover/focus washes (white over dark) + scrollbar thumb. */
      --hover-faint: rgba(235, 245, 255, 0.03);
      --hover:       rgba(235, 245, 255, 0.05);
      --hover-strong:rgba(235, 245, 255, 0.1);
      --surface-key: rgba(235, 245, 255, 0.08);  /* <kbd> face */
      --scroll-thumb:rgba(180, 190, 200, 0.15);

      /* -- Metrics ------------------------------------------------------ */
      --bar: 40px;   /* height of the chrome bars; square edge of their controls */

      /* Type scale. Rem base is 13pt (in line with the brand nav); the old
         16pt-base values scaled by 16/13, snapped to tidy 0.05 steps. */
      --text-lg:  1.35rem;   /* help heading */
      --text:     1rem;      /* body */
      --text-sm:  0.9rem;    /* buttons, tabs, tree rows */
      --text-xs:  0.8rem;    /* captions, status, fine print */
      --text-2xs: 0.75rem;   /* section-title labels */
      --text-3xs: 0.7rem;    /* row badges */

      /* Material Symbols glyph sizes — one set, shared across the UI. */
      --icon-sm: 1rem;       /* inline lock glyphs */
      --icon:    1.25rem;    /* control-bar icons (run/stop, gallery stop) */
      --icon-md: 1.35rem;    /* panel-header action icons */
      --icon-lg: 1.5rem;     /* touch targets (nav arrows, mobile bars) */

      /* Material Symbols variable-axis presets (set once, referenced below). */
      --glyph:        'FILL' 0, 'wght' 400, 'GRAD' 0, 'opsz' 24;
      --glyph-filled: 'FILL' 1, 'wght' 400, 'GRAD' 0, 'opsz' 24;
    }
    *, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }

    html { font-size: 13pt; }   /* rem base (matches the brand nav's 1.2rem) — nudge to scale the whole UI */

    body {
      background: var(--bg);
      color: var(--white);
      font-family: Lexend, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
      font-size: var(--text);
      font-weight: 300;
      display: flex;
      flex-direction: column;
      height: 100dvh;        /* live viewport — resizes with the soft keyboard / Safari chrome */
      overflow: hidden;
      /* Keep content out of the notch / status bar / home indicator. dvh handles
         the keyboard resize; these handle the unsafe edges (needs viewport-fit=cover). */
      padding-top: env(safe-area-inset-top);
      padding-bottom: env(safe-area-inset-bottom);
    }

    /* -- Top brand nav (ported from badgewa.re) --------------------------------
       Same markup and look as the brand site: a full-width bar that turns glassy
       once the page scrolls (.scrolling, toggled by the inline script in index.html).
       Kept in normal flow (a flex child of body) rather than position:fixed so it
       sits above the toolbar without overlapping the fixed-height app layout. */
    nav#main {
      flex-shrink: 0;
      z-index: 1000;
      background-color: var(--bg);
      border-bottom: 1px solid var(--border);
      transition: background 1s;
      user-select: none;
    }
    nav#main.scrolling {
      -webkit-backdrop-filter: blur(2rem);
      backdrop-filter: blur(2rem);
      background-color: rgba(235, 245, 255, 0.1);
    }
    nav#main svg { height: 2.4rem; width: auto; fill: var(--white); }
    nav#main > div {
      font-size: 1.2rem;
      line-height: 1.35;
      padding: 0.5rem 2rem;
      box-sizing: border-box;
      margin: 0 auto;
      display: grid;
      grid-gap: 0rem;
      grid-template-columns: 1fr auto auto auto auto;
      align-items: center;
    }
    nav#main a {
      color: var(--white);
      text-decoration: none;
      display: inline-block;
      padding: 0.2rem 0.75rem 0.3rem 0.75rem;
      border-radius: 2rem;
    }
    nav#main a:first-child { padding-left: 0; }
    nav#main a:not(.buy):hover { text-decoration: underline; }
    nav#main a .nav-new {
      vertical-align: -0.2em;
      margin-left: 0.15rem;
      font-size: 1.15rem;
      line-height: 1;
      color: var(--pink);
    }
    nav#main a.buy {
      background-color: var(--pink);
      color: var(--white);
      margin-left: 0.5rem;
      font-weight: 600;
      padding: 0.3rem 1.1rem 0.4rem;
    }

    /* Material Symbols Outlined (Google): the family + ligature setup come from
       Google's served rule; here we inherit the surrounding size (sized per use
       below) and set the variable axes. FILL 0 = outlined (the default look);
       run/stop override to FILL 1 below since they're primary transport controls. */
    .material-symbols-outlined {
      font-size: inherit;
      line-height: 1;
      vertical-align: middle;
      user-select: none;
      font-variation-settings: var(--glyph);
    }
    /* Run / Stop read as primary actions — keep them solid while the rest stays
       outlined. Targets both the toolbar and the floating mobile bar (and the
       play↔refresh swap) via their data-action, so no per-glyph class is needed. */
    [data-action="run"]  .material-symbols-outlined,
    [data-action="stop"] .material-symbols-outlined { font-variation-settings: var(--glyph-filled); }
    #toolbar button .material-symbols-outlined,
    #toolbar .navbtn .material-symbols-outlined,
    #toolbar .buy .material-symbols-outlined { font-size: var(--icon); }

    /* Playground toolbar: a thin bar beneath the brand nav. Its title sits at the
       left, the view buttons follow, and Help is pushed to the right (margin-auto,
       which needs this flex container to bite). */
    #toolbar {
      display: flex;
      align-items: center;
      gap: 8px;
      flex-shrink: 0;
      padding: 6px 1.6rem;
      background: rgba(10, 20, 30, 0.85);
      border-bottom: 1px solid var(--border);
      user-select: none;
    }
    .toolbar-title {
      font-size: var(--text-sm);
      font-weight: 700;
      letter-spacing: 0.04em;
      text-transform: uppercase;
      color: var(--faint);
      margin-right: 8px;
    }

    /* The Buy link and the font-explorer nav links (.navbtn) share the button shape
       (they're <a>s, hence text-decoration). */
    #toolbar button,
    #toolbar .navbtn,
    #toolbar .buy {
      display: inline-flex;
      align-items: center;
      gap: 3px;
      border: none;
      padding: 4px 12px 4px 8px;
      font-size: var(--text-sm);
      font-family: inherit;
      border-radius: 0.4rem;
      cursor: pointer;
      letter-spacing: 0.02em;
      text-decoration: none;
      transition: filter 0.1s;
      height: var(--bar);

      background: var(--panel);
      color: var(--white);
      font-weight: 400;
      border: 1px solid var(--border);
    }
    #toolbar .help {
      margin-left: auto;
    }
    #toolbar button:hover,  #toolbar .navbtn:hover,  #toolbar .buy:hover  { filter: brightness(1.3); }
    #toolbar button:active, #toolbar .navbtn:active, #toolbar .buy:active { filter: brightness(0.9); }

    #toolbar button.active,
    #toolbar .navbtn.active { border-color: var(--orange); color: var(--orange); }
    #toolbar .navbtn.active { cursor: default; }
    #toolbar .navbtn.active:hover { filter: none; }

    #toolbar button.help {
      position: relative;
      z-index: 6;
      width: var(--bar);
      text-align: center;
    }

    #toolbar .buy { background: var(--pink); color: var(--white) }

    /* -- Main layout ----------------------------------------------- */
    #workspace {
      display: flex;
      flex: 1;
      min-height: 0;
      /* visible so the 3D badge can spill up over the toolbar */
      overflow: visible;
      background: linear-gradient(45deg, rgba(65, 89, 208, 0.3) 0.000%, rgba(200, 79, 192, 0.3) 50.000%, rgba(255, 205, 112, 0.1) 100.000%)
    }

    /* -- Examples page: document-level scroll (like the font explorer) ---------
       The editor keeps its fixed, non-scrolling shell; here the whole page scrolls
       and the brand nav + Playground toolbar (wrapped in .topbar) stay pinned. The
       panels grow to their content (min-height: auto) instead of clipping. Scoped
       to .examples-page and desktop; mobile keeps the tabbed shell below. */
    @media (min-width: 768px) {
      .examples-page { height: auto; min-height: 100dvh; overflow: visible; }
      .examples-page .topbar { position: sticky; top: 0; z-index: 1000; }
      .examples-page #workspace    { min-height: auto; }
      .examples-page #editor-panel { min-height: auto; overflow: visible; }
      .examples-page #gallery      { min-height: auto; overflow: visible; }
    }

    /* -- Editor panel ---------------------------------------------- */
    #editor-panel {
      flex: 1;
      min-width: 0;
      overflow: hidden;
      display: flex;
      flex-direction: column;
    }

    /* -- Tab bar (nav > ul > li; open editor files) ---------------------------
       Structure is conveyed by tags: li = a tab, its first <span> = the name,
       a .material-symbols-outlined <span> = the read-only lock, <button> = close. Only the
       dynamic state (active / dirty / transient) is carried as classes. */
    #tab-bar {
      height: var(--bar);
      display: flex;
      align-items: stretch;
      background: var(--bar-bg);
      border-bottom: 1px solid var(--border);
      flex-shrink: 0;
      overflow: hidden;
    }
    #tab-bar ul {
      flex: 1;
      min-width: 0;
      display: flex;
      align-items: stretch;
      list-style: none;
      overflow-x: auto;
      overflow-y: hidden;
    }
    #tab-bar ul::-webkit-scrollbar { height: 0; }

    /* -- New / Run / Stop controls docked to the right of the tab bar -- */
    #tab-controls {
      display: flex;
      align-items: stretch;
      flex-shrink: 0;
    }
    #stdout button,
    #file-panel button,
    #tab-controls button {
      color: var(--faint-white);
      width: var(--bar);
      display: flex;
      align-items: center;
      justify-content: center;
      background: none;
      border: none;
      border-left: 1px solid var(--border);
      cursor: pointer;
      transition: background 0.12s;
    }

    #stdout button {
      border-color: transparent;
    }

    #stdout button:hover,
    #file-panel button:hover,
    #tab-controls button:hover { color: var(--white); }
    #file-panel .material-symbols-outlined,
    #stdout .material-symbols-outlined,
    #tab-controls .material-symbols-outlined { font-size: var(--icon); }
    #tab-controls [data-action="run"]           { color: var(--green); }
    #tab-controls [data-action="run"]:hover     { background: var(--faint-green); }
    #tab-controls [data-action="run"].reloading { color: var(--orange); }
    #tab-controls [data-action="run"].reloading:hover { background: var(--faint-orange); }
    #tab-controls [data-action="stop"] { color: var(--red); }
    #tab-controls [data-action="stop"]:hover { background: var(--faint-red); }
    #tab-controls [data-action="stop"]:disabled {
      color: var(--dim);
      cursor: default;
    }
    #tab-controls [data-action="stop"]:disabled:hover { background: none; }

    #tab-bar li {
      display: flex;
      align-items: center;
      gap: 5px;
      padding: 0 8px 0 12px;
      font-size: var(--text-sm);
      color: var(--dim);
      cursor: pointer;
      border-right: 1px solid var(--border);
      white-space: nowrap;
      flex-shrink: 0;
      max-width: 180px;
      transition: color 0.1s, background 0.1s;
      user-select: none;
      position: relative;
    }
    #tab-bar li:hover { color: var(--faint); background: var(--hover-faint); }
    #tab-bar li.active {
      color: var(--white);
      background: var(--bg);
      border-bottom: 2px solid var(--orange);
      margin-bottom: -1px;
    }

    /* tab name */
    #tab-bar li > span:first-child { flex: 1; overflow: hidden; text-overflow: ellipsis; }
    #tab-bar li.transient > span:first-child { font-style: italic; }
    /* dot for unsaved scratch tabs */
    #tab-bar li.dirty > span:first-child::after {
      content: '●'; font-size: 0.55rem; color: var(--orange);
      margin-left: 4px; vertical-align: super;
    }
    /* read-only lock glyph */
    #tab-bar li .material-symbols-outlined { font-size: var(--icon-sm); color: var(--dim); margin-left: 2px; }

    #tab-bar li button {
      background: none; border: none;
      color: inherit; opacity: 0;
      cursor: pointer; font-size: var(--text-2xs);
      line-height: 1; padding: 2px 3px;
      border-radius: 2px; flex-shrink: 0;
    }
    #tab-bar li:hover button { opacity: 0.4; }
    #tab-bar li button:hover { opacity: 1 !important; background: var(--hover-strong); }

    #editor {
      flex: 1;
      min-height: 0;
    }

    /* -- Status bar (foot of the editor panel) --------------------------------
       Run state, save toasts, and read-only/path messages — moved here out of the
       toolbar's top-right (the badge's spill zone). It bookends the tab bar as the
       editor panel's bottom chrome, so it spans just the middle column, not the
       whole window. boot.js still writes the inner #status by id; long paths
       truncate with an ellipsis. (A <footer> is reserved for a future brand footer.) */
    #statusbar {
      flex-shrink: 0;
      display: flex;
      align-items: center;
      min-height: 22px;
      padding: 2px 12px;
      background: var(--bar-bg);
      border-top: 1px solid var(--border);
      font-size: var(--text-xs);
      color: var(--dim);
      user-select: none;
    }
    #status { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

    /* -- Image preview (shown instead of #editor for image tabs) --- */
    #img-preview {
      display: none;
      flex: 1;
      min-height: 0;
      flex-direction: column;
      align-items: center;
      justify-content: center;
      gap: 10px;
      padding: 20px;
      background: rgba(0,0,0,0.25);
    }
    #img-preview img {
      max-width: 100%;
      max-height: calc(100% - 40px);
      object-fit: contain;
      image-rendering: pixelated;
    }
    #img-preview figcaption {
      display: flex;
      gap: 16px;
      font-size: var(--text-xs);
      color: var(--dim);
    }
    /* The dimensions are a <small> (semantic "fine print"); keep them the same
       size as the name for now — drop this rule to visually de-emphasise them. */
    #img-preview figcaption small { font-size: inherit; }

    /* -- Example gallery -----------------------------------------------------
       Lives on its own page now (examples.html), where it fills #editor-panel.
       Hidden by default so a stray #gallery elsewhere stays collapsed; the
       examples page opts it back in. */
    #gallery {
      display: none;
      flex: 1;
      min-height: 0;
      overflow-y: auto;
      padding: 0;
      background: rgba(0, 0, 0, 0.15);
    }
    .examples-page #gallery { display: block; }
    #gallery::-webkit-scrollbar {
      display: none;  /* The page scrolls the grid; hide the chrome scrollbar. */
    }
    /* Section heading before each grid — orange, uppercase, with a dim count.
       Shared by the examples gallery and the font explorer (fonts.html). */
    .section-title {
      padding: 24px 1.6rem 4px;
      color: var(--orange);
      font-size: var(--text-xs);
      font-weight: 700;
      text-transform: uppercase;
      letter-spacing: 0.09em;
      display: flex;
      align-items: center;
      gap: 8px;
    }
    .section-title .count { color: var(--dim); font-weight: 400; }

    .gallery-grid {
      display: grid;
      grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
      gap: 18px;
      padding: 12px 1.6rem 18px;
    }
    .example {
      display: flex;
      flex-direction: column;
      background: var(--panel);
      border: none;
      border-radius: 0.5rem;
      overflow: hidden;
      box-shadow: 0 0 1rem rgba(20, 30, 40, .2);
    }
    /* The screenshot is a button: click/tap = play the example in place. The still
       and the live canvas are produced by the simulator itself (preview.js): a
       spinner shows centred until the still is captured, then fades in; a big play
       badge overlays the still until a click moves the shared preview canvas in on
       top and plays it live. */
    .example-open {
      display: block; padding: 0; border: none; cursor: pointer;
      position: relative; aspect-ratio: 4 / 3;
      background: rgb(6, 6, 9); border-bottom: none;
    }
    .example-open .still,
    .example-open .preview-canvas {
      position: absolute; inset: 0; width: 100%; height: 100%;
      object-fit: contain; image-rendering: pixelated;
    }
    .example-open .still { opacity: 0; transition: opacity 0.15s; }
    .example.ready .example-open .still { opacity: 1; }
    /* Centred spinner (not stretched full-bleed like the still); hidden once ready. */
    .example-open .spinner {
      position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%);
      width: 34px; height: 34px; image-rendering: auto;
    }
    .example.ready .example-open .spinner { display: none; }
    /* Live preview canvas: moved into the clicked card by gallery.js, faded in. */
    .example-open .preview-canvas { opacity: 0; transition: opacity 0.12s; }
    .example.previewing .example-open .preview-canvas { opacity: 1; }
    .example-open:focus-visible { outline: 2px solid var(--orange); outline-offset: -2px; }

    /* Big play badge over the still - the "tap to run" affordance. It fades out the
       moment a card starts playing (.playing, set on click before the first frame). */
    .example-open .example-play {
      position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%);
      display: flex; align-items: center; justify-content: center;
      width: 3.4rem; height: 3.4rem; border-radius: 50%;
      background: rgba(255, 255, 255, 0.1); color: var(--white);
      font-size: 2.45rem; font-variation-settings: var(--glyph-filled);
      backdrop-filter: blur(8px);
      pointer-events: none; transition: opacity 0.15s, transform 0.15s, color 0.15s;
      opacity: 0;   /* hidden until the still has loaded, so the spinner shows through */
    }
    .example-open:hover .example-play { transform: translate(-50%, -50%) scale(1.08); color: var(--green); transition: opacity 0.2s; }
    /* Reveal the play badge only once the thumbnail is ready; hide it again while playing. */
    .example.ready .example-open .example-play { opacity: 1; }
    .example.playing .example-open .example-play { opacity: 0; }
    /* While live, the thumbnail is a touch gamepad (swipe = D-pad, tap = B), so the
       browser must not treat drags on it as scroll/zoom. Other cards scroll as usual. */
    .example.playing .example-open { touch-action: none; }

    /* Title + description on the left; Edit pinned to their right (click/tap the
       card itself to run). */
    .example-meta { display: flex; align-items: stretch; gap: 8px; padding: 1em; }
    .example-meta figcaption { flex: 1; min-width: 0; }
    .example-meta figcaption b    { display: block; font-size: var(--text-sm); font-weight: 700; color: var(--white); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
    .example-meta figcaption span { display: block; font-size: var(--text-xs); color: var(--dim);   overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
    .example-meta button {
      flex: 0 0 auto; display: inline-flex; align-items: center; justify-content: center; gap: 3px;
      font-family: inherit; font-size: 0.9rem; font-weight: 700; cursor: pointer;
      padding: 4px 12px; border-radius: 0.35rem; border: 1px solid var(--border);
      background: none; color: var(--faint);
      transition: color 0.15s, background 0.15s, border-color 0.15s;
    }
    .example-meta button .material-symbols-outlined { font-size: 1.15rem; }
    .example-meta button:hover { color: var(--white); border-color: var(--faint); }

    /* App cards (apps.html) reuse the example card; the launcher icon sits in the
       meta row beside the name. Badge icons are tiny pixel art, so render them crisp. */
    .app-icon {
      flex: 0 0 auto;
      width: 40px;
      height: 40px;
      border-radius: 0.4rem;
      object-fit: contain;
      image-rendering: pixelated;
      background: rgb(6, 6, 9);
    }

    .gallery-empty { padding: 20px; color: var(--dim); font-size: var(--text); }

    /* ==========================================================================
       Font Explorer (fonts.html). The page reuses the shared chrome above (brand
       nav, Playground toolbar, .section-title, palette); these are the bits unique
       to it — the specimen controls, the font grid/cards, and the detail modal.
       ========================================================================== */

    /* Scroll the whole document with the sticky top chrome, like the examples page,
       but at every width (no tabbed mobile shell here). These win over the mobile
       layout rules by specificity, so they hold on small screens too. */
    .fonts-page { height: auto; min-height: 100dvh; overflow: visible; }
    .fonts-page .topbar { position: sticky; top: 0; z-index: 1000; }
    .fonts-page #toolbar { display: flex; }
    .fonts-page #workspace { display: block; min-height: auto; overflow: visible; }

    /* -- Controls bar (specimen text, size, filter) ------------------ */
    #controls {
      background: var(--bar-bg);
      border-bottom: 1px solid var(--border);
      backdrop-filter: blur(10px);
      padding: 12px 1.6rem;
      display: flex;
      align-items: center;
      gap: 16px;
      flex-wrap: wrap;
    }
    #specimen-input {
      flex: 1;
      min-width: 220px;
      background: var(--panel);
      border: 1px solid var(--border);
      border-radius: 0.5rem;
      color: var(--white);
      font-family: inherit;
      font-size: var(--text);
      padding: 10px 14px;
      transition: border-color 0.15s;
    }
    #specimen-input:focus { outline: none; border-color: var(--orange); }
    #specimen-input::placeholder { color: var(--dim); }
    .control-group {
      display: flex;
      align-items: center;
      gap: 8px;
      color: var(--faint);
      font-size: var(--text-sm);
      white-space: nowrap;
    }
    .control-group input[type="range"] { accent-color: var(--orange); width: 120px; cursor: pointer; }
    .control-group .val { color: var(--white); min-width: 3.2em; text-align: right; font-variant-numeric: tabular-nums; }
    #filter-tabs, #res-tabs { display: flex; gap: 4px; }
    #filter-tabs button, #res-tabs button {
      background: var(--panel);
      color: var(--faint);
      border: 1px solid var(--border);
      border-radius: 0.4rem;
      font-family: inherit;
      font-size: var(--text-sm);
      padding: 6px 12px;
      cursor: pointer;
      transition: color 0.15s, border-color 0.15s;
    }
    #filter-tabs button:hover, #res-tabs button:hover { color: var(--white); }
    #filter-tabs button.active, #res-tabs button.active { color: var(--orange); border-color: var(--orange); }

    /* -- Font grid + cards ------------------------------------------- */
    .font-grid {
      display: grid;
      grid-template-columns: repeat(auto-fill, minmax(340px, 1fr));
      gap: 18px;
      padding: 12px 1.6rem 18px;
    }
    .font-card {
      display: flex;
      flex-direction: column;
      background: var(--panel);
      border: 1px solid transparent;
      border-radius: 0.5rem;
      overflow: hidden;
      box-shadow: 0 0 1rem rgba(20, 30, 40, .2);
      transition: border-color 0.15s, transform 0.15s;
      cursor: pointer;
    }
    .font-card:hover { border-color: var(--faint); transform: translateY(-2px); }
    /* The specimen is a badge screen: a fixed 240px-tall, 4:3 dark panel. The canvas
       backing is the real badge resolution (320x240 / 160x120); object-fit shows it
       1:1 at HIRES (and upscaled, pixelated, at LORES), centred, with long text
       clipping at the screen edge. */
    .font-card .specimen {
      background: rgb(6, 10, 16);
      overflow: hidden;
    }
    .font-card .specimen canvas {
      display: block;
      width: auto;
      height: 240px;
      object-fit: contain;
      image-rendering: pixelated;
      margin: 0 auto;
      aspect-ratio: 4/3;
    }
    .font-card .meta {
      display: flex;
      align-items: center;
      gap: 10px;
      padding: 12px 16px;
    }
    .font-card .meta .name-block { flex: 1; min-width: 0; }
    .font-card .meta .name {
      display: block;
      font-size: var(--text-sm);
      font-weight: 700;
      color: var(--white);
      overflow: hidden;
      text-overflow: ellipsis;
      white-space: nowrap;
    }
    .font-card .meta .dims { display: block; font-size: var(--text-xs); color: var(--dim); margin-top: 2px; }

    /* Type badge (vector / pixel) — shared by the card meta + modal header. */
    .font-card .badge,
    #modal-header .badge {
      flex: 0 0 auto;
      font-size: var(--text-2xs);
      font-weight: 700;
      text-transform: uppercase;
      letter-spacing: 0.06em;
      padding: 3px 8px;
      border-radius: 0.35rem;
      border: 1px solid var(--border);
    }
    .font-card .badge.vector,
    #modal-header .badge.vector { color: var(--blue); border-color: rgba(32, 189, 224, 0.4); }
    .font-card .badge.pixel,
    #modal-header .badge.pixel  { color: var(--green); border-color: rgba(32, 224, 70, 0.4); }

    /* -- Detail modal ------------------------------------------------- */
    #modal-backdrop {
      position: fixed;
      inset: 0;
      background: rgba(4, 8, 12, 0.7);
      backdrop-filter: blur(4px);
      z-index: 1100;   /* above the sticky .topbar (z-index 1000) */
      display: none;
      align-items: flex-start;
      justify-content: center;
      padding: 40px 20px;
      overflow-y: auto;
    }
    #modal-backdrop.open { display: flex; }
    #modal {
      background: var(--panel);
      border: 1px solid var(--border);
      border-radius: 0.6rem;
      width: 100%;
      max-width: 780px;
      box-shadow: 0 10px 40px rgba(0, 0, 0, 0.5);
      overflow: hidden;
    }
    #modal-header {
      display: flex;
      align-items: center;
      gap: 12px;
      padding: 18px 22px;
      border-bottom: 1px solid var(--border);
    }
    #modal-header .name { flex: 1; font-size: var(--text-lg); font-weight: 700; }
    #modal-header .close {
      background: none; border: none; color: var(--faint); cursor: pointer;
      font-size: var(--icon-lg); display: inline-flex; padding: 4px; border-radius: 0.35rem;
      transition: color 0.15s, background 0.15s;
    }
    #modal-header .close:hover { color: var(--white); background: var(--hover); }
    #modal-body { padding: 22px; }
    #modal-specimen {
      background: rgb(6, 10, 16);
      border: 1px solid var(--border);
      border-radius: 0.5rem;
      overflow: hidden;
      margin-bottom: 18px;
    }
    /* Same badge-screen canvas as the cards, shown larger and centred. */
    #modal-specimen canvas {
      display: block;
      width: 100%;
      max-width: 520px;
      height: auto;
      margin: 0 auto;
      image-rendering: pixelated;
    }
    #modal .dims-row {
      display: flex;
      flex-wrap: wrap;
      gap: 8px 20px;
      color: var(--faint);
      font-size: var(--text-sm);
      margin-bottom: 20px;
    }
    #modal .dims-row b { color: var(--white); font-weight: 500; }
    .modal-section-title {
      color: var(--orange);
      font-size: var(--text-xs);
      font-weight: 700;
      text-transform: uppercase;
      letter-spacing: 0.07em;
      margin: 20px 0 8px;
    }
    .code-block {
      position: relative;
      background: rgb(6, 10, 16);
      border: 1px solid var(--border);
      border-radius: 0.5rem;
      padding: 14px 16px;
      overflow: hidden;
    }
    .code-block pre {
      font-family: "SF Mono", ui-monospace, Menlo, Consolas, monospace;
      font-size: var(--text-sm);
      color: var(--white);
      line-height: 1.5;
      white-space: pre-wrap;
      overflow-wrap: anywhere;
      padding-right: 4.5rem;   /* keep wrapped text clear of the overlaid Copy button */
    }
    .code-block .tok-comment { color: var(--dim); }
    .code-block .tok-str { color: var(--green); }
    .code-block .tok-fn { color: var(--blue); }
    .code-block .copy-btn {
      position: absolute;
      top: 8px;
      right: 8px;
      background: var(--panel);
      border: 1px solid var(--border);
      color: var(--faint);
      border-radius: 0.35rem;
      font-family: inherit;
      font-size: var(--text-xs);
      padding: 4px 10px;
      cursor: pointer;
      display: inline-flex;
      align-items: center;
      gap: 4px;
      transition: color 0.15s, border-color 0.15s;
    }
    .code-block .copy-btn:hover { color: var(--white); border-color: var(--faint); }
    .code-block .copy-btn .material-symbols-outlined { font-size: 1.1rem; }
    .modal-actions { display: flex; gap: 10px; margin-top: 6px; }
    .btn {
      display: inline-flex;
      align-items: center;
      gap: 6px;
      font-family: inherit;
      font-size: var(--text-sm);
      font-weight: 400;
      padding: 9px 16px;
      border-radius: 0.4rem;
      border: 1px solid var(--border);
      background: var(--panel);
      color: var(--white);
      cursor: pointer;
      text-decoration: none;
      transition: filter 0.1s, border-color 0.15s;
    }
    .btn:hover { filter: brightness(1.2); }
    .btn .material-symbols-outlined { font-size: var(--icon); }
    .btn.primary { background: var(--orange); border-color: var(--orange); color: rgb(20, 14, 4); font-weight: 500; }
    #loading { padding: 60px 20px; text-align: center; color: var(--dim); font-size: var(--text); }

    /* Font Explorer on small screens: keep the Playground toolbar (it's the only
       nav here) but drop its title + button labels, and stack the grid. */
    @media (max-width: 767px) {
      .fonts-page .toolbar-title { display: none; }
      .fonts-page #toolbar .navbtn .label { display: none; }
      #controls { padding: 10px 1rem; }
      .fonts-page .section-title { padding-left: 1rem; padding-right: 1rem; }
      .font-grid { grid-template-columns: 1fr; padding-left: 1rem; padding-right: 1rem; }
      .control-group input[type="range"] { width: 90px; }
    }

    /* -- Help view (toggled by the toolbar ?, sits where #editor does) -------- */
    #help {
      display: none;
      flex: 1;
      min-height: 0;
      overflow-y: auto;
      padding: 22px;
      background: rgba(0, 0, 0, 0.15);
    }
    .help-doc {
      max-width: 600px;
      margin: 0 auto;
      color: var(--faint);
      font-size: var(--text);
      line-height: 1.5;
    }
    .help-doc h2 { color: var(--white); font-size: var(--text-lg); font-weight: 700; margin-bottom: 6px; }
    /* Doc subheading: same uppercase label treatment as the section titles, but
       inline (not a chrome bar) and accented orange. */
    .help-doc h3 {
      color: var(--orange);
      font-size: var(--text-xs);
      font-weight: 700;
      text-transform: uppercase;
      letter-spacing: 0.07em;
      margin: 22px 0 8px;
    }
    .help-doc p { margin-bottom: 10px; }
    .help-doc a { color: var(--blue); }
    .help-doc b { color: var(--white); font-weight: 500; }
    .help-keys { list-style: none; display: flex; flex-direction: column; gap: 7px; margin-bottom: 4px; }
    .help-keys li { display: flex; gap: 14px; }
    .help-keys .k { flex: 0 0 150px; color: var(--white); }
    .help-doc kbd {
      font-family: inherit;
      font-size: var(--text-xs);
      background: var(--surface-key);
      border: 1px solid var(--border);
      border-bottom-width: 2px;
      border-radius: 4px;
      padding: 1px 5px;
      color: var(--white);
    }

    /* -- Drag handles (panel & section resizers) -----------------------------
       Identified by the same data-attributes resize.js reads, so no marker class
       is needed. data-drag-orientation sets the axis; .dragging is toggled while
       a drag is in progress. */
    [data-drag-target] {
      flex-shrink: 0;
      background: var(--border);
      position: relative;
      z-index: 7;                 /* lift the handle (+ its toggle tab) above the panels */
      transition: background 0.15s;
    }
    /* Widen the pointer hit area without changing the visible 4px strip. */
    [data-drag-target]::after { content: ''; position: absolute; }
    [data-drag-target]:hover,
    [data-drag-target].dragging { background: var(--orange); }

    [data-drag-orientation="vertical"]        { width: 4px;  cursor: col-resize; }   /* dragged left/right */
    [data-drag-orientation="vertical"]::after { inset: 0 -4px; }

    [data-drag-orientation="horizontal"]        { height: 4px; cursor: row-resize; } /* dragged up/down */
    [data-drag-orientation="horizontal"]::after { inset: -4px 0; }

    /* -- Panel toggle (double-click a vertical handle) -----------------------
       Each vertical handle wears a chevron tab and doubles as a show/hide toggle
       for its panel. resize.js tags the handle with .panel-before / .panel-after
       (which side the panel sits) and .collapsed (current state); the chevron
       points toward the panel when open, away when hidden. */
    [data-drag-orientation="vertical"]::before {
      content: "";
      font-family: 'Material Symbols Outlined';
      font-variation-settings: var(--glyph);
      font-size: var(--icon-md);
      line-height: 1;
      color: var(--faint);
      position: absolute;
      top: 50%; left: 50%;
      transform: translate(0, -50%);
      width: calc(var(--bar) / 2); height: var(--bar);
      display: flex; align-items: center; justify-content: center;
      background: var(--bar-bg);
      border: 1px solid var(--border);
      border-radius: 5px;
      transition: background 0.15s;
    }
    [data-drag-orientation="vertical"]:hover::before { color: var(--white); background: var(--orange); }
    /* Chevron glyphs (Material Symbols codepoints): ‹ = e5cb, › = e5cc. */
    [data-drag-orientation="vertical"].panel-before::before           { 
      border-radius: 0 5px 5px 0;
      left: 100%;
      content: "\e5cb"; }  /* collapse the left panel */
    [data-drag-orientation="vertical"].panel-before.collapsed::before { content: "\e5cc"; }  /* re-open it */
    [data-drag-orientation="vertical"].panel-after::before            { 
      transform: translate(-100%, -50%);
      border-radius: 5px 0 0 5px;
      left: 0;
      content: "\e5cc"; }  /* collapse the right panel */
    [data-drag-orientation="vertical"].panel-after.collapsed::before  { content: "\e5cb"; }  /* re-open it */

    /* Collapsed panel: zero width, content + border hidden. .animating carries the
       slide and is only present while toggling, so a plain drag stays instant.
       Desktop-only — the mobile layout owns the panel widths (full-width tabs). */
    @media (min-width: 768px) {
      #file-panel.panel-collapsed, #side-panel.panel-collapsed {
        width: 0 !important; min-width: 0; overflow: hidden; border-width: 0;
      }
      #file-panel.animating, #side-panel.animating { transition: width 0.28s ease; overflow: hidden; }
    }

    /* While a drag is in progress (resize.js sets this on <html>): force one
       resize cursor everywhere and suppress text selection. Pointer capture keeps
       the events flowing to the handle, so no overlay element is needed. */
    .dragging-col, .dragging-col *,
    .dragging-row, .dragging-row * { user-select: none; }
    .dragging-col, .dragging-col * { cursor: col-resize !important; }
    .dragging-row, .dragging-row * { cursor: row-resize !important; }

    /* -- Side panel ------------------------------------------------ */
    #side-panel {
      width: 547px;
      flex-shrink: 0;
      border-left: 1px solid var(--border);
      display: flex;
      flex-direction: column;
      background: var(--panel);
      /* visible so the 3D badge can spill out top and bottom */
      overflow: visible;
    }

    /* -- Simulator ------------------------------------------------- */
    #simulator {
      padding: 0 12px;
      flex-shrink: 0;
      display: flex;
      flex-direction: column;
      /* lifted above the toolbar and OUTPUT box so the spilled badge sits on top */
      position: relative;
      z-index: 5;
      overflow: visible;
    }

    #badge-3d-wrap {
      flex: 1;
      min-width: 0;
      aspect-ratio: 4 / 3;
      background: transparent;
      position: relative;
      overflow: visible;
      /* Spill past the container: up over the toolbar, and down over the OUTPUT
         title by exactly that title bar's height, so the badge overlaps it fully
         whatever the title's font/icon size is. boot.js measures #stdout h2 and
         mirrors its height into --badge-spill; the fallback covers first paint / no-JS. */
      margin-top: -7%;
      margin-bottom: calc(var(--badge-spill, 40px) * -1);
      transition: margin 0.25s ease;
    }
    /* When the screen is zoomed in, pull the badge back inside its container so
       the framed screen never overlaps the toolbar or the OUTPUT box. */
    #simulator.screen-zoomed #badge-3d-wrap {
      margin-top: 10px;
      margin-bottom: 5px;
    }

    #badge-3d-wrap > canvas {
      display: block;
      width: 100% !important;
      height: 100% !important;
      outline: none;
    }

    /* -- 3D badge spin buttons (180° steps) ------------------------ */
    /* Container spans the view but ignores pointer events, so only the two
       edge buttons are clickable and the badge stays raycastable between them. */
    #simulator nav {
      position: absolute;
      left: 0;
      right: 0;
      top: 50%;
      transform: translateY(-50%);
      display: flex;
      justify-content: space-between;
      padding: 0 10px;
      pointer-events: none;
      z-index: 6;
      transition: opacity 0.45s ease;
    }

    #simulator nav button {
      pointer-events: auto;
      width: 28px;
      height: 28px;
      display: flex;
      align-items: center;
      justify-content: center;
      background: rgba(10, 20, 30, 0.6);
      border: 1px solid var(--border);
      border-radius: 25%;
      color: var(--faint);
      font-family: inherit;
      font-size: 1.25rem;
      line-height: 1;
      cursor: pointer;
      transition: color 0.15s, background 0.15s;
    }
    #simulator nav button:hover {
      color: var(--white);
      background: rgba(10, 20, 30, 0.85);
    }
    #simulator nav button .material-symbols-outlined { font-size: var(--icon-lg); }

    #simulator.screen-zoomed nav {
        opacity: 0;
    }

    /* -- Output (#stdout is the whole view: title bar + scrolling log) ------- */
    #stdout {
      flex: 1;
      overflow: hidden;
      display: flex;
      flex-direction: column;
    }

    #stdout > div {   /* the scrolling log */
      flex: 1;
      overflow-y: auto;
      padding: 8px 12px;
      font-family: Consolas, Monaco, "Andale Mono", "Ubuntu Mono", monospace;
      font-size: var(--text-xs);
      line-height: 1.6;
      color: var(--green);
      white-space: pre-wrap;
      word-break: break-all;
      background: rgba(0, 0, 0, 0.2);
    }

    #stdout > div::-webkit-scrollbar       { width: 6px; }
    #stdout > div::-webkit-scrollbar-track { background: transparent; }
    #stdout > div::-webkit-scrollbar-thumb { background: var(--scroll-thumb); border-radius: 3px; }

    .out-dim   { color: var(--dim); }
    .out-error { color: var(--red); }

    /* -- File panel ------------------------------------------------ */
    #file-panel {
      width: 200px;
      flex-shrink: 0;
      border-right: 1px solid var(--border);
      background: rgba(10, 20, 30, 0.5);
      display: flex;
      flex-direction: column;
      overflow: hidden;
    }

    /* Section title bar: the one authoritative chrome-header look, shared by the
       file-explorer sections and the output panel. Both are full-height (var(--bar))
       bars; only padding/justification differs per panel below. (The gallery + font
       explorer use the taller .section-title look instead.) */
    #file-panel h2,
    #stdout h2 {
      font-size: var(--text-2xs);
      font-weight: 400;
      color: var(--dim);
      text-transform: uppercase;
      letter-spacing: 0.1em;
      border-bottom: 1px solid var(--border);
      display: flex;
      align-items: stretch;
      flex-shrink: 0;
      min-height: var(--bar);   /* lines the headings up across panels + mobile */
    }
    #file-panel h2 > span:first-child,
    #stdout h2 > span:first-child { padding: 0 0 0 10px; align-content: center; }
    #file-panel h2 { gap: 2px; }
    #file-panel h2 > span:first-child,
    #stdout h2 > span:first-child { flex: 1; }     /* title text pushes controls right */

    #stdout h2 button {
      z-index: 6;
    }

    /* -- User section (resizable) ---------------------------------- */
    #fp-user {
      flex-shrink: 0;
      height: 220px;        /* default; drag handle overrides via inline style */
      min-height: 40px;
      display: flex;
      flex-direction: column;
      overflow: hidden;
    }

    #fp-user-list {
      flex: 1;
      min-height: 0;
      overflow-y: auto;
    }

    .fp-empty {
      padding: 8px 10px;
      font-size: var(--text-xs);
      color: var(--dim);
      font-style: italic;
    }

    /* -- System section (fills remaining space) -------------------- */
    #fp-sys {
      flex: 1;
      overflow: hidden;
      display: flex;
      flex-direction: column;
      min-height: 60px;
    }

    /* Padlock icon, not a button but should be the same width */
    #fp-sys h2 span:last-child {
      width: var(--bar);
      text-align: center;
      align-content: center;;
    }

    #fp-sys-tree {
      flex: 1;
      overflow-y: auto;
      overflow-x: hidden;
    }

    #fp-sys-tree .row-badge, #fp-user .row-action span {
      font-size: var(--icon-sm);
      width: var(--bar);
      text-align: center;
    }

    #fp-user-list::-webkit-scrollbar,
    #fp-sys-tree::-webkit-scrollbar { width: 4px; }
    #fp-user-list::-webkit-scrollbar-track,
    #fp-sys-tree::-webkit-scrollbar-track { background: transparent; }
    #fp-user-list::-webkit-scrollbar-thumb,
    #fp-sys-tree::-webkit-scrollbar-thumb { background: var(--scroll-thumb); border-radius: 2px; }

    /* -- Context menu ---------------------------------------------- */
    #file-ctx-menu {
      display: none;
      position: fixed;
      z-index: 10000;
      background: rgb(15, 25, 35);
      border: 1px solid var(--border);
      border-radius: 5px;
      padding: 3px 0;
      min-width: 145px;
      box-shadow: 0 4px 18px rgba(0,0,0,0.55);
    }

    #file-ctx-menu button {
      display: block;
      width: 100%;
      text-align: left;
      background: none;
      border: none;
      font-family: inherit;
      padding: 5px 14px;
      font-size: var(--text-sm);
      color: var(--faint);
      cursor: pointer;
      user-select: none;
    }
    #file-ctx-menu button:hover { background: var(--hover); color: var(--white); }
    #file-ctx-menu button[data-action="delete"] { color: rgba(240,141,73,0.8); }
    #file-ctx-menu button[data-action="delete"]:hover { color: rgba(240,141,73,1); background: rgba(240,141,73,0.07); }
    #file-ctx-menu hr { border: none; height: 1px; background: var(--border); margin: 3px 0; }

    /* -- Tree rows ------------------------------------------------- */
    .tree-row {
      display: flex;
      align-items: center;
      padding: 0;
      font-size: var(--text-sm);
      color: var(--faint);
      cursor: pointer;
      gap: 4px;
      white-space: nowrap;
      overflow: hidden;
      user-select: none;
    }
    .tree-row > span:first-child {
      padding: 2px 8px;
    }
    .tree-row:hover { background: var(--hover); color: var(--white); }
    .tree-row.active { background: var(--faint-orange); color: var(--orange); }
    /* Keyboard focus — file rows and directory summaries are both tab stops. */
    .tree-row:focus-visible,
    details.tree-dir > summary:focus-visible {
      outline: 1px solid var(--orange);
      outline-offset: -1px;
    }

    .tree-row .row-name {
      flex: 1;
      overflow: hidden;
      text-overflow: ellipsis;
    }
    /* A file with an open tab reads bolder; a transient (preview) tab is italic.
       These compose with .active's highlight — an active open file is both. */
    .tree-row.open .row-name      { font-weight: 400; }
    .tree-row.transient .row-name { font-style: italic; }

    .tree-row .row-badge {
      font-size: var(--text-3xs);
      color: var(--dim);
      flex-shrink: 0;
    }

    .row-actions { display: none; gap: 1px; flex-shrink: 0; }
    /* Mouse-only affordance; keyboard deletes a focused row with Delete/Backspace. */
    .tree-row:hover .row-actions { display: flex; }

    .row-action {
      background: none;
      border: none;
      color: inherit;
      opacity: 0.6;
      cursor: pointer;
      font-size: var(--text-xs);
      padding: 0 2px;
      line-height: 1;
    }
    .row-action:hover { opacity: 1; }
    .row-action[data-action="delete"]:hover { color: rgba(240,141,73,1); }

    /* Lock badge (system files + the "System" header) sized for the Material glyph. */
    .row-badge.material-symbols-outlined { font-size: var(--icon-sm); }

    /* -- Collapsible system directories --------------------------- */
    details.tree-dir > summary {
      list-style: none;
      display: flex;
      align-items: center;
      gap: 4px;
      padding: 2px 8px;
      font-size: var(--text-sm);
      color: var(--faint);
      cursor: pointer;
      user-select: none;
      white-space: nowrap;
    }
    details.tree-dir > summary::-webkit-details-marker { display: none; }
    details.tree-dir > summary:hover { background: var(--hover); color: var(--white); }

    .dir-arrow {
      font-size: 1.25rem;
      color: var(--dim);
      flex-shrink: 0;
      transition: transform 0.12s;
      display: inline-block;
    }
    details.tree-dir[open] > summary .dir-arrow { transform: rotate(90deg); }

    #fp-user-list ul, #fp-sys-tree ul { list-style: none; }   /* tree = nested lists */
    .dir-children { padding-left: 10px; }                     /* indent each level */

    /* -- Mobile-only chrome (hidden on desktop) ------------------- */
    #mobile-nav, #mobile-run { display: none; }

    /* -- Mobile layout --------------------------------------------- */
    @media (max-width: 767px) {

      /* No way to turn this off in monaco editor and I have to press and hold to keep the keyboard open!? */
      .monaco-editor .iPadShowKeyboard {
          display: none !important;
      }

      /* Drop the desktop toolbar + status bar; run/stop float on the badge, and
         run feedback lives in the Output tab. Tab controls duplicate mobile-run. */
      #toolbar { display: none; }
      #statusbar { display: none; }
      #tab-controls { display: none; }

      /* Brand nav shrinks to match badgewa.re's small-screen bar. */
      nav#main svg { height: 1.8rem; }
      nav#main > div { padding: 0.5rem 0.5rem; }

      /* Tabs move to the TOP — mobile Safari overlays the bottom edge. */
      #mobile-nav { order: -2; }

      /* Main: stack vertically */
      #workspace { flex-direction: column; overflow: hidden; }

      /* Badge strip: always visible at the top of the content. */
      #side-panel {
        order: -1;
        width: 100% !important;
        flex-shrink: 0;
        border-left: none;
        overflow: visible;  /* keep 3D canvas visible */
      }
      /* This border wrangling is a hack for the fact stdout is *in* the side panel */
      #side-panel, #gallery, #editor-panel, #file-panel {
        border-bottom: 1px solid var(--border);
      }
      #stdout {
        border-top: 1px solid var(--border);
      }
      #badge-3d-wrap { margin-top: 0 !important; margin-bottom: 0 !important; transition: none; }

      /* Floating run/stop in the badge's top-right (#simulator is positioned). */
      #mobile-run {
        display: flex;
        gap: 6px;
        position: absolute;
        top: 6px; right: 6px;
        z-index: 8;
      }
      #mobile-run button {
        width: 2.2rem; height: 2.2rem;
        display: flex; align-items: center; justify-content: center;
        border: none; border-radius: 0.5rem; cursor: pointer;
        background: rgba(10, 20, 30, 0.55); color: var(--green);
        box-shadow: 0 2px 8px rgba(0, 0, 0, 0.4);
        backdrop-filter: blur(6px);
      }
      #mobile-run button .material-symbols-outlined { font-size: var(--icon-lg); }
      #mobile-run button[data-action="run"].reloading { color: var(--orange); }
      #mobile-run button[data-action="stop"] { color: var(--red); }
      #mobile-run button:disabled { color: var(--dim); box-shadow: none; }

      /* stdout hidden unless Output tab; the tab is its title, so drop the header. */
      #stdout { display: none; }
      #stdout h2 { display: none; }

      /* File panel: full-width, User + System side by side. */
      #file-panel {
        display: none;
        flex-direction: row;
        width: 100% !important;
        flex: 1;
        min-height: 0;
        border-right: none;
      }
      #fp-user, #fp-sys { flex: 1; height: auto !important; min-height: 0; }
      #fp-user { border-right: 1px solid var(--border); }

      /* Editor panel (also hosts the gallery): full-width */
      #editor-panel { display: none; width: 100%; flex: 1; min-height: 0; }

      /* Hide every resize handle (panel widths + the user/system split). */
      [data-drag-target] { display: none; }

      /* -- Per-tab visibility ------------------------------------ */
      body[data-mobile-tab="files"]   #file-panel   { display: flex; }
      body[data-mobile-tab="gallery"] #editor-panel,
      body[data-mobile-tab="code"]    #editor-panel { display: flex; }
      body[data-mobile-tab="output"]  #side-panel   { flex: 1; overflow: hidden; }
      body[data-mobile-tab="output"]  #stdout       { display: flex; }

      /* -- Mobile nav (icon tabs, at the top) -------------------- */
      #mobile-nav {
        display: flex;
        flex-shrink: 0;
        background: var(--bar-bg);
        border-bottom: 1px solid var(--border);
        backdrop-filter: blur(1rem);
        /* The notch/status-bar inset is handled once on <body> (padding-top:
           env(safe-area-inset-top)), which pushes this whole column — nav
           included — clear of the unsafe area. No per-nav inset needed. */
      }
      #mobile-nav button {
        flex: 1;
        display: flex; align-items: center; justify-content: center;
        padding: 9px 0;
        background: none; border: none; border-bottom: 2px solid transparent;
        color: var(--dim); cursor: pointer;
        touch-action: manipulation; transition: color 0.15s; user-select: none;
      }
      #mobile-nav button .material-symbols-outlined { font-size: var(--icon-lg); }
      #mobile-nav button.active { color: var(--orange); border-bottom-color: var(--orange); }
    }
