  /* Monochrome. One ink colour, one page colour, grey for everything secondary.
     Light by default; the dark variant is the same design inverted. */
  :root {
    --page: #ffffff;
    --surface: #ffffff;
    --surface-2: #f7f7f5;
    --line: #dcdcd8;
    --line-2: #ebebe8;
    --ink: #111111;
    --on-ink: #ffffff;
    --text: #111111;
    --muted: #767672;
    --radius: 2px;
  }
  @media (prefers-color-scheme: dark) {
    :root {
      --page: #0b0b0b;
      --surface: #0f0f0f;
      --surface-2: #151514;
      --line: #2e2e2c;
      --line-2: #1f1f1e;
      --ink: #f2f2f0;
      --on-ink: #0b0b0b;
      --text: #f2f2f0;
      --muted: #8c8c88;
    }
  }

  * { box-sizing: border-box; }
  html { -webkit-text-size-adjust: 100%; }
  /* Flex column so the footer can be pushed to the bottom on short pages.
     The sheet and toast are position:fixed, so they stay out of this flow. */
  body {
    margin: 0;
    min-height: 100vh;
    min-height: 100dvh;
    display: flex;
    flex-direction: column;
    font-family: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
    background: var(--page);
    color: var(--text);
    min-height: 100vh;
    padding: 8px 16px 40px;
    font-size: 15px;
    line-height: 1.5;
    -webkit-font-smoothing: antialiased;
  }

  /* Wider screens are a progressive enhancement, never the baseline.
     The grid's own column counts live with the .grid rule further down: a
     media query adds no specificity, so setting them here would be overridden
     by the base rule that comes later in the file. */
  @media (min-width: 620px) {
    body { padding: 12px 24px 48px; }
    .container { max-width: 680px; margin: 0 auto; }
  }
  @media (min-width: 900px) {
    .container { max-width: 760px; }
  }

  /* ---- footer wordmark ----
     The name sits at the bottom: the top of a phone screen belongs to the
     board and its controls, not to branding. */
  .container { display: flex; flex-direction: column; flex: 1 1 auto; width: 100%; }
  .footer {
    border-top: 1px solid var(--line);
    padding-top: 18px;
    display: flex; align-items: baseline; justify-content: space-between; gap: 12px;
  }
  .copyright { color: var(--muted); font-size: 11px; letter-spacing: 0.04em; }
  h1 {
    font-size: 13px; font-weight: 600; margin: 0; color: var(--muted);
    letter-spacing: 0.18em; text-transform: uppercase;
  }


  /* ---- type ---- */
  label {
    display: block; font-size: 10px; font-weight: 600;
    letter-spacing: 0.12em; text-transform: uppercase;
    color: var(--muted); margin-bottom: 6px;
  }
  .small { font-size: 12.5px; color: var(--muted); line-height: 1.55; }
  a { color: var(--text); text-underline-offset: 3px; }

  /* ---- controls: outlined, square, no fills ---- */
  input, select {
    background: transparent;
    border: 1px solid var(--line);
    color: var(--text);
    padding: 12px;
    border-radius: var(--radius);
    font-size: 16px;   /* below 16px, iOS Safari zooms the page on focus */
    font-family: inherit;
    width: 100%;
    min-height: 46px;
  }
  input:focus, select:focus, button:focus-visible {
    outline: none; border-color: var(--ink); box-shadow: 0 0 0 1px var(--ink);
  }
  input::placeholder { color: var(--muted); }
  input[type=file] { padding: 9px 10px; font-size: 13px; }
  input[type=checkbox] { width: auto; accent-color: var(--ink); margin: 0; }
  select {
    appearance: none;
    background-image: linear-gradient(45deg, transparent 50%, currentColor 50%),
                      linear-gradient(135deg, currentColor 50%, transparent 50%);
    background-position: calc(100% - 16px) 52%, calc(100% - 11px) 52%;
    background-size: 5px 5px, 5px 5px;
    background-repeat: no-repeat;
    padding-right: 34px;
  }

  button {
    cursor: pointer;
    background: transparent;
    border: 1px solid var(--ink);
    color: var(--text);
    border-radius: var(--radius);
    padding: 13px 18px;
    min-height: 44px;
    font-size: 13px;
    font-weight: 500;
    letter-spacing: 0.02em;
    font-family: inherit;
    transition: background-color .12s ease, color .12s ease, border-color .12s ease;
  }
  button:hover { background: var(--ink); color: var(--on-ink); }
  button:active { transform: translateY(1px); }
  button[disabled] { opacity: .3; cursor: not-allowed; }
  button[disabled]:hover { background: transparent; color: var(--text); }
  .btn-primary { background: var(--ink); color: var(--on-ink); }
  .btn-primary:hover { background: transparent; color: var(--text); }
  .btn-ghost { border-color: var(--line); color: var(--muted); }
  .btn-ghost:hover { border-color: var(--ink); background: transparent; color: var(--text); }
  .btn-danger { border-color: var(--ink); }
  .mini { padding: 9px 12px; min-height: 40px; font-size: 12px; }
  .row { display: flex; gap: 10px; flex-wrap: wrap; align-items: center; }
  .field { flex: 1; min-width: 120px; }
  .hidden { display: none !important; }

  /* ---- cards: hairlines, not boxes ---- */
  .card {
    border-top: 1px solid var(--line);
    padding: 0;
    margin-bottom: 2px;
  }
  #backupCard { margin-bottom: 28px; }
  .card-head {
    display: flex; align-items: center; justify-content: space-between; gap: 10px;
    cursor: pointer; user-select: none; padding: 16px 0;
  }
  .card-head strong {
    font-size: 11px; font-weight: 600; letter-spacing: 0.12em; text-transform: uppercase;
  }
  .card-head .chev {
    color: var(--muted); flex: 0 0 auto;
    width: 20px; height: 20px; line-height: 18px; text-align: center;
    border: 1px solid var(--line); border-radius: var(--radius);
    font-size: 13px; font-weight: 400;
  }
  .card-head .chev::before { content: '−'; }          /* minus when open */
  .card.collapsed .card-head .chev::before { content: '+'; }
  .card-head:hover .chev { border-color: var(--ink); color: var(--text); }
  .card.collapsed .card-body { display: none; }
  .card-body { padding-bottom: 22px; }

  .status { display: inline-flex; align-items: center; gap: 7px; font-size: 11px; color: var(--muted); letter-spacing: 0.06em; text-transform: uppercase; }
  .dot { width: 6px; height: 6px; border-radius: 50%; background: transparent; border: 1px solid var(--muted); flex-shrink: 0; }
  .dot.ok { background: var(--ink); border-color: var(--ink); }
  .dot.warn { background: var(--muted); border-color: var(--muted); }

  /* ---- the board ---- */
  .grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 10px; margin-top: 2px; }
  /* Kept next to the base rule above, not with the other breakpoints, so the
     later-rule-wins ordering works in our favour rather than against us. */
  @media (min-width: 620px) { .grid { grid-template-columns: repeat(3, 1fr); gap: 12px; } }
  @media (min-width: 900px) { .grid { grid-template-columns: repeat(4, 1fr); } }
  .clip {
    background: transparent;
    border: 1px solid var(--line);
    border-radius: var(--radius);
    padding: 16px 12px;
    /* Square, so every tile on every board is the same size by construction —
       content cannot grow one and leave the boards uneven when swiping. */
    aspect-ratio: 1 / 1;
    min-height: 0; overflow: hidden;
    display: flex; flex-direction: column;
    align-items: center; justify-content: center;
    text-align: center;
    cursor: pointer; position: relative;
    user-select: none; -webkit-tap-highlight-color: transparent;
    transition: border-color .12s ease, background-color .12s ease, color .12s ease;
  }
  .clip:hover { border-color: var(--ink); }
  /* Acknowledge the press on finger-down; audio cannot always be that fast. */
  .clip.armed { border-color: var(--ink); transform: scale(.97); }
  .clip { touch-action: manipulation; }   /* drop the double-tap wait, keep panning */
  /* Playing inverts the tile — unmistakable across a rink, no colour needed. */
  .clip.playing { background: var(--ink); color: var(--on-ink); border-color: var(--ink); }
  .clip.playing .meta { color: var(--on-ink); opacity: .65; }
  .clip .emoji {
    font-size: 26px; display: block; margin-bottom: 10px; line-height: 1;
    /* Emoji are the one thing that would break a black-and-white palette.
       Delete this line to let the icons keep their colour. */
    filter: grayscale(1);
  }
  .clip.playing .emoji { filter: grayscale(1) invert(1); }
  .tab { font-variant-emoji: text; }
  .clip .name {
    font-weight: 600; font-size: 15px; word-break: break-word; letter-spacing: 0.01em;
    line-height: 1.25;
    /* A long name gets two lines and an ellipsis, not a taller tile. */
    display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
  }
  .clip .meta {
    color: var(--muted); font-size: 11px; margin-top: 6px;
    letter-spacing: 0.06em;
    font-variant-numeric: tabular-nums;
    filter: grayscale(1);   /* the file marker is an emoji too */
  }
  .clip .edit {
    position: absolute; top: 2px; right: 2px;
    background: transparent; color: var(--muted); border: none;
    font-size: 14px; padding: 9px 11px; line-height: 1; opacity: 0;
    min-height: 0;
  }
  .clip:hover .edit, .clip:focus-within .edit { opacity: 1; }
  @media (hover: none) { .clip .edit { opacity: .4; } }   /* no hover on touch — keep it reachable */
  .clip .edit:hover { background: transparent; color: var(--text); }
  .clip.playing .edit { color: var(--on-ink); }
  .nudges { gap: 6px; margin-top: 10px; }
  .nudges .mini { flex: 1; padding: 9px 4px; font-variant-numeric: tabular-nums; }

  /* the + tile */
  .clip-add {
    border-style: dashed;
    border-color: var(--line);
    color: var(--muted);
  }
  .clip-add:hover { border-color: var(--ink); color: var(--text); }
  .clip-add .plus { font-size: 30px; font-weight: 200; line-height: 1; }
  .clip-add .label {
    font-size: 10px; letter-spacing: 0.12em; text-transform: uppercase; margin-top: 10px;
  }
  .empty {
    grid-column: 1 / -1; padding: 8px 0 0; text-align: center;
    color: var(--muted); font-size: 12.5px;
  }

  /* ---- tabs ---- */
  /* The strip scrolls; the + stays pinned beside it and never scrolls away. */
  .topbar {
    position: sticky; top: 0; z-index: 6;
    background: var(--page);
    margin-bottom: 18px;
  }
  .tabstrip {
    display: flex; align-items: stretch;
    background: var(--page);
    border-bottom: 1px solid var(--line);
  }
  .tabbar {
    display: flex; gap: 0; flex: 1 1 auto; min-width: 0;
    overflow-x: auto; scrollbar-width: none;
  }
  .tabbar::-webkit-scrollbar { display: none; }
  .tab {
    flex: 0 0 auto;
    background: none; border: none; border-bottom: 1.5px solid transparent;
    border-radius: 0; color: var(--muted);
    padding: 15px 12px 13px;
    min-height: 48px;
    font-size: 12px; font-weight: 500;
    letter-spacing: 0.08em; text-transform: uppercase;
    white-space: nowrap; margin-bottom: -1px;
  }
  .tab:hover { background: none; color: var(--text); }
  .tab.active { color: var(--text); border-bottom-color: var(--ink); }
  .tab-add {
    flex: 0 0 auto; color: var(--muted);
    border-left: 1px solid var(--line);
    padding: 15px 16px 13px; min-height: 48px; font-size: 17px; font-weight: 300; line-height: 1;
    background: none; border: none; border-radius: 0;
  }
  .tab-add:hover { background: none; color: var(--text); }

  .pages {
    display: flex; overflow-x: auto;
    scroll-snap-type: x mandatory; -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
    /* Fill the column down to the connect row, so the whole board area is a
       swipe surface — not just the rows that happen to have tiles in them. */
    flex: 1 1 auto;
  }
  .pages::-webkit-scrollbar { display: none; }
  .page { flex: 0 0 100%; width: 100%; scroll-snap-align: start; min-height: 40px; }

  /* ---- transport ---- */
  #stopAllBar {
    background: var(--page); padding: 6px 0 12px;
    display: flex; gap: 12px; align-items: center;
  }
  #deviceStatus { flex: 1; min-width: 0; }
  .icon-btn {
    flex: 0 0 auto; width: 44px; height: 44px; padding: 0;
    border: 1px solid var(--line); border-radius: var(--radius);
    color: var(--text); font-size: 17px; line-height: 1;
    display: inline-flex; align-items: center; justify-content: center;
  }
  .icon-btn:hover { background: var(--ink); color: var(--on-ink); border-color: var(--ink); }
  #deviceStatus { font-size: 11px; letter-spacing: 0.04em; }

  /* ---- add-clip sheet ---- */
  .sheet-backdrop {
    position: fixed; inset: 0; z-index: 50;
    background: rgba(0,0,0,.28);
    display: flex; align-items: flex-end; justify-content: center;
  }
  @media (prefers-color-scheme: dark) { .sheet-backdrop { background: rgba(0,0,0,.6); } }
  .sheet {
    background: var(--surface);
    border-top: 1px solid var(--ink);
    width: 100%; max-width: 560px;
    max-height: 92vh; overflow-y: auto;
    padding: 20px 20px calc(24px + env(safe-area-inset-bottom));
    animation: sheet-in .2s ease;
  }
  @keyframes sheet-in { from { transform: translateY(14px); opacity: 0; } }
  @media (min-width: 620px) {
    .sheet-backdrop { align-items: center; }
    .sheet { border: 1px solid var(--ink); max-height: 86vh; }
  }
  .sheet-head {
    display: flex; align-items: center; justify-content: space-between;
    margin-bottom: 18px; padding-bottom: 12px; border-bottom: 1px solid var(--line);
  }
  .sheet-head strong { font-size: 11px; font-weight: 600; letter-spacing: 0.12em; text-transform: uppercase; }
  .sheet-close { border: none; color: var(--muted); font-size: 20px; padding: 4px 8px; line-height: 1; }
  .sheet-close:hover { background: none; color: var(--text); }
  /* In the settings sheet the cards' own top rules provide the separation,
     so the head does not need one as well. (:first-of-type would match the
     head, not a card, so the card keeps its border and the head loses one.) */
  #settingsSheet .sheet-head { border-bottom: none; margin-bottom: 0; }
  #settingsSheet .card:last-of-type { border-bottom: 1px solid var(--line); }
  .sheet-actions {
    display: flex; gap: 10px; margin-top: 22px; padding-top: 16px;
    border-top: 1px solid var(--line);
  }
  .sheet-actions .btn-primary { flex: 1; }
  /* One-tap icon choices under the Icon field. */
  .icon-chips { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 12px; }
  .icon-chips button { min-width: 44px; padding: 8px 10px; font-size: 18px; line-height: 1; }

  /* ---- segmented source toggle ---- */
  .seg { display: inline-flex; border: 1px solid var(--line); border-radius: var(--radius); overflow: hidden; }
  .seg button {
    border: none; border-radius: 0; color: var(--muted);
    padding: 10px 16px; font-size: 12px; letter-spacing: 0.06em; text-transform: uppercase;
  }
  .seg button + button { border-left: 1px solid var(--line); }
  .seg button.on { background: var(--ink); color: var(--on-ink); }

  /* ---- search ---- */
  .search-wrap { position: relative; }
  .search-results {
    position: absolute; top: 100%; left: 0; right: 0; z-index: 20;
    background: var(--surface); border: 1px solid var(--ink);
    border-radius: var(--radius); margin-top: -1px;
    max-height: 300px; overflow-y: auto;
  }
  .search-result { display: flex; align-items: center; gap: 11px; padding: 10px 12px; cursor: pointer; }
  .search-result + .search-result { border-top: 1px solid var(--line-2); }
  .search-result:hover { background: var(--surface-2); }
  .search-result img { width: 34px; height: 34px; border-radius: var(--radius); flex-shrink: 0; filter: grayscale(1); }
  .search-result .info { min-width: 0; }
  .search-result .t { font-size: 13.5px; font-weight: 500; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
  .search-result .a { font-size: 12px; color: var(--muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

  .selected-track {
    display: flex; align-items: center; gap: 11px;
    border: 1px solid var(--ink); border-radius: var(--radius);
    padding: 10px 12px; margin-top: 12px;
  }
  .selected-track img { width: 38px; height: 38px; border-radius: var(--radius); filter: grayscale(1); }
  .selected-track .clear { margin-left: auto; border: none; color: var(--muted); font-size: 15px; padding: 4px 8px; }
  .selected-track .clear:hover { background: none; color: var(--text); }

  /* ---- scrubber ---- */
  .scrubber { border: 1px solid var(--line); border-radius: var(--radius); padding: 14px; margin-top: 12px; }
  .scrub-head { display: flex; justify-content: space-between; align-items: baseline; gap: 10px; margin-bottom: 10px; }
  .scrub-time {
    font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
    font-size: 12.5px; color: var(--muted); font-variant-numeric: tabular-nums;
  }
  #scrubNow { color: var(--text); font-weight: 600; }
  input[type=range] {
    -webkit-appearance: none; appearance: none;
    width: 100%; background: transparent; padding: 0; border: none; margin: 10px 0;
  }
  input[type=range]:focus { box-shadow: none; }
  input[type=range]::-webkit-slider-runnable-track { height: 1px; background: var(--line); }
  input[type=range]::-moz-range-track { height: 1px; background: var(--line); }
  /* Deliberately large: this is dragged with a thumb, not a mouse. */
  input[type=range]::-webkit-slider-thumb {
    -webkit-appearance: none; appearance: none;
    width: 22px; height: 22px; border-radius: 50%;
    background: var(--page); border: 1.5px solid var(--ink);
    margin-top: -11px; cursor: grab;
  }
  input[type=range]::-moz-range-thumb {
    width: 22px; height: 22px; border-radius: 50%;
    background: var(--page); border: 1.5px solid var(--ink); cursor: grab;
  }
  .wave-wrap { position: relative; margin: 10px 0 2px; }
  #waveform {
    display: block; width: 100%; height: 88px;
    border: 1px solid var(--line); border-radius: var(--radius);
    cursor: crosshair; touch-action: none;
  }
  .wave-note {
    position: absolute; inset: 0;
    display: flex; align-items: center; justify-content: center;
    background: var(--surface-2);
    border: 1px solid var(--line); border-radius: var(--radius);
  }
  .scrubber.previewing { border-color: var(--ink); }
  .scrubber.previewing #scrubNow { animation: blink 1.1s infinite; }
  @keyframes blink { 50% { opacity: .35; } }

  /* ---- dashboards editor ---- */
  .cat-row { display: flex; gap: 8px; align-items: center; padding: 8px 0; border-bottom: 1px solid var(--line-2); }
  .cat-row .cat-emoji { width: 52px; flex: 0 0 52px; text-align: center; }
  .cat-row .cat-name { flex: 1; min-width: 70px; }
  .cat-row .count { flex: 0 0 26px; text-align: center; font-variant-numeric: tabular-nums; }
  .cat-row .mini { padding: 7px 9px; border-color: var(--line); color: var(--muted); }
  .cat-row .mini:hover { border-color: var(--ink); color: var(--text); background: transparent; }

  /* ---- connect row ----
     One line by default and stuck to the bottom of the viewport, so it stays
     reachable without taking board space. The explanation is behind the +. */
  .connect-row {
    position: sticky; bottom: 0; z-index: 4;
    background: var(--page);
    border-top: 1px solid var(--line);
    /* .pages grows to fill the column, so this sits at the bottom on short
       boards by layout; sticky keeps it there on long ones. */
  }
  .connect-line {
    display: flex; align-items: center; gap: 10px;
    padding: 10px 0;
    min-height: 52px;
  }
  .connect-label {
    flex: 1; min-width: 0;
    font-size: 13px; font-weight: 500;
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  }
  .connect-row .mini { flex: 0 0 auto; }
  .chev-btn {
    flex: 0 0 auto; width: 32px; height: 32px; padding: 0;
    border: 1px solid var(--line); border-radius: var(--radius);
    color: var(--muted); font-size: 13px; line-height: 1;
    display: inline-flex; align-items: center; justify-content: center;
    min-height: 0;
  }
  .chev-btn::before { content: '+'; }
  .connect-row.open .chev-btn::before { content: '−'; }
  .chev-btn:hover { border-color: var(--ink); color: var(--text); background: transparent; }
  .connect-detail { padding: 0 0 14px; }
  .connect-detail .row { margin-top: 10px; }

  /* ---- bundled sound library ---- */
  .sound-item {
    display: flex; align-items: center; gap: 12px;
    padding: 11px 0; border-bottom: 1px solid var(--line-2);
    cursor: pointer;
  }
  .sound-item.on { border-bottom-color: var(--ink); }
  .sound-item .pick {
    flex: 0 0 18px; height: 18px; border: 1px solid var(--line);
    border-radius: 50%;
  }
  .sound-item.on .pick { border-color: var(--ink); background: var(--ink); box-shadow: inset 0 0 0 3px var(--page); }
  .sound-item .info { flex: 1; min-width: 0; }
  .sound-item .n { font-size: 14px; font-weight: 500; }
  .sound-item .c {
    font-size: 11px; color: var(--muted); margin-top: 2px;
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  }
  .sound-item .try { flex: 0 0 auto; }

  /* ---- gallery ---- */
  .gallery-item {
    display: flex; align-items: center; gap: 12px;
    padding: 12px 0; border-bottom: 1px solid var(--line-2);
    cursor: pointer;
  }
  .gallery-item:hover .gallery-name { text-decoration: underline; text-underline-offset: 3px; }
  .gallery-item .info { flex: 1; min-width: 0; }
  .gallery-name { font-size: 14px; font-weight: 600; }
  .gallery-desc { font-size: 12.5px; color: var(--muted); margin-top: 2px; }
  .gallery-meta {
    font-size: 10.5px; color: var(--muted); margin-top: 5px;
    letter-spacing: 0.06em; text-transform: uppercase;
    font-variant-numeric: tabular-nums;
  }
  .gallery-item .go { color: var(--muted); font-size: 16px; flex: 0 0 auto; }

  /* ---- backup ---- */
  .checkrow { display: flex; align-items: center; gap: 9px; font-size: 13px; color: var(--text); margin: 14px 0; cursor: pointer; }
  .checkrow label, .checkrow span { text-transform: none; letter-spacing: 0; font-size: 13px; color: var(--text); font-weight: 400; margin: 0; }
  .import-panel { border: 1px solid var(--ink); border-radius: var(--radius); padding: 14px; margin-top: 14px; }
  .import-panel ul { margin: 10px 0 14px; padding-left: 18px; font-size: 13px; color: var(--muted); }
  .import-panel li { margin-bottom: 3px; }

  /* ---- setup ---- */
  .setup-uri {
    border: 1px solid var(--line); border-radius: var(--radius);
    padding: 11px 12px; font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
    font-size: 12.5px; word-break: break-all; margin: 10px 0;
    background: var(--surface-2);
  }
  .warnbox {
    border: 1px solid var(--ink); border-left-width: 3px;
    border-radius: var(--radius); padding: 12px 14px;
    font-size: 13px; margin-bottom: 18px;
  }

  /* ---- toast ---- */
  .toast {
    position: fixed; left: 50%; bottom: 24px; transform: translate(-50%, 150%);
    background: var(--ink); color: var(--on-ink);
    border-radius: var(--radius);
    padding: 13px 18px; font-size: 13.5px; font-weight: 450;
    max-width: min(520px, calc(100vw - 32px)); z-index: 100;
    transition: transform .22s ease, opacity .22s ease; opacity: 0;
    text-align: center; line-height: 1.45;
  }
  .toast.show { transform: translate(-50%, 0); opacity: 1; }
  .toast.error { border: 1px solid var(--ink); }

  /* ---- landscape on a tablet ----
     Wide and short. The narrow reading column wastes most of the screen, and
     square tiles at two columns push the board metres past the fold. Here the
     container goes full width, the grid auto-fills, and the page itself stops
     scrolling: the transport bar, the tabs and the connect row stay put, and
     only the board scrolls if a dashboard is unusually full. That matters
     during a game — Stop must never be scrolled off. */
  @media (orientation: landscape) and (min-width: 820px) {
    body { height: 100dvh; overflow: hidden; padding: 10px 20px 0; }
    /* Capped so a wide monitor shows a centred app rather than one long row
       of tiles your eye has to track across. 1400 sits just above the widest
       tablet (12.9" iPad is 1366), so no tablet is affected, and it gives the
       same 7 columns on a desktop that the 12.9" already gets. */
    .container { max-width: 1400px; margin-inline: auto; min-height: 0; }
    /* min-height:0 lets these flex children shrink instead of forcing the
       column taller than the viewport. */
    .pages { min-height: 0; }
    .page { overflow-y: auto; scrollbar-width: none; padding-bottom: 10px; }
    .page::-webkit-scrollbar { display: none; }
    .grid { grid-template-columns: repeat(auto-fill, minmax(170px, 1fr)); gap: 12px; }
    #stopAllBar { padding: 2px 0 10px; }
    .tabbar { margin-bottom: 12px; }
    .footer { padding-top: 12px; padding-bottom: 6px; }
  }

  /* A phone on its side: the same idea, with the chrome squeezed so the board
     still gets a usable share of ~400px of height. */
  @media (orientation: landscape) and (max-height: 520px) {
    .grid { grid-template-columns: repeat(auto-fill, minmax(130px, 1fr)); gap: 10px; }
    .tab { min-height: 40px; padding: 10px 12px 8px; }
    .tab-add { min-height: 40px; padding: 10px 14px 8px; }
    .icon-btn { width: 40px; height: 40px; }
    #stopAllBar button { min-height: 38px; padding: 8px 14px; }
    .connect-line { min-height: 44px; padding: 6px 0; }
    .footer { padding-top: 8px; }
    .footer h1 { font-size: 11px; }
    .copyright { font-size: 10px; }
  }
