/* Frozen copy of the board styling live before the new designer (bobaqueue.com board.html, 2026-09-25).
   Boards saved before it (no typographyVersion, or 1) keep exactly this look until the owner publishes
   from the new designer, which stamps typographyVersion 2 and switches board.html to its own <style>.
   Do not edit: tests/board-classic-parity.render.py compares it with the frozen live render. */
  :root {
    /* Customer and shop names may use any writing system. Named OS/Noto faces
       make selection predictable where available; sans-serif remains the
       browser's per-glyph fallback for scripts not installed by name. */
    --bq-font-stack: -apple-system, BlinkMacSystemFont, "SF Pro Display", "SF Pro Text",
      "Helvetica Neue", Inter, Roboto, "Noto Sans", "Noto Sans Arabic",
      "Noto Sans Hebrew", "Noto Sans Devanagari", "Noto Sans Bengali",
      "Noto Sans Thai", "Noto Sans SC", "Noto Sans TC", "Noto Sans JP",
      "Noto Sans KR", "Noto Sans CJK SC", "Noto Sans CJK TC",
      "Noto Sans CJK JP", "Noto Sans CJK KR", "PingFang SC", "PingFang TC",
      "Hiragino Sans", "Yu Gothic UI", Meiryo, "Apple SD Gothic Neo",
      "Malgun Gothic", "Microsoft YaHei UI", "Microsoft JhengHei UI",
      "Nirmala UI", "Leelawadee UI", "Segoe UI", system-ui,
      "DejaVu Sans", Arial, sans-serif;
  }
  * { box-sizing: border-box; margin: 0; }
  html, body { width: 100%; height: 100%; overflow: hidden; }
  body {
    display: flex;
    flex-direction: column;
    background: var(--bg);
    color: var(--text);
    font-family: "Avenir Next", var(--bq-font-stack);
  }
  body.type-rounded {
    font-family: "Pickup Lexend", var(--bq-font-stack);
  }
  body.type-editorial {
    font-family: "Pickup Fraunces", var(--bq-font-stack);
  }
  body.type-condensed {
    font-family: "Pickup IBM Plex Sans Condensed", var(--bq-font-stack);
  }
  body.type-modern {
    font-family: "Pickup Space Grotesk", var(--bq-font-stack);
  }
  body.type-hyperlegible {
    font-family: "Pickup Atkinson Hyperlegible Next", var(--bq-font-stack);
  }
  body.type-noto-sans {
    font-family: "Pickup Noto Sans", var(--bq-font-stack);
  }

  .hdr {
    display: flex;
    flex: none;
    align-items: center;
    gap: 14px;
    min-height: 72px;
    padding: 16px 28px;
    background: var(--headerBg);
    border-bottom: 2px solid var(--accent, var(--readyTitle));
  }
  .enso {
    width: 40px;
    height: 40px;
    flex: none;
    border: 3px solid var(--accent, var(--textDark));
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 18px;
    overflow: hidden;
  }
  .wordmark {
    min-width: 0;
    color: var(--textDark);
    font-size: clamp(22px, 2.1vw, 32px);
    font-weight: 800;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    /* Same F20 clip-window idiom as .ord .customer: overflow:hidden clips at the padding box,
       and the shop name is exactly as Vietnamese as the customer names — "Phở"-class marks sit
       above cap height and Ậ/ặ/ợ dot-below descenders reach under the normal SF Pro line box
       (~1.16em), which shaved up to 0.62px at template sizes and 3.3px in the portrait
       display-full header where line-height is 1. The padding extends only the vertical clip
       window; the equal negative margin hands the space straight back, so the margin box, header
       heights, and flex centering are byte-identical and the ellipsis still fires at the
       unpadded left/right edges. Cascades into every template's wordmark, including the
       portrait display-full variant; overflow:visible wordmarks (brand-sidebar/corner
       landscape) never clipped and are unaffected. */
    padding-block: .3em;
    margin-block: -.3em;
  }
  .hdrtag {
    margin-left: auto;
    color: var(--muted);
    font-size: 12px;
    font-weight: 750;
    letter-spacing: .2em;
    text-transform: uppercase;
    white-space: nowrap;
  }
  .clock {
    flex: none;
    font-size: 17px;
    font-variant-numeric: tabular-nums;
    font-weight: 750;
  }
  .cols {
    flex: 1;
    display: flex;
    gap: 18px;
    min-height: 0;
    padding: 18px 24px 24px;
  }
  .col {
    flex: 1;
    min-width: 0;
    min-height: 0;
    padding: 16px;
    border-radius: 16px;
    display: flex;
    flex-direction: column;
    gap: 9px;
    overflow: hidden;
  }
  .colMaking { background: var(--headerBg); border: 1px solid var(--border); }
  .colReady { background: var(--readyBg); }
  .coltitle {
    flex: none;
    margin-bottom: 4px;
    font-size: 15px;
    font-weight: 800;
    letter-spacing: .18em;
    line-height: 1.25;
    text-transform: uppercase;
  }
  .colMaking .coltitle { color: var(--muted); }
  .colReady .coltitle { color: var(--readyTitle); }
  .list {
    min-height: 0;
    display: flex;
    flex-direction: column;
    gap: 9px;
  }
  .ord {
    min-width: 0;
    padding: 12px 16px;
    border-radius: 12px;
    background: var(--card);
    display: flex;
    align-items: center;
    gap: 9px;
    font-size: clamp(17px, 1.6vw, 24px);
    font-weight: 700;
    line-height: 1.15;
  }
  .ord .customer {
    /* max-width is what actually makes the ellipsis fire. overflow+text-overflow only clip when the
       box is narrower than its text, and in a COLUMN flex row with align-items:flex-start the box
       shrink-to-fits its content, so it never is. Marquee's Making strip hit exactly that: a 29-char
       name rendered a 378px span inside a 295px card and bled 99px into the neighbouring card, with
       the ellipsis rule present and inert the whole time. Capping at the container width costs
       nothing to a name that already fits. */
    max-width: 100%;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    /* overflow:hidden clips at the padding box, and every template line box (1.0-1.15em) is
       shorter than stacked-diacritic ink: Ậ measures ~1.14em and clears cap height, so Vietnamese
       tildes/circumflexes (and dot-below descenders) were shaved off — F20. The padding extends
       only the vertical clip window; the equal negative margin hands the space straight back, so
       the margin box, card heights, and row fit are byte-identical and the ellipsis still fires
       at the unpadded left/right edges. */
    padding-block: .3em;
    margin-block: -.3em;
  }
  /* A nameless order (ticket/auto entry mode, showNames still true) still emits this span empty —
     collapse it here rather than leaving a blank gap before the ticket number. */
  .ord .customer:empty { display: none; }
  body.shape-square .ord { border-radius: 2px; }
  body.shape-soft .ord { border-radius: 12px; }
  body.shape-round .ord { border-radius: 24px; }
  .ord .num {
    flex: none;
    color: var(--muted);
    font-size: .65em;
    font-variant-numeric: tabular-nums;
    font-weight: 700;
  }
  .ord .src {
    flex: none;
    color: var(--muted);
    font-size: 10px;
    font-weight: 800;
    letter-spacing: .08em;
  }
  .eta {
    margin-left: auto;
    padding: 4px 12px;
    border-radius: 99px;
    background: var(--waitBg);
    color: var(--waitText);
    font-size: clamp(12px, 1vw, 15px);
    font-variant-numeric: tabular-nums;
    font-weight: 800;
    white-space: nowrap;
  }
  .colReady .ord {
    background: var(--readyCard, var(--headerBg));
    border: 2px solid var(--readyBorder);
    color: var(--readyText);
    font-size: clamp(20px, 1.8vw, 28px);
  }
  .colReady .ord .num { color: var(--readyTitle); }
  .ready-mark {
    margin-left: auto;
    color: var(--readyTitle);
    font-size: 10px;
    font-weight: 850;
    letter-spacing: .12em;
    text-transform: uppercase;
  }
  .anim { animation: board-in .3s ease-out; }
  @keyframes board-in {
    from { opacity: 0; transform: translateY(-8px); }
    to { opacity: 1; transform: translateY(0); }
  }
  .colReady .ord.fresh { animation: ready-in .45s cubic-bezier(.2, .9, .25, 1.2); }
  @keyframes ready-in {
    from { opacity: 0; transform: scale(.92); }
    to { opacity: 1; transform: scale(1); }
  }
  #expiredList {
    margin-top: auto;
    display: flex;
    flex-direction: column;
    gap: 7px;
  }
  .expiredRow {
    padding: 9px 13px;
    border: 1px dashed #D9B98F;
    border-radius: 10px;
    background: #FBEFE0;
    color: #75562F;
    font-size: 14px;
    font-weight: 650;
  }
  .overflow-note {
    padding: 5px;
    color: var(--muted);
    font-size: 13px;
    font-weight: 700;
    text-align: center;
  }

  /* Header and composition controls stay independent from each template's component grammar. */
  body.header-compact .hdr { gap: 10px; min-height: 54px; padding: 9px 22px; }
  body.header-compact .enso { width: 32px; height: 32px; border-width: 2px; font-size: 15px; }
  body.header-compact .wordmark { font-size: 22px; }
  body.header-compact .hdrtag { font-size: 10px; }
  body.header-compact .clock { font-size: 15px; }
  body.header-centered .hdr { position: relative; justify-content: center; padding-inline: 112px; }
  body.header-centered .hdrtag { margin-left: 0; }
  body.header-centered .clock { position: absolute; right: 28px; }

  body.layout-balanced .colMaking { flex: 1.18; }
  body.layout-balanced .colReady { flex: .82; }
  body.layout-queue-rail .cols {
    display: grid;
    grid-template-columns: minmax(0, 3fr) minmax(210px, 1fr);
    gap: 14px;
    padding: 14px 20px 20px;
  }
  body.layout-queue-rail .colMaking {
    margin: 0;
    padding-left: 0;
    border: 0;
    background: transparent;
  }
  body.layout-queue-rail .colReady { border-radius: 8px; padding: 15px 12px; }
  body.layout-queue-rail .colReady .coltitle { text-align: center; }
  body.layout-queue-rail .colReady .ord { padding-inline: 10px; }
  body.layout-queue-rail .colReady .src,
  body.layout-queue-rail .colReady .ready-mark { display: none; }
  body.layout-ready-spotlight .cols {
    display: grid;
    grid-template-columns: 1fr;
    grid-template-rows: minmax(0, 1.65fr) minmax(170px, .95fr);
    gap: 12px;
    padding: 14px 20px 20px;
  }
  body.layout-ready-spotlight .colReady { order: 1; padding: 14px 18px; }
  body.layout-ready-spotlight .colMaking { order: 2; padding: 12px 14px; }
  body.layout-ready-spotlight .colReady .coltitle {
    font-size: clamp(15px, 1.3vw, 20px);
    text-align: center;
  }
  body.layout-ready-spotlight .colReady .list {
    flex: 1;
    display: grid;
    grid-template-columns: repeat(4, minmax(0, 1fr));
    grid-template-rows: repeat(2, minmax(0, 1fr));
    gap: 10px;
  }
  body.layout-ready-spotlight .colReady .ord {
    min-width: 0;
    justify-content: center;
    padding: 14px;
  }
  body.layout-ready-spotlight .colMaking .list {
    display: grid;
    grid-template-columns: repeat(4, minmax(0, 1fr));
    gap: 8px;
  }
  body.layout-ready-spotlight .colMaking .ord {
    min-width: 0;
    padding: 8px 11px;
    font-size: clamp(14px, 1.35vw, 20px);
  }
  body.layout-ready-spotlight .colMaking .src { display: none; }
  body.layout-ready-spotlight .eta { padding-inline: 8px; font-size: 11px; }
  body.layout-ready-spotlight #expiredList {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 6px;
    margin-top: 8px;
  }
  body.layout-ready-spotlight .expiredRow {
    min-width: 0;
    padding: 6px 9px;
    overflow: hidden;
    font-size: 12px;
    text-overflow: ellipsis;
    white-space: nowrap;
  }

  body.density-compact .cols { gap: 10px; padding: 10px 16px 16px; }
  body.density-compact .col { gap: 5px; padding: 10px; }
  body.density-compact .list { gap: 5px; }
  body.density-compact .coltitle { margin-bottom: 1px; font-size: 12px; }
  body.density-compact .ord { gap: 7px; padding: 7px 11px; font-size: clamp(15px, 1.35vw, 20px); }
  body.density-compact .colReady .ord { font-size: clamp(17px, 1.5vw, 22px); }
  body.density-compact .eta { padding: 2px 8px; font-size: 11px; }
  body.layout-queue-rail.density-compact .cols { padding: 10px 14px 14px; }
  body.layout-ready-spotlight.density-compact .cols {
    grid-template-rows: minmax(0, 1.55fr) minmax(150px, .85fr);
    gap: 8px;
  }

  /* BobaQueue Clean: one system sans, an inset ledger, and an announcement panel.
     Row height comes from the grid track, not from padding, so the board fills the
     frame at any order count and the shared 7-row compaction is a no-op here.
     Weights stay 400/600/700 — a Pi falling back to DejaVu has no 500. */
  body.template-bliss-light.type-clean {
    font-family: var(--bq-font-stack);
  }

  /* Header is a toolbar: no ring around the mark, no accent rule. */
  body.template-bliss-light .hdr {
    background: var(--headerBg);
    border-bottom: 1px solid var(--border);
  }
  body.template-bliss-light.header-classic .hdr {
    gap: clamp(12px, 1vw, 20px);
    min-height: clamp(74px, 8.4vh, 108px);
    padding: 0 clamp(26px, 2.5vw, 50px);
  }
  body.template-bliss-light .hdr .enso {
    border: 0;
    border-radius: 0;
    font-size: clamp(24px, 2.1vw, 44px);
    overflow: visible;
  }
  body.template-bliss-light.header-classic .hdr .enso {
    height: clamp(32px, 2.6vw, 54px);
    width: clamp(32px, 2.6vw, 54px);
  }
  body.template-bliss-light .wordmark {
    color: var(--textDark);
    font-size: clamp(26px, 2.15vw, 46px);
    font-weight: 600;
    letter-spacing: -.021em;
  }
  @media (min-width: 761px) and (min-aspect-ratio: 1.001/1) {
  body.template-bliss-light.header-centered .hdr { display:grid; grid-template-columns:auto auto; column-gap:16px; row-gap:4px; padding-block:12px; }
  body.template-bliss-light.header-centered .enso { grid-column:1; grid-row:1; }
  body.template-bliss-light.header-centered .wordmark { grid-column:2; grid-row:1; }
  body.template-bliss-light.header-centered .hdrtag { grid-column:2; grid-row:2; justify-self:start; }
  body.template-bliss-light.header-centered .clock { top:50%; transform:translateY(-50%); }
  }
  #boardModeLabel[hidden], #makingTitle[hidden], #readyTitle[hidden] { display:none !important; }
  body.template-bliss-light .hdrtag {
    color: var(--muted);
    font-size: clamp(11px, .8vw, 17px);
    font-weight: 600;
    letter-spacing: .18em;
  }
  body.template-bliss-light .clock {
    color: var(--text);
    font-size: clamp(15px, 1.1vw, 23px);
    font-weight: 600;
    letter-spacing: -.01em;
  }
  body.template-bliss-light.header-classic .clock,
  body.template-bliss-light.header-compact .clock {
    border-left: 1px solid var(--border);
    padding-left: clamp(12px, 1vw, 20px);
  }

  /* Two inset panels on a grey field; Ready is the elevated one. */
  body.template-bliss-light.density-comfortable .cols {
    gap: clamp(18px, 1.9vw, 38px);
    padding: clamp(16px, 2.2vh, 32px) clamp(22px, 2.4vw, 48px) clamp(18px, 2.6vh, 38px);
  }
  body.template-bliss-light.density-compact .cols {
    gap: clamp(12px, 1.3vw, 24px);
    padding: clamp(10px, 1.4vh, 20px) clamp(14px, 1.6vw, 30px) clamp(12px, 1.8vh, 24px);
  }
  body.template-bliss-light .col { border-radius: clamp(12px, 1.05vw, 22px); }
  body.template-bliss-light .col.colMaking {
    background: var(--card);
    border: 1px solid var(--border);
    box-shadow: none;
    flex: 1.1;
    gap: 0;
    padding: clamp(16px, 2vh, 28px) clamp(18px, 1.6vw, 32px) clamp(8px, 1vh, 16px);
  }
  body.template-bliss-light .col.colReady {
    background: var(--readyBg);
    border: 0;
    box-shadow: 0 1px 2px rgba(22, 22, 26, .05), 0 14px 36px rgba(22, 22, 26, .07);
    flex: 1;
    gap: 0;
    padding: clamp(18px, 2.3vh, 32px) clamp(20px, 1.8vw, 36px) clamp(12px, 1.6vh, 22px);
  }

  /* Both headings share a baseline so equal size controls produce equal type. */
  body.template-bliss-light .col .coltitle {
    font-size: clamp(15px, 1.18vw, 25px);
    align-items: center;
    display: flex;
    gap: .62em;
    letter-spacing: .16em;
    line-height: 1.2;
    margin: 0;
    padding-bottom: clamp(10px, 1.3vh, 18px);
    text-transform: uppercase;
  }
  body.template-bliss-light .col.colMaking .coltitle {
    border-bottom: 1px solid var(--border);
    color: var(--muted);
    font-weight: 600;
  }
  body.template-bliss-light .col.colReady .coltitle {
    color: var(--readyTitle);
    font-weight: 700;
  }
  /* The list owns the column height; tracks divide it evenly. */
  body.template-bliss-light .col .list {
    align-content: stretch;
    display: grid;
    flex: 1;
    gap: 0;
    grid-auto-rows: minmax(0, 1fr);
    padding-top: clamp(6px, .8vh, 14px);
  }
  /* Quiet service (1-3): cap the tracks and centre the group instead of stranding
     three rows at the top. Browsers without :has() keep stretching — the safe failure. */
  body.template-bliss-light .col.colMaking .list:has(> .ord:first-child:nth-last-child(-n+3)) {
    align-content: center;
    grid-auto-rows: minmax(0, clamp(84px, 14vh, 190px));
  }
  body.template-bliss-light .col.colReady .list:has(> .ord:first-child:nth-last-child(-n+3)) {
    align-content: center;
    grid-auto-rows: minmax(0, clamp(104px, 19vh, 260px));
  }

  /* Making is a ledger: hairline-ruled rows, name first, wait time last. */
  body.template-bliss-light .col.colMaking .ord {
    align-items: center;
    background: transparent;
    border: 0;
    border-bottom: 1px solid var(--border);
    border-radius: 0;
    color: var(--text);
    /* vh term guards a wide-and-short panel, where a row-count rule cannot: at 1920x720
       eight rows overflowed the track by 4.6px and were clipped by .col overflow:hidden. */
    font-size: clamp(18px, min(2vw, 6.8vh), 48px);
    font-weight: 600;
    gap: clamp(8px, .7vw, 16px);
    letter-spacing: -.015em;
    line-height: 1.1;
    min-height: 0;
    padding: 0;
  }
  body.template-bliss-light .col.colMaking .ord:last-child { border-bottom: 0; }
  body.template-bliss-light .col.colMaking .ord:first-child:nth-last-child(-n+3),
  body.template-bliss-light .col.colMaking .ord:first-child:nth-last-child(-n+3) ~ .ord {
    font-size: clamp(21px, 2.55vw, 62px);
  }
  body.template-bliss-light .col.colMaking .num {
    color: var(--muted);
    font-size: .6em;
    font-variant-numeric: tabular-nums;
    font-weight: 600;
    letter-spacing: -.01em;
  }
  body.template-bliss-light .col .src {
    color: var(--muted);
    font-size: .32em;
    font-weight: 700;
    letter-spacing: .1em;
    text-transform: uppercase;
  }
  body.template-bliss-light .col .eta {
    background: transparent;
    border-radius: 0;
    color: var(--waitText);
    font-size: .62em;
    font-variant-numeric: tabular-nums;
    font-weight: 600;
    letter-spacing: -.005em;
    padding: 0;
  }

  /* Ready is an announcement: no rules, no cards, no badge — name and number only. */
  body.template-bliss-light .col.colReady .ord {
    align-items: center;
    background: transparent;
    border: 0;
    border-radius: 0;
    box-shadow: none;
    color: var(--readyText);
    font-size: clamp(24px, min(3.55vw, 7.2vh), 88px);
    font-weight: 600;
    gap: clamp(10px, .9vw, 20px);
    letter-spacing: -.028em;
    line-height: 1.02;
    min-height: 0;
    padding: 0;
  }
  body.template-bliss-light .col.colReady .ord:first-child:nth-last-child(-n+3),
  body.template-bliss-light .col.colReady .ord:first-child:nth-last-child(-n+3) ~ .ord {
    font-size: clamp(28px, 4.4vw, 108px);
  }
  body.template-bliss-light .col.colReady .num {
    color: var(--readyTitle);
    font-size: .46em;
    font-variant-numeric: tabular-nums;
    font-weight: 600;
    letter-spacing: -.01em;
    margin-left: auto;
    order: 2;
  }
  body.template-bliss-light .col.colReady .src,
  body.template-bliss-light .col.colReady .ready-mark { display: none; }

  /* Overflow and expiry are the last lines of their panel, not stickers. */
  body.template-bliss-light .overflow-note {
    color: var(--muted);
    font-size: clamp(14px, 1.12vw, 24px);
    font-weight: 600;
    padding: clamp(10px, 1.2vh, 18px) 0 0;
    text-align: left;
  }
  body.template-bliss-light #expiredList {
    border-top: 1px solid var(--border);
    gap: 0;
    margin-top: clamp(10px, 1.4vh, 20px);
    padding-top: clamp(8px, 1vh, 14px);
  }
  /* No uncollected orders is the normal case — don't leave a rule pointing at nothing. */
  body.template-bliss-light #expiredList:empty {
    border-top: 0;
    margin-top: 0;
    padding-top: 0;
  }
  body.template-bliss-light .expiredRow {
    background: transparent;
    border: 0;
    border-radius: 0;
    color: var(--muted);
    font-size: clamp(14px, 1.12vw, 24px);
    font-weight: 600;
    letter-spacing: -.005em;
    padding: clamp(4px, .5vh, 8px) 0;
  }
  /* renderBoard() inline-styles the expired order number at .6 opacity (~2.6:1). */
  body.template-bliss-light .expiredRow span { opacity: 1 !important; }

  body.template-bliss-light .anim,
  body.template-bliss-light .colReady .ord.fresh {
    animation: clean-in .34s cubic-bezier(.22, .61, .36, 1);
  }
  @keyframes clean-in {
    from { opacity: 0; transform: translateY(7px); }
    to { opacity: 1; transform: none; }
  }

  /* Service Grid: a service table, not a ledger. A tabular number column leads every scan,
     hairline rules carry the structure, and the pickup rail is the only lifted surface on the
     board. Rows keep a fixed rhythm and stay top-aligned — a timetable does not resize when it is
     quiet. Geometry is routed through .col.colMaking / .col.colReady / .list so the owner-control
     layer below cannot flatten the table at any density; weights stay 400/600 because a Pi
     falling back to DejaVu Sans has no 500 and CSS resolves it down to 400. */
  body.template-matcha-modern.type-clean {
    font-family: var(--bq-font-stack);
  }

  /* An ink chrome bar, the way terminal and departure boards do it: no accent underline,
     no ring around the mark. header-* never sets paint, so no chain is needed here. */
  body.template-matcha-modern .hdr {
    background: var(--headerBg);
    border-bottom: 0;
    color: var(--textDark);
  }
  body.template-matcha-modern .enso {
    background: transparent;
    border: 0;
    border-radius: 0;
    overflow: visible;
  }
  body.template-matcha-modern .wordmark {
    color: var(--textDark);
    font-weight: 600;
    letter-spacing: -.01em;
  }
  /* Utilities stay full white: muted on the ink bar is 2.57:1, and an rgba(255,255,255,…) dim
     would break if an owner republished headerBg light. Size and tracking separate them. */
  body.template-matcha-modern .hdrtag,
  body.template-matcha-modern .clock {
    color: var(--textDark);
    font-variant-numeric: tabular-nums;
    font-weight: 600;
  }
  /* header-compact owns this geometry, so chain the template's own header default. */
  body.template-matcha-modern.header-compact .hdr {
    gap: clamp(10px, 1vw, 18px);
    min-height: clamp(48px, min(3.6vw, 6.6vh), 70px);
    padding: 0 clamp(18px, 2vw, 40px);
  }
  body.template-matcha-modern.header-compact .enso {
    height: auto;
    width: auto;
    font-size: clamp(16px, 1.3vw, 24px);
  }
  body.template-matcha-modern.header-compact .wordmark { font-size: clamp(18px, 1.5vw, 28px); }
  body.template-matcha-modern.header-compact .hdrtag {
    font-size: clamp(9px, .72vw, 13px);
    letter-spacing: .16em;
  }
  body.template-matcha-modern.header-compact .clock { font-size: clamp(13px, 1.05vw, 20px); }
  body.template-matcha-modern.density-compact .cols {
    gap: clamp(14px, 1.5vw, 30px);
    padding: clamp(12px, 1.3vw, 26px) clamp(18px, 2vw, 40px) clamp(14px, 1.5vw, 30px);
  }

  /* The table has no panel: it rules straight onto the board ground. */
  body.template-matcha-modern .col.colMaking {
    background: transparent;
    border: 0;
    border-radius: 0;
    flex: 1;
    gap: clamp(6px, .7vw, 13px);
    padding: 0;
  }
  body.template-matcha-modern .col.colMaking .coltitle {
    border-bottom: 2px solid var(--accent);
    color: var(--muted);
    font-size: clamp(10px, .82vw, 15px);
    font-weight: 600;
    letter-spacing: .14em;
    margin-bottom: 0;
    padding-bottom: clamp(6px, .7vw, 13px);
  }
  /* Rows are grid tracks that divide the column, floored at the table's own rhythm, so eight
     rows and three rows both fill the frame. A closing rule under the last row bounds the
     table, and the space below it reads as outside the table rather than as a hole in it. */
  body.template-matcha-modern .col.colMaking .list {
    align-content: stretch;
    border-bottom: 1px solid var(--border);
    display: grid;
    flex: 1;
    gap: 0;
    grid-auto-rows: minmax(clamp(30px, min(3.2vw, 6.6vh), 62px), 1fr);
  }
  /* Quiet service: cap the tracks and keep the table top-aligned — a timetable does not centre
     its departures, which is where Metro and Clean's centred quiet step part ways. `flex: none`
     is load-bearing: a stretched list would strand the closing rule at the foot of the column,
     a hairline pointing at nothing 500px below the last row. */
  body.template-matcha-modern .col.colMaking .list:has(> .ord:first-child:nth-last-child(-n+3)) {
    align-content: start;
    flex: none;
    grid-auto-rows: minmax(0, clamp(84px, 17vh, 220px));
  }
  /* The vh terms are height guards: a row-count rule cannot see that 1920x720 has 360px less
     to spend than 1920x1080, so type is bounded by both axes instead of by order count. */
  body.template-matcha-modern .col.colMaking .list .ord {
    align-items: center;
    background: transparent;
    border: 0;
    border-bottom: 1px solid var(--border);
    box-shadow: none;
    column-gap: clamp(10px, 1vw, 22px);
    display: grid;
    font-size: clamp(19px, min(1.75vw, 4.4vh), 34px);
    font-weight: 400;
    grid-template-columns: minmax(2.6em, auto) minmax(0, 1fr) auto minmax(3.4em, auto);
    line-height: 1.1;
    min-height: 0;
    padding: clamp(5px, .55vw, 11px) 0;
  }
  body.template-matcha-modern .col.colMaking .list .ord:first-child:nth-last-child(-n+3),
  body.template-matcha-modern .col.colMaking .list .ord:first-child:nth-last-child(-n+3) ~ .ord {
    font-size: clamp(22px, min(2.4vw, 6.2vh), 46px);
  }
  body.template-matcha-modern .col.colMaking .list .ord:last-child { border-bottom: 0; }
  /* grid-row: 1 on every cell is load-bearing — .customer precedes .num in the DOM, so sparse
     auto-placement would push the number onto a second row and double the row height. */
  body.template-matcha-modern .col.colMaking .list .num {
    color: var(--text);
    font-size: 1em;
    font-variant-numeric: tabular-nums;
    font-weight: 600;
    grid-column: 1;
    grid-row: 1;
    letter-spacing: -.01em;
  }
  body.template-matcha-modern .col.colMaking .list .customer {
    font-size: max(13px, .68em);
    font-weight: 400;
    grid-column: 2;
    grid-row: 1;
  }
  body.template-matcha-modern .col.colMaking .list .src {
    color: var(--muted);
    font-size: clamp(9px, .72vw, 13px);
    font-weight: 600;
    grid-column: 3;
    grid-row: 1;
    letter-spacing: .08em;
  }
  /* The wait is a table column, not a chip: right-aligned tabular reference. */
  body.template-matcha-modern .col.colMaking .list .eta {
    background: transparent;
    border-radius: 0;
    color: var(--waitText);
    font-size: max(11px, .48em);
    font-variant-numeric: tabular-nums;
    font-weight: 400;
    grid-column: 4;
    grid-row: 1;
    justify-self: end;
    margin: 0;
    padding: 0;
    text-align: right;
  }

  /* Pickup rail: the only lifted surface. It hugs its content, so three collected orders never
     leave a white panel three-quarters empty. */
  body.template-matcha-modern .col.colReady {
    background: var(--readyBg);
    border: 1px solid var(--readyBorder);
    border-radius: 0;
    flex: .34;
    gap: clamp(7px, .8vw, 15px);
    padding: clamp(11px, 1.2vw, 24px) clamp(10px, 1.1vw, 22px);
  }
  /* `align-self: start` made the rail hug its rows: at six orders it stopped 70% down a 1011px
     column and the remaining 300px became a grey slab — the same dead-space complaint as the old
     lime panel, in a quieter colour. It stretches now, and the rows distribute inside it against a
     capped track so a two-order morning gets symmetric air instead of two rows adrift in a
     full-height rail. Same discipline as Clean's quiet state and the Ready-only pickup screen. */
  body.template-matcha-modern.layout-queue-rail .col.colReady {
    align-self: stretch;
    max-height: 100%;
  }
  body.template-matcha-modern .col.colReady .coltitle {
    border-bottom: 1px solid var(--readyBorder);
    color: var(--readyTitle);
    font-size: clamp(10px, .82vw, 15px);
    font-weight: 600;
    letter-spacing: .14em;
    margin-bottom: 0;
    padding-bottom: clamp(6px, .7vw, 13px);
    text-align: left;
  }
  body.template-matcha-modern .col.colReady .list {
    align-content: center;
    display: grid;
    /* flex:1 is what makes align-content mean anything — without it the list is only as tall as its
       tracks, so the spare height pools below the list instead of being centred within it. */
    flex: 1;
    gap: 0;
    grid-auto-rows: minmax(0, clamp(76px, 10.5vh, 200px));
  }
  /* column-reverse puts the ticket number above the name without a markup change — .customer
     precedes .num in the DOM, and on a rail read at 20 feet the number has to lead. */
  body.template-matcha-modern .col.colReady .list .ord {
    background: transparent;
    border: 0;
    border-bottom: 1px solid var(--readyBorder);
    border-radius: 0;
    box-shadow: none;
    color: var(--readyText);
    display: flex;
    flex-direction: column-reverse;
    gap: clamp(2px, .25vw, 5px);
    justify-content: flex-end;
    min-height: clamp(46px, min(4.1vw, 10.4vh), 80px);
    padding: clamp(6px, .7vw, 13px) 0;
  }
  body.template-matcha-modern .col.colReady .list .ord:last-child { border-bottom: 0; }
  body.template-matcha-modern .col.colReady .list .num {
    color: var(--readyText);
    font-size: clamp(24px, min(2.2vw, 5.6vh), 42px);
    font-variant-numeric: tabular-nums;
    font-weight: 600;
    letter-spacing: -.01em;
    line-height: 1;
    margin: 0;
  }
  body.template-matcha-modern .col.colReady .list .customer {
    font-size: clamp(13px, 1.1vw, 21px);
    font-weight: 400;
  }
  /* A column headed "Collect" does not need "READY" stamped on every row. */
  body.template-matcha-modern .ready-mark,
  body.template-matcha-modern .col.colReady .list .src { display: none; }

  /* An empty column is a state, not a void. */
  body.template-matcha-modern #makingList:empty::after,
  body.template-matcha-modern #readyList:empty::after {
    color: var(--muted);
    display: block;
    font-size: clamp(12px, 1.05vw, 20px);
    font-weight: 400;
    padding-top: clamp(8px, .9vw, 17px);
  }
  body.template-matcha-modern #makingList:empty::after { content: "Queue clear"; }
  body.template-matcha-modern #readyList:empty::after { content: "Nothing to collect yet"; }

  body.template-matcha-modern .expiredRow {
    background: transparent;
    border: 0;
    border-top: 1px solid var(--readyBorder);
    border-radius: 0;
    color: var(--muted);
    font-size: clamp(11px, 1vw, 19px);
    font-weight: 400;
    padding: clamp(6px, .7vw, 13px) 0;
  }
  /* renderBoard() inline-styles the expired order number at .6 opacity (~2.6:1). */
  body.template-matcha-modern .expiredRow span { opacity: 1 !important; }
  body.template-matcha-modern .overflow-note {
    color: var(--muted);
    font-size: clamp(11px, .95vw, 18px);
    font-weight: 600;
    letter-spacing: .04em;
    padding: clamp(6px, .7vw, 13px) 0 0;
    text-align: left;
  }
  /* directional-slide, restrained: one short lateral settle, no bounce. */
  body.template-matcha-modern .anim,
  body.template-matcha-modern .colReady .ord.fresh {
    animation: metro-in .24s cubic-bezier(.22, .61, .36, 1);
  }
  @keyframes metro-in {
    from { opacity: 0; transform: translateX(-7px); }
    to { opacity: 1; transform: none; }
  }

  /* Night Service: a low-glare stacked board — a lit pickup stage above a status ticker.
     The ground is near-neutral ink so lightness alone carries elevation, the single sage accent
     is the only color on the board, and text stops at #EDEFEF rather than pure white so large
     type does not bloom on an LED panel at night. The one template where cardShape is visible:
     dark grounds swallow hairlines, so the ticker cells are real surfaces and take the radius. */
  body.template-midnight-pearl.type-clean {
    font-family: var(--bq-font-stack);
  }
  body.template-midnight-pearl .hdr {
    background: transparent;
    border-bottom: 1px solid var(--border);
  }
  body.template-midnight-pearl .enso {
    background: transparent;
    border: 0;
    box-shadow: none;
    overflow: visible;
  }
  body.template-midnight-pearl .hdrtag,
  body.template-midnight-pearl .clock {
    color: var(--muted);
    font-variant-numeric: tabular-nums;
    font-weight: 600;
  }
  body.template-midnight-pearl.header-centered .hdr {
    gap: clamp(10px, 1vw, 18px);
    min-height: clamp(52px, min(4.6vw, 8.2vh), 88px);
    padding: 0 clamp(84px, 7vw, 132px);
  }
  body.template-midnight-pearl.header-centered .enso {
    height: auto;
    width: auto;
    font-size: clamp(17px, 1.5vw, 28px);
  }
  body.template-midnight-pearl.header-centered .wordmark {
    color: var(--textDark);
    font-size: clamp(19px, 1.7vw, 32px);
    font-weight: 600;
    letter-spacing: .01em;
  }
  body.template-midnight-pearl.header-centered .hdrtag {
    font-size: clamp(9px, .75vw, 13px);
    letter-spacing: .16em;
  }
  body.template-midnight-pearl.header-centered .clock {
    font-size: clamp(13px, 1.05vw, 20px);
    right: clamp(22px, 2vw, 40px);
  }
  body.template-midnight-pearl.density-comfortable .cols {
    gap: clamp(10px, 1.1vw, 22px);
    padding: clamp(12px, 1.3vw, 26px) clamp(18px, 2vw, 40px) clamp(14px, 1.5vw, 30px);
  }
  /* The ticker hugs its rows and the stage takes the rest, rather than both zones holding a
     fixed fraction — a three-order ticker otherwise leaves 200px of dead band under itself.
     Deliberately not chained to density: this is Pearl's composition, not a spacing preference. */
  body.template-midnight-pearl.layout-ready-spotlight .cols {
    grid-template-rows: minmax(0, 1fr) min-content;
  }

  /* The stage: one lightness step up from the ground, bounded by a 2.19:1 sage hairline that
     survives a TV at twenty feet. Never a bright slab — glare avoidance is the whole template. */
  body.template-midnight-pearl .col.colReady {
    background: var(--readyBg);
    border: 1px solid var(--readyBorder);
    border-radius: 12px;
    gap: clamp(9px, 1vw, 18px);
    padding: clamp(14px, 1.5vw, 30px) clamp(16px, 1.8vw, 36px);
  }
  body.template-midnight-pearl .col.colReady .coltitle {
    color: var(--readyTitle);
    font-size: clamp(10px, .88vw, 16px);
    font-weight: 600;
    letter-spacing: .14em;
    margin-bottom: 0;
    text-align: center;
  }
  /* auto-fit collapses the empty tracks, so one ready order is one full-width headline instead
     of one cell in an eight-cell grid with seven holes. Resetting grid-template-rows is required
     — the layout layer pins two explicit rows, which would leave a single name filling only the
     top half of the stage. */
  body.template-midnight-pearl.layout-ready-spotlight .col.colReady .list {
    display: grid;
    flex: 1;
    gap: clamp(6px, .7vw, 14px);
    grid-auto-rows: minmax(0, 1fr);
    /* The px floor is a legibility guard, not decoration: a percentage-only track always
       yields four columns, so a 1280-wide panel gave 265px cells and ellipsised real names.
       max() keeps four across at 1920 and drops to three where the name would not fit. */
    grid-template-columns: repeat(auto-fit, minmax(min(100%, max(22%, 320px)), 1fr));
    grid-template-rows: none;
  }
  body.template-midnight-pearl .col.colReady .list .ord {
    align-items: center;
    background: transparent;
    border: 0;
    border-radius: 0;
    box-shadow: none;
    color: var(--readyText);
    display: flex;
    flex-direction: column;
    gap: clamp(4px, .45vw, 9px);
    justify-content: center;
    min-height: 0;
    padding: clamp(6px, .7vw, 14px);
    text-align: center;
  }
  body.template-midnight-pearl .col.colReady .list .customer {
    font-size: clamp(30px, min(3.4vw, 9vh), 68px);
    font-weight: 600;
    letter-spacing: -.02em;
    line-height: 1.02;
    width: 100%;
  }
  /* Quiet service is what a spotlight is for: one to three names take the extra room the
     hugging ticker gives back. Bounded on both axes so a short panel cannot clip them. */
  body.template-midnight-pearl .col.colReady .list .ord:first-child:nth-last-child(-n+3) .customer,
  body.template-midnight-pearl .col.colReady .list .ord:first-child:nth-last-child(-n+3) ~ .ord .customer {
    font-size: clamp(32px, min(4vw, 10.4vh), 84px);
  }
  /* Absolute, not em: the stage sets its scale on .customer, so an em here would resolve
     against the untouched base .ord size and collapse to ~8px. */
  body.template-midnight-pearl .col.colReady .list .num {
    color: var(--readyTitle);
    font-size: clamp(13px, 1.15vw, 22px);
    font-variant-numeric: tabular-nums;
    font-weight: 400;
    letter-spacing: .06em;
    margin: 0;
  }
  body.template-midnight-pearl .ready-mark,
  body.template-midnight-pearl .col.colReady .list .src { display: none; }

  /* The ticker: a low band of surfaces under the stage. */
  body.template-midnight-pearl .col.colMaking {
    background: transparent;
    border: 0;
    border-radius: 0;
    border-top: 1px solid var(--border);
    gap: clamp(7px, .8vw, 15px);
    padding: clamp(11px, 1.2vw, 24px) clamp(4px, .5vw, 10px) 0;
  }
  body.template-midnight-pearl .col.colMaking .coltitle {
    color: var(--muted);
    font-size: clamp(10px, .88vw, 16px);
    font-weight: 600;
    letter-spacing: .14em;
    margin-bottom: 0;
  }
  body.template-midnight-pearl.layout-ready-spotlight .col.colMaking .list {
    display: grid;
    gap: clamp(6px, .7vw, 14px);
    grid-template-columns: repeat(auto-fit, minmax(min(100%, 23%), 1fr));
  }
  /* border-radius is deliberately left to the shape-* layer: this is the one board where the
     owner's cardShape control has something to act on. */
  body.template-midnight-pearl .col.colMaking .list .ord {
    background: var(--card);
    border: 0;
    font-size: clamp(15px, 1.35vw, 26px);
    font-weight: 400;
    letter-spacing: -.01em;
    min-height: clamp(38px, min(3.2vw, 7.4vh), 62px);
    padding: clamp(7px, .8vw, 15px) clamp(9px, 1vw, 19px);
  }
  body.template-midnight-pearl .col.colMaking .list .num {
    color: var(--muted);
    font-size: max(12px, .7em);
    font-variant-numeric: tabular-nums;
    font-weight: 400;
  }
  body.template-midnight-pearl .col.colMaking .list .src {
    color: var(--muted);
    font-size: clamp(9px, .75vw, 13px);
    font-weight: 600;
    letter-spacing: .06em;
  }
  /* No purple chip: the wait is quiet reference text on the cell it belongs to. */
  body.template-midnight-pearl .col.colMaking .list .eta {
    background: transparent;
    border-radius: 0;
    color: var(--waitText);
    font-size: max(11px, .62em);
    font-variant-numeric: tabular-nums;
    font-weight: 400;
    padding: 0;
  }

  body.template-midnight-pearl #readyList:empty::after,
  body.template-midnight-pearl #makingList:empty::after {
    color: var(--muted);
    display: block;
    font-size: clamp(13px, 1.15vw, 22px);
    font-weight: 400;
  }
  body.template-midnight-pearl #readyList:empty::after {
    align-self: center;
    content: "Ready orders appear here";
    padding: clamp(10px, 1.2vw, 22px) 0;
    text-align: center;
  }
  body.template-midnight-pearl #makingList:empty::after { content: "Nothing in the works"; }

  body.template-midnight-pearl .expiredRow {
    background: var(--card);
    border: 0;
    border-radius: 8px;
    color: var(--muted);
    font-size: clamp(11px, 1vw, 19px);
    font-weight: 400;
    padding: clamp(6px, .7vw, 13px) clamp(9px, 1vw, 19px);
  }
  body.template-midnight-pearl .expiredRow span { opacity: 1 !important; }
  body.template-midnight-pearl .overflow-note {
    color: var(--muted);
    font-size: clamp(11px, .95vw, 18px);
    font-weight: 600;
    padding: clamp(6px, .7vw, 13px) 0 0;
    text-align: center;
  }
  /* measured-rise: slow enough to register at twenty feet, no overshoot. */
  body.template-midnight-pearl .colReady .ord.fresh {
    animation: spotlight-in .38s cubic-bezier(.22, .61, .36, 1);
  }
  @keyframes spotlight-in {
    from { opacity: 0; transform: translateY(9px); }
    to { opacity: 1; transform: none; }
  }

  /* Pickup Gallery: the far-view, low-count board. Warm paper, no panels at all — a slim production
     rail sits against a wide pickup gallery, divided by one full-height rule, and the clay ticket
     token is the only color in the composition. Pickup names run 2.3x the rail so a calm queue
     reads from across the room; a shop that regularly sits at 15+ orders belongs on Metro. */
  body.template-boba-pop.type-clean {
    font-family: var(--bq-font-stack);
  }
  body.template-boba-pop .hdr {
    background: var(--headerBg);
    border-bottom: 1px solid var(--border);
  }
  body.template-boba-pop .enso {
    background: transparent;
    border: 0;
    box-shadow: none;
    color: var(--textDark);
    overflow: visible;
    transform: none;
  }
  body.template-boba-pop .wordmark {
    color: var(--textDark);
    font-weight: 600;
    letter-spacing: -.015em;
  }
  body.template-boba-pop .hdrtag,
  body.template-boba-pop .clock {
    color: var(--muted);
    font-variant-numeric: tabular-nums;
    font-weight: 600;
  }
  body.template-boba-pop.header-classic .hdr {
    gap: clamp(11px, 1.1vw, 20px);
    min-height: clamp(56px, min(5vw, 8.9vh), 96px);
    padding: 0 clamp(22px, 2.4vw, 48px);
  }
  body.template-boba-pop.header-classic .enso {
    height: auto;
    width: auto;
    font-size: clamp(18px, 1.6vw, 30px);
  }
  body.template-boba-pop.header-classic .wordmark { font-size: clamp(20px, 1.9vw, 36px); }
  body.template-boba-pop.header-classic .hdrtag {
    border: 0;
    font-size: clamp(9px, .78vw, 14px);
    letter-spacing: .14em;
    padding: 0;
  }
  body.template-boba-pop.header-classic .clock { font-size: clamp(13px, 1.1vw, 21px); }
  body.template-boba-pop.density-comfortable .cols {
    gap: clamp(18px, 2.2vw, 44px);
    padding: clamp(15px, 1.8vw, 36px) clamp(22px, 2.4vw, 48px) clamp(18px, 2.1vw, 42px);
  }

  /* One continuous field: the only structure between the zones is a full-height rule. */
  body.template-boba-pop .col.colMaking {
    background: transparent;
    border: 0;
    border-radius: 0;
    border-right: 1px solid var(--readyBorder);
    box-shadow: none;
    flex: .58;
    gap: clamp(7px, .8vw, 15px);
    margin: 0;
    padding: 0 clamp(18px, 2.2vw, 44px) 0 0;
  }
  body.template-boba-pop .col.colReady {
    background: transparent;
    border: 0;
    border-radius: 0;
    box-shadow: none;
    flex: 1.42;
    gap: clamp(9px, 1vw, 18px);
    margin: 0;
    padding: 0;
  }
  body.template-boba-pop .col.colMaking .coltitle,
  body.template-boba-pop .col.colReady .coltitle {
    border-bottom: 1px solid var(--border);
    font-size: clamp(10px, .86vw, 16px);
    font-weight: 600;
    letter-spacing: .13em;
    margin-bottom: 0;
    padding-bottom: clamp(7px, .8vw, 15px);
    text-transform: uppercase;
  }
  body.template-boba-pop .col.colMaking .coltitle { color: var(--muted); }
  body.template-boba-pop .col.colReady .coltitle { color: var(--readyTitle); }

  /* The rail: production stays legible but subordinate. Its tracks divide the field at half
     the gallery's rhythm, so the two zones stay in proportion at any order count. */
  body.template-boba-pop .col.colMaking .list {
    align-content: stretch;
    display: grid;
    flex: 1;
    gap: 0;
    grid-auto-rows: minmax(clamp(28px, min(2.9vw, 5.6vh), 56px), 1fr);
  }
  body.template-boba-pop .col.colMaking .list:has(> .ord:first-child:nth-last-child(-n+3)) {
    align-content: start;
    grid-auto-rows: minmax(0, clamp(56px, 9.5vh, 124px));
  }
  body.template-boba-pop .col.colMaking .list .ord {
    background: transparent;
    border: 0;
    border-bottom: 1px solid var(--border);
    border-radius: 0;
    box-shadow: none;
    font-size: clamp(14px, 1.25vw, 24px);
    font-weight: 400;
    gap: clamp(8px, .9vw, 17px);
    margin: 0;
    min-height: 0;
    padding: clamp(5px, .6vw, 11px) 0;
  }
  /* The gallery is a two-column grid, so "last child" is one column's last row, not the
     board's — the rule stays on every gallery row or the two columns end unevenly. */
  body.template-boba-pop .col.colMaking .list .ord:last-child { border-bottom: 0; }
  /* ticket-token: a typographic token leading the row, not a filled chip. */
  body.template-boba-pop .col.colMaking .list .num,
  body.template-boba-pop .col.colReady .list .num {
    background: transparent;
    border-radius: 0;
    color: var(--accent);
    display: block;
    font-variant-numeric: tabular-nums;
    font-weight: 600;
    letter-spacing: .04em;
    margin: 0;
    min-height: 0;
    min-width: 2.4em;
    order: -1;
    padding: 0;
  }
  body.template-boba-pop .col.colMaking .list .num { font-size: max(12px, .72em); }
  body.template-boba-pop .col.colMaking .list .src {
    color: var(--muted);
    font-size: clamp(9px, .74vw, 13px);
    font-weight: 600;
    letter-spacing: .06em;
  }
  body.template-boba-pop .col.colMaking .list .eta {
    background: transparent;
    border: 0;
    border-radius: 0;
    color: var(--waitText);
    font-size: max(11px, .62em);
    font-variant-numeric: tabular-nums;
    font-weight: 400;
    padding: 0;
  }

  /* The gallery: pickup names at room scale. auto-fit keeps one name full width and pairs up at
     two or more; 1fr rows distribute the names down the whole field, so four orders fill the
     board instead of clustering at the top over dead space. */
  body.template-boba-pop .col.colReady .list {
    display: grid;
    flex: 1;
    gap: 0 clamp(18px, 2vw, 40px);
    grid-auto-rows: minmax(clamp(50px, 4.4vw, 86px), 1fr);
    grid-template-columns: repeat(auto-fit, minmax(min(100%, 44%), 1fr));
  }
  body.template-boba-pop .col.colReady .list .ord {
    background: transparent;
    border: 0;
    border-bottom: 1px solid var(--readyBorder);
    border-radius: 0;
    box-shadow: none;
    color: var(--readyText);
    font-size: clamp(26px, min(2.9vw, 7.6vh), 58px);
    font-weight: 600;
    gap: clamp(9px, 1vw, 19px);
    letter-spacing: -.02em;
    margin: 0;
    min-height: clamp(50px, 4.4vw, 86px);
    padding: clamp(6px, .7vw, 13px) 0;
  }
  body.template-boba-pop .col.colReady .list .num { font-size: max(13px, .34em); }
  /* Quiet service is this template's home, so the gallery scales up rather than sitting still. */
  body.template-boba-pop .col.colReady .list .ord:first-child:nth-last-child(-n+3),
  body.template-boba-pop .col.colReady .list .ord:first-child:nth-last-child(-n+3) ~ .ord {
    font-size: clamp(30px, min(3.5vw, 9.2vh), 74px);
  }
  body.template-boba-pop .ready-mark,
  body.template-boba-pop .col.colReady .list .src { display: none; }

  body.template-boba-pop #makingList:empty::after,
  body.template-boba-pop #readyList:empty::after {
    color: var(--muted);
    display: block;
    font-size: clamp(13px, 1.15vw, 22px);
    font-weight: 400;
    padding-top: clamp(9px, 1vw, 18px);
  }
  body.template-boba-pop #makingList:empty::after { content: "Nothing in preparation"; }
  body.template-boba-pop #readyList:empty::after { content: "Ready orders appear here"; }

  body.template-boba-pop .expiredRow {
    background: transparent;
    border: 0;
    border-top: 1px solid var(--readyBorder);
    border-radius: 0;
    color: var(--muted);
    font-size: clamp(12px, 1.05vw, 20px);
    font-weight: 400;
    padding: clamp(7px, .8vw, 15px) 0;
  }
  body.template-boba-pop .expiredRow span { opacity: 1 !important; }
  body.template-boba-pop .overflow-note {
    color: var(--muted);
    font-size: clamp(11px, 1vw, 19px);
    font-weight: 600;
    padding: clamp(7px, .8vw, 15px) 0 0;
    text-align: left;
  }
  /* measured-rise, a touch slower than Pearl's so the two never read as the same board. */
  body.template-boba-pop .colReady .ord.fresh {
    animation: studio-in .44s cubic-bezier(.25, .6, .3, 1);
  }
  @keyframes studio-in {
    from { opacity: 0; transform: translateY(10px); }
    to { opacity: 1; transform: none; }
  }

  /* Pickup Wall: the countertop face. One status, one wall — Ready names at the largest type in the
     product, in two columns divided by a single hairline and nothing else. There is no production
     column at all, which is both the whole proposition and the whole caveat.
     Portrait is a first-class target here, not a fallback: on a rotated panel `vw` is the SHORT
     axis, so the wall drops to one column and re-bases its type on the long axis in the media query
     below. Row tracks are capped at 1.5x the type in the same units and the group is centred, so
     the type-to-track ratio holds near 67% at any order count instead of stranding small names in
     tall 1fr rows. Geometry rides .col.colReady / .list so no later owner-control block can reach
     it, and weights stay 600/700 because a Pi falling back to DejaVu Sans has no 500. */
  body.template-pickup-wall.type-clean {
    font-family: var(--bq-font-stack);
  }
  /* The chrome is a caption strip: this board spends its height on names. */
  body.template-pickup-wall .hdr {
    background: var(--headerBg);
    border-bottom: 1px solid var(--border);
  }
  body.template-pickup-wall .enso { border: 0; border-radius: 0; overflow: visible; }
  body.template-pickup-wall.header-compact .hdr {
    gap: clamp(9px, .9vw, 16px);
    min-height: clamp(42px, min(3.1vw, 5.4vh), 62px);
    padding: 0 clamp(18px, 2vw, 40px);
  }
  body.template-pickup-wall.header-compact .enso {
    height: auto;
    width: auto;
    font-size: clamp(15px, 1.2vw, 22px);
  }
  body.template-pickup-wall.header-compact .wordmark {
    color: var(--textDark);
    font-size: clamp(16px, 1.3vw, 25px);
    font-weight: 600;
    letter-spacing: -.012em;
  }
  body.template-pickup-wall .hdrtag,
  body.template-pickup-wall .clock {
    color: var(--muted);
    font-variant-numeric: tabular-nums;
    font-weight: 600;
  }
  body.template-pickup-wall.header-compact .hdrtag {
    font-size: clamp(9px, .7vw, 13px);
    letter-spacing: .18em;
  }
  body.template-pickup-wall.header-compact .clock { font-size: clamp(12px, 1vw, 19px); }
  /* Making is not hidden on a Making screen — a screen rendering nothing is worse than one
     rendering the half it was pointed at — but in every other mode it does not exist. */
  body.template-pickup-wall:not(.display-making) .col.colMaking { display: none !important; }
  /* Spanning both tracks and flexing to 1 is what makes this layout-proof: whatever grid or flex
     arrangement layoutStyle and density leave behind, the wall takes the whole frame instead of
     82% of a flex row or 65% of a two-track grid with an empty second row. */
  body.template-pickup-wall:not(.display-making) .col.colReady {
    flex: 1;
    grid-column: 1 / -1;
    grid-row: 1 / -1;
  }
  body.template-pickup-wall.density-comfortable .cols,
  body.template-pickup-wall.density-compact .cols {
    gap: 0;
    padding: clamp(10px, 1.4vh, 22px) clamp(16px, 1.8vw, 40px) clamp(12px, 1.6vh, 26px);
  }
  body.template-pickup-wall .col.colReady {
    background: var(--readyBg);
    border: 0;
    border-radius: 0;
    box-shadow: none;
    gap: 0;
    padding: 0;
  }
  body.template-pickup-wall .col.colReady .coltitle {
    color: var(--readyTitle);
    font-size: clamp(11px, min(.9vw, 1.9vh), 18px);
    font-weight: 700;
    letter-spacing: .22em;
    margin-bottom: 0;
    padding-bottom: clamp(6px, .9vh, 15px);
    text-align: center;
  }
  /* auto-fit keeps one name full width and pairs up at two; the 460px floor is what drops a
     portrait panel to a single column before the media query is even consulted. */
  body.template-pickup-wall .col.colReady .list {
    align-content: center;
    display: grid;
    flex: 1;
    gap: 0 clamp(20px, 2.6vw, 56px);
    grid-auto-rows: minmax(0, clamp(46px, min(9.3vw, 18vh), 285px));
    grid-template-columns: repeat(auto-fit, minmax(min(100%, max(45%, 460px)), 1fr));
    grid-template-rows: none;
  }
  /* One centred hairline, drawn only when there is a second column for it to divide. */
  body.template-pickup-wall .col.colReady .list:has(> .ord:nth-child(2)) {
    background: linear-gradient(var(--border), var(--border)) center / 1px 100% no-repeat;
  }
  body.template-pickup-wall .col.colReady .list .ord {
    align-items: flex-start;
    background: transparent;
    border: 0;
    border-radius: 0;
    box-shadow: none;
    color: var(--readyText);
    display: flex;
    flex-direction: column;
    /* min(vw, vh) rather than a row-count step: eight names clipping at 1920x720 is an
       aspect-ratio failure, and a count rule cannot see the missing 360px of height. */
    font-size: clamp(30px, min(6.2vw, 12vh), 190px);
    font-weight: 600;
    gap: 0;
    justify-content: center;
    letter-spacing: -.03em;
    line-height: 1.04;
    min-height: 0;
    padding: 0 clamp(8px, 1vw, 22px);
  }
  body.template-pickup-wall .col.colReady .list .customer { width: 100%; }
  body.template-pickup-wall .col.colReady .list .num {
    color: var(--readyTitle);
    font-size: .23em;
    font-variant-numeric: tabular-nums;
    font-weight: 700;
    letter-spacing: .1em;
    margin: 0;
    order: -1;
  }
  body.template-pickup-wall .ready-mark,
  body.template-pickup-wall .col.colReady .list .src { display: none; }
  body.template-pickup-wall #readyList:empty::after {
    align-self: center;
    color: var(--muted);
    content: "All orders collected";
    display: block;
    font-size: clamp(16px, min(1.8vw, 3.8vh), 36px);
    font-weight: 600;
    text-align: center;
  }
  body.template-pickup-wall .overflow-note {
    color: var(--muted);
    font-size: clamp(13px, min(1.2vw, 2.6vh), 26px);
    font-weight: 600;
    padding: clamp(6px, .9vh, 14px) 0 0;
    text-align: center;
  }
  body.template-pickup-wall #expiredList {
    border-top: 1px solid var(--border);
    gap: 0;
    margin-top: clamp(8px, 1.2vh, 18px);
    padding-top: clamp(6px, .9vh, 14px);
  }
  body.template-pickup-wall #expiredList:empty {
    border-top: 0;
    margin-top: 0;
    padding-top: 0;
  }
  body.template-pickup-wall .expiredRow {
    background: transparent;
    border: 0;
    border-radius: 0;
    color: var(--muted);
    font-size: clamp(13px, min(1.2vw, 2.6vh), 26px);
    font-weight: 600;
    padding: clamp(3px, .4vh, 7px) 0;
    text-align: center;
  }
  /* renderBoard() inline-styles the expired order number at .6 opacity (~2.6:1). */
  body.template-pickup-wall .expiredRow span { opacity: 1 !important; }
  /* held-fade: no travel at all. A name this large moving is a distraction, not a cue. */
  body.template-pickup-wall .anim,
  body.template-pickup-wall .colReady .ord.fresh {
    animation: wall-in .4s cubic-bezier(.33, .66, .4, 1);
  }
  @keyframes wall-in {
    from { opacity: 0; }
    to { opacity: 1; }
  }

  /* Ticket Numbers: the board for shops that will not put customer names on a screen. The name is
     not hidden here — renderBoard never emits it, because a display:none .customer is still a
     customer's name in the DOM of a screen facing a room. Numbers are tokens on a dark field:
     outlined while making, filled when ready, so state is carried by weight of ink rather than by
     position alone. Tokens are capped and centred in 1fr tracks, which keeps a token the same size
     at three orders and at sixteen. border-radius is deliberately left to the shape-* layer — this
     is one of the two boards where the owner's card-shape control has something real to act on. */
  body.template-ticket-numbers.type-clean {
    font-family: var(--bq-font-stack);
  }
  body.template-ticket-numbers .hdr {
    background: var(--headerBg);
    border-bottom: 1px solid var(--border);
  }
  body.template-ticket-numbers .enso {
    background: transparent;
    border: 0;
    border-radius: 0;
    overflow: visible;
  }
  body.template-ticket-numbers.header-compact .hdr {
    gap: clamp(10px, 1vw, 18px);
    min-height: clamp(46px, min(3.4vw, 6.2vh), 68px);
    padding: 0 clamp(18px, 2vw, 40px);
  }
  body.template-ticket-numbers.header-compact .enso {
    height: auto;
    width: auto;
    font-size: clamp(16px, 1.3vw, 24px);
  }
  body.template-ticket-numbers.header-compact .wordmark {
    color: var(--textDark);
    font-size: clamp(17px, 1.4vw, 27px);
    font-weight: 600;
    letter-spacing: -.008em;
  }
  /* Utilities stay full textDark: muted on this ground measures under 4.5:1 at utility sizes, and
     an rgba dim would break the moment an owner republished headerBg light. */
  body.template-ticket-numbers .hdrtag,
  body.template-ticket-numbers .clock {
    color: var(--textDark);
    font-variant-numeric: tabular-nums;
    font-weight: 600;
  }
  body.template-ticket-numbers.header-compact .hdrtag {
    font-size: clamp(9px, .72vw, 13px);
    letter-spacing: .18em;
  }
  body.template-ticket-numbers.header-compact .clock { font-size: clamp(13px, 1.05vw, 20px); }
  body.template-ticket-numbers.density-compact .cols {
    gap: clamp(16px, 2vw, 44px);
    padding: clamp(12px, 1.4vw, 28px) clamp(18px, 2vw, 40px) clamp(14px, 1.6vw, 32px);
  }
  body.template-ticket-numbers .col.colMaking,
  body.template-ticket-numbers .col.colReady {
    background: transparent;
    border: 0;
    border-radius: 0;
    box-shadow: none;
    gap: clamp(8px, .9vw, 17px);
    padding: 0;
  }
  body.template-ticket-numbers .col.colMaking { flex: .78; }
  body.template-ticket-numbers .col.colReady { flex: 1.22; }
  body.template-ticket-numbers .col .coltitle {
    font-size: clamp(10px, .84vw, 15px);
    font-weight: 700;
    letter-spacing: .2em;
    margin-bottom: 0;
    padding-bottom: clamp(6px, .7vw, 13px);
  }
  body.template-ticket-numbers .col.colMaking .coltitle {
    border-bottom: 1px solid var(--border);
    color: var(--muted);
  }
  body.template-ticket-numbers .col.colReady .coltitle {
    border-bottom: 1px solid var(--readyBorder);
    color: var(--readyTitle);
  }
  /* The TRACK is capped and the group centred, so the tokens sit adjacent instead of drifting apart:
     at 1fr the three rows spread over 290px tracks and a 165px token floated in each. A ticket keeps
     ticket proportions — wide and short — whatever the count. */
  body.template-ticket-numbers .col .list {
    align-content: center;
    display: grid;
    flex: 1;
    gap: clamp(7px, .8vw, 15px);
    grid-auto-rows: minmax(0, clamp(78px, min(8.6vw, 19vh), 190px));
    grid-template-rows: none;
  }
  body.template-ticket-numbers .col.colMaking .list {
    grid-template-columns: repeat(auto-fit, minmax(min(100%, 46%), 1fr));
  }
  body.template-ticket-numbers .col.colReady .list {
    grid-template-columns: repeat(auto-fit, minmax(min(100%, 31%), 1fr));
  }
  body.template-ticket-numbers .col .list .ord {
    align-items: center;
    background: transparent;
    border: 2px solid var(--border);
    box-shadow: none;
    color: var(--text);
    display: flex;
    flex-direction: column;
    gap: clamp(2px, .3vw, 6px);
    justify-content: center;
    min-height: 0;
    padding: clamp(6px, .7vw, 13px);
  }
  /* Filled is ready. The fill is the token's own surface, so the outline disappears into it. */
  body.template-ticket-numbers .col.colReady .list .ord {
    background: var(--readyCard);
    border-color: var(--readyCard);
    color: var(--readyText);
  }
  body.template-ticket-numbers .col .list .num {
    color: inherit;
    font-size: clamp(26px, min(4vw, 9vh), 84px);
    font-variant-numeric: tabular-nums;
    font-weight: 700;
    letter-spacing: -.015em;
    line-height: 1;
    margin: 0;
  }
  body.template-ticket-numbers .col.colMaking .list .eta {
    background: transparent;
    border-radius: 0;
    color: var(--waitText);
    font-size: clamp(10px, .8vw, 15px);
    font-variant-numeric: tabular-nums;
    font-weight: 600;
    margin: 0;
    padding: 0;
  }
  body.template-ticket-numbers .ready-mark,
  body.template-ticket-numbers .col .list .src { display: none; }
  body.template-ticket-numbers #makingList:empty::after,
  body.template-ticket-numbers #readyList:empty::after {
    color: var(--muted);
    display: block;
    font-size: clamp(12px, 1.05vw, 20px);
    font-weight: 600;
    padding-top: clamp(8px, .9vw, 17px);
  }
  body.template-ticket-numbers #makingList:empty::after { content: "Nothing preparing"; }
  body.template-ticket-numbers #readyList:empty::after { content: "Nothing ready yet"; }
  body.template-ticket-numbers .expiredRow {
    background: transparent;
    border: 0;
    border-top: 1px solid var(--border);
    border-radius: 0;
    color: var(--muted);
    font-size: clamp(11px, 1vw, 19px);
    font-weight: 600;
    padding: clamp(6px, .7vw, 13px) 0;
  }
  body.template-ticket-numbers .expiredRow span { opacity: 1 !important; }
  body.template-ticket-numbers .overflow-note {
    color: var(--muted);
    font-size: clamp(11px, .95vw, 18px);
    font-weight: 600;
    letter-spacing: .04em;
    padding: clamp(6px, .7vw, 13px) 0 0;
    text-align: left;
  }
  /* state-fill: the token arrives already filled, so the motion is the fill settling. */
  body.template-ticket-numbers .anim,
  body.template-ticket-numbers .colReady .ord.fresh {
    animation: token-in .3s cubic-bezier(.22, .61, .36, 1);
  }
  @keyframes token-in {
    from { opacity: 0; transform: scale(.94); }
    to { opacity: 1; transform: none; }
  }

  /* Marquee: a call board, not a list. One ready name holds the stage and rotates every
     cfg.readyRotationSeconds; the rest of the queue is stated as a count, so the name on screen is
     unambiguously the one being called. renderBoard drops the Ready cap to 1 on this template,
     which is what makes "+N more ready" a true number rather than an overflow notice.
     The stage type is bound by WIDTH, not height: one line of a fifteen-character name at 11vw is
     already at the frame's limit, and going larger would truncate rather than fill. The ticket
     number carries the leftover height instead, and the production strip below stays deliberately
     small — it is context, not the message. */
  body.template-marquee.type-clean {
    font-family: var(--bq-font-stack);
  }
  body.template-marquee .hdr {
    background: var(--headerBg);
    border-bottom: 1px solid var(--border);
  }
  body.template-marquee .enso { border: 0; border-radius: 0; overflow: visible; }
  body.template-marquee.header-compact .hdr {
    gap: clamp(9px, .9vw, 16px);
    min-height: clamp(44px, min(3.2vw, 5.6vh), 64px);
    padding: 0 clamp(20px, 2.2vw, 44px);
  }
  body.template-marquee.header-compact .enso {
    height: auto;
    width: auto;
    font-size: clamp(15px, 1.2vw, 22px);
  }
  body.template-marquee.header-compact .wordmark {
    color: var(--textDark);
    font-size: clamp(16px, 1.35vw, 26px);
    font-weight: 600;
    letter-spacing: -.012em;
  }
  body.template-marquee .hdrtag,
  body.template-marquee .clock {
    color: var(--muted);
    font-variant-numeric: tabular-nums;
    font-weight: 600;
  }
  body.template-marquee.header-compact .hdrtag {
    font-size: clamp(9px, .7vw, 13px);
    letter-spacing: .18em;
  }
  body.template-marquee.header-compact .clock { font-size: clamp(12px, 1vw, 19px); }
  /* The stack is the template, not a layout preference, so it is pinned against every density and
     layout an owner can publish. Consequence: layoutStyle is inert on this board. */
  body.template-marquee.density-comfortable .cols,
  body.template-marquee.density-compact .cols {
    display: grid;
    gap: 0;
    grid-template-columns: minmax(0, 1fr);
    grid-template-rows: minmax(0, 1fr) min-content;
    padding: 0;
  }
  body.template-marquee .col.colReady {
    background: var(--readyBg);
    border: 0;
    border-radius: 0;
    box-shadow: none;
    gap: 0;
    order: 1;
    padding: clamp(10px, 1.6vh, 26px) clamp(20px, 2.2vw, 48px) clamp(10px, 1.6vh, 26px);
  }
  body.template-marquee .col.colReady .coltitle {
    color: var(--readyTitle);
    font-size: clamp(12px, min(1.1vw, 2.4vh), 22px);
    font-weight: 700;
    letter-spacing: .28em;
    margin-bottom: 0;
    text-align: center;
  }
  body.template-marquee .col.colReady .list {
    align-content: center;
    display: grid;
    flex: 1;
    gap: 0;
    grid-auto-rows: minmax(0, auto);
    grid-template-columns: minmax(0, 1fr);
    grid-template-rows: none;
  }
  body.template-marquee .col.colReady .list .ord {
    align-items: center;
    background: transparent;
    border: 0;
    border-radius: 0;
    box-shadow: none;
    color: var(--readyText);
    display: flex;
    flex-direction: column;
    gap: clamp(2px, .5vh, 10px);
    justify-content: center;
    min-height: 0;
    padding: 0;
    text-align: center;
  }
  body.template-marquee .col.colReady .list .customer {
    font-size: clamp(44px, min(11vw, 22vh), 300px);
    font-weight: 700;
    letter-spacing: -.035em;
    line-height: 1;
    width: 100%;
  }
  /* Absolute, not em: the stage sets its scale on .customer, so an em here would resolve against
     the untouched base .ord size and collapse to a caption. */
  body.template-marquee .col.colReady .list .num {
    color: var(--readyTitle);
    font-size: clamp(22px, min(4.4vw, 9vh), 110px);
    font-variant-numeric: tabular-nums;
    font-weight: 700;
    letter-spacing: .04em;
    line-height: 1;
    margin: 0;
    order: -1;
  }
  body.template-marquee .ready-mark,
  body.template-marquee .col.colReady .list .src { display: none; }
  /* The count is the rest of the queue, not a footnote about it. */
  body.template-marquee .col.colReady .overflow-note {
    color: var(--muted);
    font-size: clamp(14px, min(1.5vw, 3.2vh), 32px);
    font-weight: 600;
    letter-spacing: .02em;
    padding: clamp(6px, 1vh, 18px) 0 0;
    text-align: center;
  }
  body.template-marquee #readyList:empty::after {
    align-self: center;
    color: var(--muted);
    content: "Nothing ready yet";
    display: block;
    font-size: clamp(18px, min(2.2vw, 4.6vh), 44px);
    font-weight: 600;
    text-align: center;
  }
  /* The strip: a single row of small cells, hugging its own height. */
  body.template-marquee .col.colMaking {
    background: transparent;
    border: 0;
    border-radius: 0;
    border-top: 1px solid var(--border);
    gap: clamp(6px, .8vh, 12px);
    order: 2;
    padding: clamp(9px, 1.2vh, 20px) clamp(20px, 2.2vw, 48px) clamp(10px, 1.4vh, 22px);
  }
  body.template-marquee .col.colMaking .coltitle {
    color: var(--muted);
    font-size: clamp(9px, .76vw, 14px);
    font-weight: 600;
    letter-spacing: .2em;
    margin-bottom: 0;
  }
  /* Six cells across, not eight: at eight the cell is 210px and a fifteen-character display name
     ellipsises. A strip that truncates the name is worse than a strip that wraps to a second row,
     and at the volumes this template declares (calm/mixed) the second row rarely appears. */
  body.template-marquee .col.colMaking .list {
    display: grid;
    gap: clamp(6px, .7vw, 13px);
    grid-auto-rows: minmax(0, auto);
    grid-template-columns: repeat(auto-fit, minmax(min(100%, 14.5%), 1fr));
    grid-template-rows: none;
  }
  body.template-marquee .col.colMaking .list .ord {
    align-items: flex-start;
    background: var(--card);
    border: 1px solid var(--border);
    box-shadow: none;
    color: var(--text);
    display: flex;
    flex-direction: column;
    font-size: clamp(12px, min(1.3vw, 2.8vh), 26px);
    font-weight: 600;
    gap: 1px;
    letter-spacing: -.008em;
    min-height: 0;
    padding: clamp(5px, .6vw, 11px) clamp(7px, .8vw, 15px);
  }
  body.template-marquee .col.colMaking .list .num {
    color: var(--muted);
    font-size: .82em;
    font-variant-numeric: tabular-nums;
    font-weight: 700;
    order: -1;
  }
  body.template-marquee .col.colMaking .list .eta {
    background: transparent;
    border-radius: 0;
    color: var(--waitText);
    font-size: .78em;
    font-variant-numeric: tabular-nums;
    font-weight: 600;
    margin: 0;
    padding: 0;
  }
  body.template-marquee .col.colMaking .list .src { display: none; }
  body.template-marquee #makingList:empty::after {
    color: var(--muted);
    content: "Queue clear";
    display: block;
    font-size: clamp(11px, 1vw, 19px);
    font-weight: 600;
  }
  body.template-marquee .col.colMaking .overflow-note {
    color: var(--muted);
    font-size: clamp(10px, .9vw, 17px);
    font-weight: 600;
    padding: clamp(5px, .6vh, 10px) 0 0;
    text-align: left;
  }
  body.template-marquee #expiredList {
    border-top: 1px solid var(--border);
    gap: 0;
    margin-top: clamp(6px, .9vh, 14px);
    padding-top: clamp(5px, .8vh, 12px);
  }
  body.template-marquee #expiredList:empty {
    border-top: 0;
    margin-top: 0;
    padding-top: 0;
  }
  body.template-marquee .expiredRow {
    background: transparent;
    border: 0;
    border-radius: 0;
    color: var(--muted);
    font-size: clamp(12px, min(1.1vw, 2.4vh), 24px);
    font-weight: 600;
    padding: clamp(3px, .4vh, 6px) 0;
    text-align: center;
  }
  body.template-marquee .expiredRow span { opacity: 1 !important; }
  /* called-rise: the name is being announced, so it arrives from below and settles. */
  body.template-marquee .anim { animation: marquee-strip-in .26s cubic-bezier(.22, .61, .36, 1); }
  body.template-marquee .colReady .ord.fresh {
    animation: marquee-in .42s cubic-bezier(.2, .62, .3, 1);
  }
  @keyframes marquee-in {
    from { opacity: 0; transform: translateY(clamp(10px, 2vh, 26px)); }
    to { opacity: 1; transform: none; }
  }
  @keyframes marquee-strip-in {
    from { opacity: 0; transform: translateY(5px); }
    to { opacity: 1; transform: none; }
  }

  /* Card Grid: for shops that finish drinks in batches. Ready is a field of equal cells — same
     size, same weight, no ranking — because a batch has no first place; that is also the honest
     caveat, since nothing on the board shows which drink has waited longest. Making stays a plain
     queue list so the cards are the only surfaces in the composition.
     Tracks are 1fr, so the grid can never overflow whatever the count; each card is then capped and
     centred inside its track, which keeps a card card-sized instead of letting one lonely cell
     inflate to fill a column. Cards WRAP rather than truncate — a box can take a second line, and
     that is the one thing a card grammar can do that a row cannot. */
  body.template-card-grid.type-clean {
    font-family: var(--bq-font-stack);
  }
  body.template-card-grid .hdr {
    background: var(--headerBg);
    border-bottom: 1px solid var(--border);
  }
  body.template-card-grid .enso { border: 0; border-radius: 0; overflow: visible; }
  body.template-card-grid.header-classic .hdr {
    gap: clamp(11px, 1.1vw, 20px);
    min-height: clamp(58px, min(4.8vw, 8.4vh), 96px);
    padding: 0 clamp(20px, 2.2vw, 46px);
  }
  body.template-card-grid.header-classic .enso {
    height: auto;
    width: auto;
    font-size: clamp(19px, 1.6vw, 30px);
  }
  body.template-card-grid.header-classic .wordmark {
    color: var(--textDark);
    font-size: clamp(21px, 1.85vw, 36px);
    font-weight: 600;
    letter-spacing: -.016em;
  }
  body.template-card-grid .hdrtag,
  body.template-card-grid .clock {
    color: var(--muted);
    font-variant-numeric: tabular-nums;
    font-weight: 600;
  }
  body.template-card-grid.header-classic .hdrtag {
    font-size: clamp(9px, .76vw, 14px);
    letter-spacing: .16em;
  }
  body.template-card-grid.header-classic .clock { font-size: clamp(13px, 1.1vw, 21px); }
  body.template-card-grid.density-comfortable .cols {
    gap: clamp(16px, 1.9vw, 40px);
    padding: clamp(14px, 1.8vh, 30px) clamp(20px, 2.2vw, 46px) clamp(16px, 2vh, 34px);
  }
  body.template-card-grid .col.colMaking,
  body.template-card-grid .col.colReady {
    background: transparent;
    border: 0;
    border-radius: 0;
    box-shadow: none;
    padding: 0;
  }
  body.template-card-grid .col.colMaking { flex: .82; gap: clamp(7px, .8vw, 15px); }
  body.template-card-grid .col.colReady { flex: 1.18; gap: clamp(9px, 1vw, 18px); }
  body.template-card-grid .col .coltitle {
    border-bottom: 1px solid var(--border);
    font-size: clamp(11px, .88vw, 17px);
    font-weight: 700;
    letter-spacing: .18em;
    margin-bottom: 0;
    padding-bottom: clamp(7px, .8vw, 14px);
  }
  body.template-card-grid .col.colMaking .coltitle { color: var(--muted); }
  body.template-card-grid .col.colReady .coltitle { color: var(--readyTitle); }
  /* Making: a numbered queue on the bare ground — no rules, no cards, nothing that competes.
     Tracks are CAPPED and the list is top-aligned, not stretched: with nothing ruling the rows,
     1fr tracks measured a 27px name floating in a 146px band and the queue read as scattered
     rather than as a list. Air belongs at the foot of the column, not between the rows. */
  body.template-card-grid .col.colMaking .list {
    /* Centred, not start. The track is capped so rows keep their proportions at any count, which is
       right - but stacking a capped group at the top stranded the remainder as dead space: measured
       4-11% of the column used at one order and still only 32-80% at the eight-order cap, next to a
       Ready grid that was already centring itself. D47's rule for a capped track holding
       fixed-proportion items is exactly this, and it is what this template's own Ready column does. */
    align-content: center;
    display: grid;
    flex: 1;
    gap: 0;
    grid-auto-rows: minmax(0, clamp(34px, min(3.6vw, 7.4vh), 78px));
    grid-template-columns: minmax(0, 1fr);
    grid-template-rows: none;
  }
  body.template-card-grid .col.colMaking .list .ord {
    background: transparent;
    border: 0;
    border-radius: 0;
    box-shadow: none;
    color: var(--text);
    font-size: clamp(15px, min(1.4vw, 3.4vh), 28px);
    font-weight: 600;
    gap: clamp(8px, .9vw, 16px);
    letter-spacing: -.012em;
    line-height: 1.1;
    min-height: 0;
    padding: clamp(4px, .5vw, 9px) 0;
  }
  body.template-card-grid .col.colMaking .list .num {
    color: var(--muted);
    font-size: .74em;
    font-variant-numeric: tabular-nums;
    font-weight: 700;
    min-width: 2.6em;
    order: -1;
  }
  body.template-card-grid .col.colMaking .list .src {
    color: var(--muted);
    font-size: clamp(9px, .72vw, 13px);
    font-weight: 700;
    letter-spacing: .08em;
  }
  body.template-card-grid .col.colMaking .list .eta {
    background: transparent;
    border-radius: 0;
    color: var(--waitText);
    font-size: max(11px, .62em);
    font-variant-numeric: tabular-nums;
    font-weight: 600;
    padding: 0;
  }
  /* The cards. auto-fit with a px floor keeps a card a card: percentage-only tracks give three
     narrow cells on a 1280 panel and wrap every name onto three lines.
     The track is CAPPED and the group centred, and the card STRETCHES to its track. Both halves are
     load-bearing. Cards sized to their own content are not equal cells — a name that wraps to two
     lines grew its card 60px taller than the two beside it, which is the one thing this template
     promises not to do. And 1fr tracks with no cap turn three ready drinks into three cells 880px
     tall. The cap is bounded by 18vh, not by a row count, because the column count changes with
     width: 1280 gives two columns and therefore FOUR rows where 1920 gives three. */
  body.template-card-grid .col.colReady .list {
    align-content: center;
    display: grid;
    flex: 1;
    gap: clamp(9px, 1.1vw, 20px);
    grid-auto-rows: minmax(0, clamp(84px, min(13vw, 18vh), 260px));
    grid-template-columns: repeat(auto-fit, minmax(min(100%, max(29%, 250px)), 1fr));
    grid-template-rows: none;
  }
  /* A batch of three is this template's calm state, and one row can afford to be generous. */
  body.template-card-grid .col.colReady .list:has(> .ord:first-child:nth-last-child(-n+3)) {
    grid-auto-rows: minmax(0, clamp(110px, min(15vw, 30vh), 320px));
  }
  body.template-card-grid .col.colReady .list .ord {
    align-items: center;
    align-self: stretch;
    background: var(--readyCard);
    border: 1px solid var(--readyBorder);
    box-shadow: 0 1px 2px rgba(19, 23, 25, .05), 0 10px 26px rgba(19, 23, 25, .07);
    color: var(--readyText);
    display: flex;
    flex-direction: column;
    font-size: clamp(18px, min(2.6vw, 5.6vh), 52px);
    font-weight: 600;
    gap: clamp(3px, .5vh, 9px);
    justify-content: center;
    letter-spacing: -.02em;
    line-height: 1.06;
    min-height: 0;
    padding: clamp(10px, 1.3vw, 26px) clamp(9px, 1vw, 18px);
    text-align: center;
  }
  body.template-card-grid .col.colReady .list:has(> .ord:first-child:nth-last-child(-n+3)) .ord {
    font-size: clamp(20px, min(3vw, 6.6vh), 60px);
  }
  /* A card wraps. Truncating inside a box this size would be a choice, not a constraint. */
  body.template-card-grid .col.colReady .list .customer {
    overflow: visible;
    overflow-wrap: break-word;
    text-overflow: clip;
    white-space: normal;
    width: 100%;
  }
  body.template-card-grid .col.colReady .list .num {
    color: var(--readyTitle);
    font-size: .32em;
    font-variant-numeric: tabular-nums;
    font-weight: 700;
    letter-spacing: .1em;
    margin: 0;
    order: -1;
  }
  body.template-card-grid .ready-mark,
  body.template-card-grid .col.colReady .list .src { display: none; }
  body.template-card-grid #makingList:empty::after,
  body.template-card-grid #readyList:empty::after {
    color: var(--muted);
    display: block;
    font-size: clamp(13px, 1.15vw, 22px);
    font-weight: 600;
    padding-top: clamp(9px, 1vw, 18px);
  }
  body.template-card-grid #makingList:empty::after { content: "Nothing in progress"; }
  body.template-card-grid #readyList:empty::after { content: "Ready orders appear here"; }
  body.template-card-grid .expiredRow {
    background: transparent;
    border: 0;
    border-top: 1px solid var(--border);
    border-radius: 0;
    color: var(--muted);
    font-size: clamp(12px, 1.05vw, 20px);
    font-weight: 600;
    padding: clamp(6px, .7vw, 13px) 0;
  }
  body.template-card-grid .expiredRow span { opacity: 1 !important; }
  body.template-card-grid .overflow-note {
    color: var(--muted);
    font-size: clamp(11px, 1vw, 19px);
    font-weight: 600;
    padding: clamp(7px, .8vw, 14px) 0 0;
    text-align: left;
  }
  /* card-settle: a card lands, it does not slide in from anywhere. */
  body.template-card-grid .anim,
  body.template-card-grid .colReady .ord.fresh {
    animation: card-in .32s cubic-bezier(.22, .61, .36, 1);
  }
  @keyframes card-in {
    from { opacity: 0; transform: scale(.96); }
    to { opacity: 1; transform: none; }
  }

  /* Portrait Rail: the only template designed for a 9:16 mount. The two columns become two stacked
     bands of full-width rows — Ready above, Making below — so a rotated panel crops nothing. Each
     Ready row is a plate with an edge stripe, a component grammar no other board here uses.
     Landscape is a legible fallback rather than the target: the rows sit two-up by default, and
     drop to one column in the portrait media query below, where they also re-base their type on the
     LONG axis, because on a rotated panel `vw` is the short one. Row tracks are capped at 1.5x the
     type in the same units and centred, which is what turns leftover height into symmetric air
     instead of an all-but-empty board. */
  body.template-portrait-rail.type-clean {
    font-family: var(--bq-font-stack);
  }
  body.template-portrait-rail .hdr {
    background: var(--headerBg);
    border-bottom: 1px solid var(--border);
  }
  body.template-portrait-rail .enso { border: 0; border-radius: 0; overflow: visible; }
  body.template-portrait-rail.header-compact .hdr {
    gap: clamp(9px, 1vw, 16px);
    min-height: clamp(44px, min(4vw, 4.6vh), 74px);
    padding: 0 clamp(16px, 1.8vw, 36px);
  }
  body.template-portrait-rail.header-compact .enso {
    height: auto;
    width: auto;
    font-size: clamp(16px, min(1.7vw, 2vh), 30px);
  }
  body.template-portrait-rail.header-compact .wordmark {
    color: var(--textDark);
    font-size: clamp(17px, min(1.9vw, 2.2vh), 34px);
    font-weight: 600;
    letter-spacing: -.014em;
  }
  body.template-portrait-rail .hdrtag,
  body.template-portrait-rail .clock {
    color: var(--muted);
    font-variant-numeric: tabular-nums;
    font-weight: 600;
  }
  body.template-portrait-rail.header-compact .hdrtag {
    font-size: clamp(9px, min(.8vw, .95vh), 15px);
    letter-spacing: .16em;
  }
  body.template-portrait-rail.header-compact .clock {
    font-size: clamp(12px, min(1.2vw, 1.4vh), 22px);
  }
  /* Stacked is the template. Pinned against every density and layout, so layoutStyle is inert. */
  body.template-portrait-rail.density-comfortable .cols,
  body.template-portrait-rail.density-compact .cols {
    display: grid;
    gap: clamp(10px, 1.2vh, 22px);
    grid-template-columns: minmax(0, 1fr);
    grid-template-rows: minmax(0, 1.5fr) minmax(0, 1fr);
    padding: clamp(12px, 1.4vh, 24px) clamp(16px, 1.8vw, 36px) clamp(14px, 1.6vh, 28px);
  }
  body.template-portrait-rail .col.colReady {
    background: transparent;
    border: 0;
    border-radius: 0;
    box-shadow: none;
    gap: clamp(6px, .9vh, 14px);
    order: 1;
    padding: 0;
  }
  body.template-portrait-rail .col.colMaking {
    background: transparent;
    border: 0;
    border-radius: 0;
    border-top: 1px solid var(--border);
    gap: clamp(6px, .8vh, 12px);
    order: 2;
    padding: clamp(9px, 1.2vh, 20px) 0 0;
  }
  /* text-align is explicit because the layout layer centres a ready-spotlight column title, which
     would leave READY centred over rows that are flush left. */
  body.template-portrait-rail .col .coltitle {
    font-size: clamp(10px, min(1vw, 1.5vh), 18px);
    font-weight: 700;
    letter-spacing: .2em;
    margin-bottom: 0;
    text-align: left;
  }
  body.template-portrait-rail .col.colMaking .coltitle { color: var(--muted); }
  body.template-portrait-rail .col.colReady .coltitle { color: var(--readyTitle); }
  body.template-portrait-rail .col.colReady .list {
    align-content: center;
    display: grid;
    flex: 1;
    gap: clamp(5px, .7vh, 11px) clamp(9px, 1vw, 18px);
    grid-auto-rows: minmax(0, clamp(36px, min(7.5vw, 10.5vh), 195px));
    grid-template-columns: repeat(auto-fit, minmax(min(100%, 46%), 1fr));
    grid-template-rows: none;
  }
  body.template-portrait-rail .col.colReady .list .ord {
    align-items: center;
    background: var(--readyCard);
    border: 0;
    border-left: clamp(4px, .5vw, 10px) solid var(--readyBorder);
    border-radius: 0;
    box-shadow: none;
    color: var(--readyText);
    font-size: clamp(24px, min(5vw, 7vh), 130px);
    font-weight: 600;
    gap: clamp(8px, .9vw, 18px);
    letter-spacing: -.024em;
    line-height: 1.04;
    min-height: 0;
    padding: 0 clamp(10px, 1.1vw, 22px);
  }
  body.template-portrait-rail .col.colReady .list .num {
    color: var(--readyTitle);
    font-size: .38em;
    font-variant-numeric: tabular-nums;
    font-weight: 700;
    letter-spacing: .06em;
    margin-left: auto;
    order: 2;
  }
  body.template-portrait-rail .ready-mark,
  body.template-portrait-rail .col.colReady .list .src { display: none; }
  body.template-portrait-rail .col.colMaking .list {
    align-content: start;
    display: grid;
    gap: clamp(4px, .6vh, 9px) clamp(8px, 1vw, 18px);
    grid-auto-rows: minmax(0, clamp(28px, min(3.4vw, 4.8vh), 76px));
    grid-template-columns: repeat(auto-fit, minmax(min(100%, 23%), 1fr));
    grid-template-rows: none;
  }
  body.template-portrait-rail .col.colMaking .list .ord {
    background: transparent;
    border: 0;
    border-bottom: 1px solid var(--border);
    border-radius: 0;
    box-shadow: none;
    color: var(--text);
    font-size: clamp(13px, min(1.6vw, 2.4vh), 30px);
    font-weight: 600;
    gap: clamp(6px, .7vw, 13px);
    letter-spacing: -.01em;
    min-height: 0;
    padding: 0;
  }
  body.template-portrait-rail .col.colMaking .list .num {
    color: var(--muted);
    font-size: .78em;
    font-variant-numeric: tabular-nums;
    font-weight: 700;
    order: -1;
  }
  body.template-portrait-rail .col.colMaking .list .src { display: none; }
  body.template-portrait-rail .col.colMaking .list .eta {
    background: transparent;
    border-radius: 0;
    color: var(--waitText);
    font-size: max(11px, .68em);
    font-variant-numeric: tabular-nums;
    font-weight: 600;
    padding: 0;
  }
  body.template-portrait-rail #makingList:empty::after,
  body.template-portrait-rail #readyList:empty::after {
    color: var(--muted);
    display: block;
    font-size: clamp(13px, min(1.3vw, 1.9vh), 24px);
    font-weight: 600;
    padding-top: clamp(8px, 1vh, 16px);
  }
  body.template-portrait-rail #makingList:empty::after { content: "Nothing being made"; }
  body.template-portrait-rail #readyList:empty::after { content: "Ready orders appear here"; }
  body.template-portrait-rail .expiredRow {
    background: transparent;
    border: 0;
    border-top: 1px solid var(--readyBorder);
    border-radius: 0;
    color: var(--muted);
    font-size: clamp(12px, min(1.2vw, 1.8vh), 22px);
    font-weight: 600;
    padding: clamp(6px, .8vh, 12px) 0;
  }
  body.template-portrait-rail .expiredRow span { opacity: 1 !important; }
  body.template-portrait-rail .overflow-note {
    color: var(--muted);
    font-size: clamp(11px, min(1.1vw, 1.7vh), 20px);
    font-weight: 600;
    padding: clamp(6px, .8vh, 12px) 0 0;
    text-align: left;
  }
  /* row-slide: rows enter along the rail, which is the axis the whole board is built on. */
  body.template-portrait-rail .anim,
  body.template-portrait-rail .colReady .ord.fresh {
    animation: rail-in .3s cubic-bezier(.22, .61, .36, 1);
  }
  @keyframes rail-in {
    from { opacity: 0; transform: translateX(-10px); }
    to { opacity: 1; transform: none; }
  }

  /* Brand Band: the shop's name at sign scale is the first thing on the board and the band is the
     only colour on it. The band replaces the hairline header entirely, so the queue below carries
     no chrome of its own — two flat groups whose labels quote the band colour once, filled on Ready
     and outlined on Making. Band height is bounded on both axes: a sign that ate a 1920x720 mount
     would leave the queue nothing, which a vw-only rule cannot see. */
  body.template-brand-band.type-clean {
    font-family: var(--bq-font-stack);
  }
  body.template-brand-band .hdr {
    background: var(--headerBg);
    border-bottom: 0;
  }
  body.template-brand-band .enso {
    background: transparent;
    border: 0;
    border-radius: 0;
    color: var(--textDark);
    overflow: visible;
  }
  body.template-brand-band.header-centered .hdr {
    gap: clamp(10px, 1.2vw, 24px);
    min-height: clamp(80px, min(10vw, 16vh), 200px);
    padding: 0 clamp(88px, 8vw, 152px);
  }
  body.template-brand-band.header-centered .enso {
    height: auto;
    width: auto;
    font-size: clamp(26px, min(3.4vw, 5.6vh), 76px);
  }
  body.template-brand-band.header-centered .wordmark {
    color: var(--textDark);
    font-size: clamp(30px, min(4.4vw, 7vh), 104px);
    font-weight: 700;
    letter-spacing: -.028em;
  }
  /* Utilities stay full textDark for the same reason Metro's do: an rgba dim breaks the moment an
     owner republishes the band light, and size plus tracking already separates them. */
  body.template-brand-band .hdrtag,
  body.template-brand-band .clock {
    color: var(--textDark);
    font-variant-numeric: tabular-nums;
    font-weight: 600;
  }
  /* Pinned to the left edge opposite the clock, so the band reads as tag | sign | time. Left in the
     flow it butts against the wordmark and the shop's name stops looking like a sign. */
  body.template-brand-band.header-centered .hdrtag {
    font-size: clamp(9px, .76vw, 15px);
    left: clamp(20px, 2vw, 44px);
    letter-spacing: .2em;
    position: absolute;
  }
  body.template-brand-band.header-centered .clock {
    font-size: clamp(13px, 1.1vw, 22px);
    right: clamp(20px, 2vw, 44px);
  }
  body.template-brand-band.density-comfortable .cols {
    gap: clamp(20px, 2.4vw, 52px);
    padding: clamp(14px, 1.8vh, 30px) clamp(24px, 2.6vw, 56px) clamp(16px, 2vh, 34px);
  }
  body.template-brand-band .col.colMaking,
  body.template-brand-band .col.colReady {
    background: transparent;
    border: 0;
    border-radius: 0;
    box-shadow: none;
    flex: 1;
    gap: 0;
    padding: 0;
  }
  /* The label is a chip, and the only place the band colour appears again. */
  body.template-brand-band .col .coltitle {
    align-self: var(--heading-chip-align, flex-start);
    border-radius: 999px;
    font-size: clamp(10px, .84vw, 16px);
    font-weight: 700;
    letter-spacing: .18em;
    margin-bottom: 0;
    padding: clamp(5px, .6vh, 10px) clamp(11px, 1.1vw, 22px);
  }
  body.template-brand-band .col.colMaking .coltitle {
    border: 1px solid var(--border);
    color: var(--muted);
  }
  body.template-brand-band .col.colReady .coltitle {
    background: var(--readyTitle);
    color: var(--textDark);
  }
  body.template-brand-band .col .list {
    align-content: stretch;
    display: grid;
    flex: 1;
    gap: 0;
    grid-auto-rows: minmax(0, 1fr);
    grid-template-columns: minmax(0, 1fr);
    grid-template-rows: none;
    padding-top: clamp(8px, 1.1vh, 16px);
  }
  /* Quiet service: cap the tracks and centre, rather than stranding three rows under a sign. */
  body.template-brand-band .col.colMaking .list:has(> .ord:first-child:nth-last-child(-n+3)) {
    align-content: center;
    grid-auto-rows: minmax(0, clamp(60px, 10.5vh, 150px));
  }
  body.template-brand-band .col.colReady .list:has(> .ord:first-child:nth-last-child(-n+3)) {
    align-content: center;
    grid-auto-rows: minmax(0, clamp(80px, 14.5vh, 210px));
  }
  /* A quiet queue under a sign should not read as a caption: take the room the capped tracks free. */
  body.template-brand-band .col.colMaking .list:has(> .ord:first-child:nth-last-child(-n+3)) .ord {
    font-size: clamp(18px, min(2.2vw, 5.8vh), 44px);
  }
  body.template-brand-band .col.colReady .list:has(> .ord:first-child:nth-last-child(-n+3)) .ord {
    font-size: clamp(26px, min(3.4vw, 9vh), 76px);
  }
  body.template-brand-band .col .list .ord {
    align-items: center;
    background: transparent;
    border: 0;
    border-bottom: 1px solid var(--border);
    border-radius: 0;
    box-shadow: none;
    min-height: 0;
    padding: 0;
  }
  body.template-brand-band .col .list .ord:last-child { border-bottom: 0; }
  body.template-brand-band .col.colMaking .list .ord {
    color: var(--text);
    font-size: clamp(16px, min(1.7vw, 4.6vh), 34px);
    font-weight: 600;
    gap: clamp(8px, .8vw, 16px);
    letter-spacing: -.012em;
    line-height: 1.1;
  }
  body.template-brand-band .col.colReady .list .ord {
    border-bottom-color: var(--readyBorder);
    color: var(--readyText);
    font-size: clamp(22px, min(2.7vw, 7.2vh), 62px);
    font-weight: 700;
    gap: clamp(9px, .9vw, 18px);
    letter-spacing: -.026em;
    line-height: 1.05;
  }
  body.template-brand-band .col.colMaking .list .num {
    color: var(--muted);
    font-size: .68em;
    font-variant-numeric: tabular-nums;
    font-weight: 700;
  }
  body.template-brand-band .col.colReady .list .num {
    color: var(--readyTitle);
    font-size: .44em;
    font-variant-numeric: tabular-nums;
    font-weight: 700;
    margin-left: auto;
    order: 2;
  }
  body.template-brand-band .col .list .src {
    color: var(--muted);
    font-size: .34em;
    font-weight: 700;
    letter-spacing: .1em;
    text-transform: uppercase;
  }
  body.template-brand-band .col .list .eta {
    background: transparent;
    border-radius: 0;
    color: var(--waitText);
    font-size: .62em;
    font-variant-numeric: tabular-nums;
    font-weight: 600;
    padding: 0;
  }
  body.template-brand-band .ready-mark,
  body.template-brand-band .col.colReady .list .src { display: none; }
  body.template-brand-band #makingList:empty::after,
  body.template-brand-band #readyList:empty::after {
    color: var(--muted);
    display: block;
    font-size: clamp(13px, 1.15vw, 22px);
    font-weight: 600;
    padding-top: clamp(9px, 1.2vh, 18px);
  }
  body.template-brand-band #makingList:empty::after { content: "Nothing being made"; }
  body.template-brand-band #readyList:empty::after { content: "Ready orders appear here"; }
  body.template-brand-band #expiredList {
    border-top: 1px solid var(--border);
    gap: 0;
    margin-top: clamp(10px, 1.4vh, 20px);
    padding-top: clamp(8px, 1vh, 14px);
  }
  body.template-brand-band #expiredList:empty {
    border-top: 0;
    margin-top: 0;
    padding-top: 0;
  }
  body.template-brand-band .expiredRow {
    background: transparent;
    border: 0;
    border-radius: 0;
    color: var(--muted);
    font-size: clamp(13px, 1.1vw, 23px);
    font-weight: 600;
    padding: clamp(4px, .5vh, 8px) 0;
  }
  body.template-brand-band .expiredRow span { opacity: 1 !important; }
  body.template-brand-band .overflow-note {
    color: var(--muted);
    font-size: clamp(13px, 1.1vw, 23px);
    font-weight: 600;
    padding: clamp(9px, 1.1vh, 16px) 0 0;
    text-align: left;
  }
  /* band-fade: quiet, because the band is already doing the announcing. */
  body.template-brand-band .anim,
  body.template-brand-band .colReady .ord.fresh {
    animation: band-in .34s cubic-bezier(.22, .61, .36, 1);
  }
  @keyframes band-in {
    from { opacity: 0; transform: translateY(6px); }
    to { opacity: 1; transform: none; }
  }

  /*
   * Owner controls are the final desktop cascade layer. Templates keep their
   * composition and component grammar; these selectors own only the published
   * typography, card shape, density, and header geometry choices.
   */
  body.type-clean {
    font-family: "Avenir Next", var(--bq-font-stack);
  }
  body.type-rounded {
    font-family: "Pickup Lexend", var(--bq-font-stack);
  }
  body.type-editorial {
    font-family: "Pickup Fraunces", var(--bq-font-stack);
  }
  body.type-condensed {
    font-family: "Pickup IBM Plex Sans Condensed", var(--bq-font-stack);
  }
  body.type-modern {
    font-family: "Pickup Space Grotesk", var(--bq-font-stack);
  }
  body.type-hyperlegible {
    font-family: "Pickup Atkinson Hyperlegible Next", var(--bq-font-stack);
  }
  body.type-noto-sans {
    font-family: "Pickup Noto Sans", var(--bq-font-stack);
  }
  body.type-clean :is(.coltitle, .ord, .ord .num, .eta),
  body.type-rounded :is(.coltitle, .ord, .ord .num, .eta),
  body.type-editorial :is(.coltitle, .ord, .ord .num, .eta),
  body.type-condensed :is(.coltitle, .ord, .ord .num, .eta),
  body.type-modern :is(.coltitle, .ord, .ord .num, .eta),
  body.type-hyperlegible :is(.coltitle, .ord, .ord .num, .eta),
  body.type-noto-sans :is(.coltitle, .ord, .ord .num, .eta) {
    font-family: inherit;
  }

  body.shape-square .col .ord { border-radius: 2px; }
  body.shape-soft .col .ord { border-radius: 12px; }
  body.shape-round .col .ord { border-radius: 24px; }

  body.density-comfortable .cols { gap: 18px; padding: 18px 24px 24px; }
  body.density-comfortable .col { gap: 9px; }
  body.density-comfortable .list { gap: 9px; }
  body.density-comfortable .coltitle { margin-bottom: 4px; font-size: 15px; }
  body.density-comfortable .ord { min-height: 52px; padding-block: 10px; }
  body.density-comfortable .colReady .ord { min-height: 54px; }
  body.density-comfortable .eta { padding-block: 4px; }

  body.density-compact .cols { gap: 10px; padding: 10px 16px 16px; }
  body.density-compact .col { gap: 5px; padding-block: 10px; }
  body.density-compact .list { gap: 5px; }
  body.density-compact .coltitle { margin-bottom: 1px; font-size: 12px; }
  body.density-compact .ord {
    min-height: 0;
    gap: 7px;
    padding-block: 7px;
    font-size: clamp(15px, 1.35vw, 20px);
  }
  body.density-compact .colReady .ord {
    min-height: 0;
    font-size: clamp(17px, 1.5vw, 22px);
  }
  body.density-compact .eta { padding-block: 2px; font-size: 11px; }

  body.header-classic .hdr {
    position: static;
    justify-content: flex-start;
    gap: 14px;
    min-height: 72px;
    padding: 16px 28px;
  }
  body.header-classic .enso { width: 40px; height: 40px; }
  body.header-classic .hdrtag { margin-left: auto; }
  body.header-classic .clock { position: static; }
  body.header-compact .hdr {
    position: static;
    justify-content: flex-start;
    gap: 10px;
    min-height: 54px;
    padding: 9px 22px;
  }
  body.header-compact .enso { width: 32px; height: 32px; border-width: 2px; font-size: 15px; }
  body.header-compact .wordmark { font-size: 22px; }
  body.header-compact .hdrtag { margin-left: auto; font-size: 10px; }
  body.header-compact .clock { position: static; font-size: 15px; }
  body.header-centered .hdr {
    position: relative;
    justify-content: center;
    gap: 14px;
    min-height: 72px;
    padding: 16px 112px;
  }
  body.header-centered .hdrtag { margin-left: 0; }
  body.header-centered .clock { position: absolute; right: 28px; }

  /* Seven or eight visible orders switch to a TV-safe high-capacity rhythm. */
  .list:has(.ord:nth-child(7)) { gap: 5px; }
  .list:has(.ord:nth-child(7)) .ord {
    min-height: 0;
    padding-block: 6px;
  }
  /* Each template ships its own 7+ rhythm: the geometry above lands at (0,5,1) and outranks the
     shared rule, so without these eight rows would overflow a clipped column.
     `.display-full` is not decoration — a `:has()` rule of this shape computes to (0,8,1) and
     would otherwise outrank every split-TV rule below (which tops out at (0,6,1)), shrinking a
     dedicated Making or Ready TV to the shared-screen dense size. Density steps belong to the
     shared screen; a TV that owns one status has a whole screen and needs no step. */
  /* Metro's Making table needs no count step at all: its tracks already divide the column and
     its type is height-guarded, so a count rule could only shrink type where there is room. */
  body.template-matcha-modern.display-full .col.colReady .list:has(.ord:nth-child(7)) .ord {
    min-height: clamp(34px, min(3vw, 7.6vh), 58px);
    padding-block: clamp(4px, .45vw, 9px);
  }
  body.template-matcha-modern.display-full .col.colReady .list:has(.ord:nth-child(7)) .num {
    font-size: clamp(19px, min(1.7vw, 4.3vh), 32px);
  }
  body.template-matcha-modern.display-full .col.colReady .list:has(.ord:nth-child(7)) .customer {
    font-size: clamp(12px, .95vw, 17px);
  }
  /* Pearl's stage is already auto-fit with 1fr rows, so it absorbs 5-8 names by reflowing;
     only the name scale and the ticker need a dense step. */
  body.template-midnight-pearl.display-full .col.colReady .list:has(.ord:nth-child(5)) .customer {
    font-size: clamp(22px, min(2.4vw, 6.2vh), 46px);
  }
  body.template-midnight-pearl.display-full .col.colReady .list:has(.ord:nth-child(7)) .customer {
    font-size: clamp(19px, min(2vw, 5.2vh), 38px);
  }
  body.template-midnight-pearl.display-full .col.colReady .list:has(.ord:nth-child(7)) .num {
    font-size: clamp(11px, .9vw, 17px);
  }
  body.template-midnight-pearl.display-full .col.colMaking .list:has(.ord:nth-child(7)) .ord {
    font-size: clamp(13px, 1.15vw, 22px);
    min-height: clamp(30px, min(2.5vw, 5.8vh), 48px);
    padding-block: clamp(4px, .5vw, 10px);
  }
  /* queue-rail and balanced owners lose the stage grid, so the stage falls back to stacked rows. */
  body.template-midnight-pearl:not(.layout-ready-spotlight) .col.colReady .list .ord {
    align-items: center;
    flex-direction: row;
    justify-content: flex-start;
    text-align: left;
  }
  body.template-midnight-pearl:not(.layout-ready-spotlight) .col.colReady .list .customer {
    font-size: clamp(22px, min(2.2vw, 5.6vh), 42px);
    width: auto;
  }
  body.template-midnight-pearl:not(.layout-ready-spotlight) .col.colReady .list .num {
    margin-left: auto;
  }
  /* The gallery reflows to two columns before it shrinks; these steps only protect long names. */
  body.template-boba-pop.display-full .col.colMaking .list:has(.ord:nth-child(7)) .ord {
    font-size: clamp(13px, 1.1vw, 21px);
    min-height: clamp(28px, min(2.4vw, 5.6vh), 46px);
    padding-block: clamp(3px, .35vw, 7px);
  }
  body.template-boba-pop.display-full .col.colReady .list:has(.ord:nth-child(5)) .ord {
    font-size: clamp(21px, min(2.4vw, 6.2vh), 46px);
  }
  body.template-boba-pop.display-full .col.colReady .list:has(.ord:nth-child(7)) .ord {
    font-size: clamp(18px, min(2.1vw, 5.4vh), 40px);
  }

  @media (max-width: 760px), (max-aspect-ratio: 1/1) {
    .hdr { min-height: 58px; padding: 10px 14px; }
    .enso { width: 32px; height: 32px; border-width: 2px; font-size: 14px; }
    .wordmark { font-size: 20px; }
    .hdrtag { display: none; }
    .clock { margin-left: auto; font-size: 14px; }
    body.header-centered .hdr { justify-content: flex-start; padding-inline: 14px; }
    body.header-centered .clock { position: static; margin-left: auto; }
    .cols,
    body.layout-queue-rail .cols {
      display: grid;
      grid-template-columns: 1fr;
      grid-template-rows: minmax(0, 1fr) minmax(0, .8fr);
      gap: 8px;
      padding: 8px;
    }
    body.layout-ready-spotlight .cols {
      grid-template-rows: minmax(0, 1.25fr) minmax(0, .75fr);
      padding: 8px;
    }
    .col { padding: 9px; }
    .coltitle { font-size: 11px; }
    .ord { min-height: 0; padding: 6px 9px; font-size: clamp(13px, 3.4vw, 18px); }
    .eta { padding: 2px 6px; font-size: 10px; }
    body.layout-ready-spotlight .colReady .list {
      grid-template-columns: repeat(2, minmax(0, 1fr));
      grid-template-rows: repeat(4, minmax(0, 1fr));
    }
    body.layout-ready-spotlight .colMaking .list { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    body.template-bliss-light.header-classic .hdr { min-height: 58px; padding: 0 14px; }
    body.template-bliss-light .wordmark { font-size: 22px; }
    body.template-bliss-light .col { border-radius: 10px; }
    body.template-bliss-light .col.colMaking,
    body.template-bliss-light .col.colReady { padding: 10px 12px; }
    body.template-bliss-light .col .coltitle { padding-bottom: 7px; }
    /* a phone frame has no room to grow tracks — always stretch */
    body.template-bliss-light .col.colMaking .list:has(> .ord:first-child:nth-last-child(-n+3)),
    body.template-bliss-light .col.colReady .list:has(> .ord:first-child:nth-last-child(-n+3)) {
      align-content: stretch;
      grid-auto-rows: minmax(0, 1fr);
    }
    /* Same cascade arithmetic in the other direction: media queries add no specificity, so the
       (0,5,1) template geometry above out-ranks a plain rule here and a portrait TV, a phone
       preview and the Settings preview frame would all keep desktop row geometry. The paired
       `.display-full …:has()` selector on each rule restores portrait sizing at 7+ orders, where
       vw-based dense steps would otherwise land at ~17px on a 1080x1920 mount. */
    body.template-matcha-modern .col.colMaking .list .ord,
    body.template-matcha-modern .col.colMaking .list .ord:first-child:nth-last-child(-n+3),
    body.template-matcha-modern .col.colMaking .list .ord:first-child:nth-last-child(-n+3) ~ .ord {
      font-size: clamp(15px, 3.6vw, 22px);
      grid-template-columns: minmax(2.2em, auto) minmax(0, 1fr) minmax(3.4em, auto);
      min-height: 0;
      padding-block: 5px;
    }
    body.template-matcha-modern .col.colMaking .list,
    body.template-matcha-modern .col.colMaking .list:has(> .ord:first-child:nth-last-child(-n+3)),
    body.template-boba-pop .col.colMaking .list,
    body.template-boba-pop .col.colMaking .list:has(> .ord:first-child:nth-last-child(-n+3)) {
      align-content: start;
      grid-auto-rows: minmax(0, auto);
    }
    body.template-matcha-modern .col.colMaking .list .src { display: none; }
    body.template-matcha-modern .col.colMaking .list .eta { grid-column: 3; }
    body.template-matcha-modern.display-full .col.colReady .list:has(.ord:nth-child(7)) .ord,
    body.template-matcha-modern .col.colReady .list .ord { min-height: 0; padding-block: 6px; }
    body.template-matcha-modern.display-full .col.colReady .list:has(.ord:nth-child(7)) .num,
    body.template-matcha-modern .col.colReady .list .num { font-size: clamp(19px, 4.4vw, 28px); }
    body.template-matcha-modern.display-full .col.colReady .list:has(.ord:nth-child(7)) .customer,
    body.template-matcha-modern .col.colReady .list .customer { font-size: clamp(12px, 2.8vw, 16px); }
    body.template-midnight-pearl.display-full .col.colMaking .list:has(.ord:nth-child(7)) .ord,
    body.template-midnight-pearl .col.colMaking .list .ord {
      font-size: clamp(13px, 3.4vw, 18px);
      min-height: 0;
      padding: 7px 10px;
    }
    body.template-midnight-pearl.layout-ready-spotlight .col.colReady .list {
      grid-template-columns: repeat(auto-fit, minmax(min(100%, 46%), 1fr));
    }
    body.template-midnight-pearl.display-full .col.colReady .list:has(.ord:nth-child(5)) .customer,
    body.template-midnight-pearl.display-full .col.colReady .list:has(.ord:nth-child(7)) .customer,
    body.template-midnight-pearl:not(.layout-ready-spotlight) .col.colReady .list .customer,
    body.template-midnight-pearl .col.colReady .list .customer { font-size: clamp(20px, 5vw, 32px); }
    body.template-midnight-pearl.display-full .col.colReady .list:has(.ord:nth-child(7)) .num,
    body.template-midnight-pearl .col.colReady .list .num { font-size: clamp(11px, 2.6vw, 15px); }
    /* Portrait and phone stack the columns, so a border-right would rule down the middle of
       nothing — Studio's single divider turns horizontal. */
    body.template-boba-pop .col.colMaking {
      border-bottom: 1px solid var(--readyBorder);
      border-right: 0;
      padding-right: 10px;
    }
    body.template-boba-pop .col.colReady .list {
      grid-auto-rows: minmax(0, auto);
      grid-template-columns: minmax(0, 1fr);
    }
    body.template-boba-pop.display-full .col.colMaking .list:has(.ord:nth-child(7)) .ord,
    body.template-boba-pop .col.colMaking .list .ord {
      font-size: clamp(13px, 3.4vw, 18px);
      min-height: 0;
      padding-block: 5px;
    }
    body.template-boba-pop.display-full .col.colReady .list:has(.ord:nth-child(5)) .ord,
    body.template-boba-pop.display-full .col.colReady .list:has(.ord:nth-child(7)) .ord,
    body.template-boba-pop .col.colReady .list .ord:first-child:nth-last-child(-n+3),
    body.template-boba-pop .col.colReady .list .ord:first-child:nth-last-child(-n+3) ~ .ord,
    body.template-boba-pop .col.colReady .list .ord {
      font-size: clamp(19px, 5vw, 30px);
      min-height: 0;
      padding-block: 6px;
    }

    /* ---- the portrait-capable templates re-base their type on the LONG axis ----
       On a rotated panel `vw` is the SHORT side, so a landscape rule leaves type width-bound at
       roughly half its usable size while a thousand pixels of height go unspent. Each of these
       swaps the two coefficients and keeps the track at 1.5x the type in the SAME units, so the
       type-to-track ratio holds near 67% and nothing clips. */
    body.template-pickup-wall .cols { grid-template-rows: minmax(0, 1fr); }
    body.template-pickup-wall .col.colReady .list {
      gap: 0;
      grid-auto-rows: minmax(0, clamp(39px, min(15vw, 10.5vh), 285px));
      grid-template-columns: minmax(0, 1fr);
    }
    /* One column: there is nothing left to divide. */
    body.template-pickup-wall .col.colReady .list:has(> .ord:nth-child(2)) { background: none; }
    body.template-pickup-wall .col.colReady .list .ord {
      font-size: clamp(26px, min(10vw, 7vh), 190px);
      padding-inline: 0;
    }
    /* Ready leads on a portrait mount; the generic stack puts Making first at 1fr. */
    body.template-ticket-numbers .cols {
      grid-template-rows: minmax(0, .85fr) minmax(0, 1fr);
    }
    body.template-ticket-numbers .col.colMaking .list,
    body.template-ticket-numbers .col.colReady .list {
      grid-template-columns: repeat(auto-fit, minmax(min(100%, 46%), 1fr));
    }
    body.template-ticket-numbers .col .list {
      grid-auto-rows: minmax(0, clamp(64px, min(17vw, 11vh), 160px));
    }
    body.template-ticket-numbers .col .list .num {
      font-size: clamp(24px, min(8vw, 5.2vh), 72px);
    }

    /* The stage is WIDTH-bound, so a narrow panel simply calls a smaller name — that is why this
       template declares `orientation: 'landscape'`. Only the strip needs re-flowing. */
    body.template-marquee .col.colMaking .list {
      grid-template-columns: repeat(auto-fit, minmax(min(100%, 31%), 1fr));
    }

    body.template-card-grid .cols { grid-template-rows: minmax(0, .8fr) minmax(0, 1fr); }
    /* The landscape queue rule bottoms out on its 15px floor at 810 wide — a subordinate column is
       still meant to be read. Re-based on the long axis, track at 1.8x for a ruleless list. */
    body.template-card-grid .col.colMaking .list {
      grid-auto-rows: minmax(0, clamp(34px, min(5.4vw, 4vh), 90px));
    }
    body.template-card-grid .col.colMaking .list .ord {
      font-size: clamp(15px, min(3vw, 2.2vh), 34px);
    }
    body.template-card-grid .col.colReady .list {
      grid-template-columns: repeat(auto-fit, minmax(min(100%, 46%), 1fr));
    }
    body.template-card-grid .col.colReady .list {
      grid-auto-rows: minmax(0, clamp(76px, min(18vw, 13vh), 200px));
    }
    body.template-card-grid .col.colReady .list:has(> .ord:first-child:nth-last-child(-n+3)) {
      grid-auto-rows: minmax(0, clamp(96px, min(22vw, 17vh), 260px));
    }
    body.template-card-grid .col.colReady .list .ord,
    body.template-card-grid .col.colReady .list:has(> .ord:first-child:nth-last-child(-n+3)) .ord {
      font-size: clamp(16px, min(4.4vw, 3.8vh), 46px);
    }

    /* Portrait Rail's home. Making hugs its rows and Ready takes everything left, because a fixed
       1fr production band left 200px of dead space under a two-row queue. */
    body.template-portrait-rail.density-comfortable .cols,
    body.template-portrait-rail.density-compact .cols {
      grid-template-rows: minmax(0, 1fr) min-content;
    }
    body.template-portrait-rail .col.colReady .list {
      gap: clamp(4px, .5vh, 10px);
      grid-auto-rows: minmax(0, clamp(39px, min(14.1vw, 8.25vh), 240px));
      grid-template-columns: minmax(0, 1fr);
    }
    body.template-portrait-rail .col.colReady .list .ord {
      font-size: clamp(26px, min(9.4vw, 5.5vh), 160px);
    }
    body.template-portrait-rail .col.colMaking .list {
      grid-auto-rows: minmax(0, clamp(26px, min(6.4vw, 2.8vh), 66px));
      grid-template-columns: repeat(auto-fit, minmax(min(100%, 46%), 1fr));
    }
    body.template-portrait-rail .col.colMaking .list .ord {
      font-size: clamp(13px, min(3.1vw, 1.9vh), 30px);
    }

    /* A sign on a portrait mount can spend the width it has; 10vw would render a caption. */
    body.template-brand-band .cols { grid-template-rows: minmax(0, .85fr) minmax(0, 1fr); }
    body.template-brand-band.header-centered .hdr {
      min-height: clamp(70px, min(19vw, 12vh), 220px);
      padding: 0 clamp(14px, 3.4vw, 40px);
    }
    body.template-brand-band.header-centered .enso {
      font-size: clamp(22px, min(6.4vw, 4.2vh), 70px);
    }
    body.template-brand-band.header-centered .wordmark {
      font-size: clamp(26px, min(8.4vw, 5.4vh), 96px);
    }
    /* The quiet-step selectors below carry a `:has()` argument, which lifts them to (0,7,1) — a
       plain portrait rule at (0,5,1) loses to them however late it appears, so both counts are
       restated here or a three-order portrait board keeps landscape's 3.4vw type. */
    body.template-brand-band .col.colMaking .list:has(> .ord:first-child:nth-last-child(-n+3)) {
      grid-auto-rows: minmax(0, clamp(36px, min(5.1vw, 4vh), 100px));
    }
    body.template-brand-band .col.colReady .list:has(> .ord:first-child:nth-last-child(-n+3)) {
      grid-auto-rows: minmax(0, clamp(48px, min(7.4vw, 5.8vh), 130px));
    }
    body.template-brand-band .col.colMaking .list .ord,
    body.template-brand-band .col.colMaking .list:has(> .ord:first-child:nth-last-child(-n+3)) .ord {
      font-size: clamp(14px, min(3.2vw, 2.5vh), 34px);
    }
    body.template-brand-band .col.colReady .list .ord,
    body.template-brand-band .col.colReady .list:has(> .ord:first-child:nth-last-child(-n+3)) .ord {
      font-size: clamp(20px, min(4.6vw, 3.6vh), 62px);
    }
  }

  /* ---------------------------------------------------------------------------
   * Warm Counter — menu-leaders / leader-rows.
   *
   * The warm option. Its grammar is the printed cafe menu: a name on the left, the
   * thing you are waiting for on the right, and a dotted leader carrying your eye
   * across the gap. That leader is why this is a template and not a recolour — on a
   * wide screen a bare row makes you re-find your line halfway across, and every
   * other board solves that with a rule, a card edge or a column. This one solves it
   * the way a menu does.
   *
   * The leader is `.ord::before` with `order: 1`, so it lands between the name
   * (order 0) and the number (order 2) without the row builder emitting anything
   * extra — no template gets its own DOM.
   * ------------------------------------------------------------------------- */
  body.template-warm-counter.type-clean {
    font-family: var(--bq-font-stack);
  }

  body.template-warm-counter .hdr {
    background: var(--headerBg);
    border-bottom: 1px solid var(--border);
  }
  body.template-warm-counter.header-classic .hdr {
    gap: clamp(12px, 1vw, 20px);
    min-height: clamp(72px, 8.2vh, 106px);
    padding: 0 clamp(26px, 2.5vw, 50px);
  }
  body.template-warm-counter .hdr .enso {
    border: 0;
    border-radius: 0;
    font-size: clamp(24px, 2.1vw, 44px);
    overflow: visible;
  }
  body.template-warm-counter.header-classic .hdr .enso {
    height: clamp(32px, 2.6vw, 54px);
    width: clamp(32px, 2.6vw, 54px);
  }
  body.template-warm-counter .wordmark {
    color: var(--textDark);
    font-size: clamp(26px, 2.15vw, 46px);
    font-weight: 600;
    letter-spacing: -.018em;
  }
  body.template-warm-counter .hdrtag {
    color: var(--muted);
    font-size: clamp(11px, .8vw, 17px);
    font-weight: 600;
    letter-spacing: .18em;
  }
  body.template-warm-counter .clock {
    border-left: 1px solid var(--border);
    color: var(--text);
    font-size: clamp(15px, 1.1vw, 23px);
    font-weight: 600;
    padding-left: clamp(12px, 1vw, 20px);
  }

  /* Making sits open on the warm ground; Ready is the one panel, so the eye lands
     on it first from across a room. */
  body.template-warm-counter.density-comfortable .cols {
    gap: clamp(20px, 2.1vw, 42px);
    padding: clamp(16px, 2.2vh, 32px) clamp(24px, 2.6vw, 52px) clamp(18px, 2.6vh, 38px);
  }
  body.template-warm-counter.density-compact .cols {
    gap: clamp(12px, 1.4vw, 26px);
    padding: clamp(10px, 1.4vh, 20px) clamp(15px, 1.7vw, 32px) clamp(12px, 1.8vh, 24px);
  }
  body.template-warm-counter .col.colMaking {
    background: transparent;
    border: 0;
    box-shadow: none;
    flex: 1.05;
    gap: 0;
    padding: clamp(14px, 1.9vh, 26px) 0 clamp(8px, 1vh, 16px);
  }
  body.template-warm-counter .col.colReady {
    background: var(--readyBg);
    border: 0;
    border-radius: clamp(14px, 1.2vw, 26px);
    box-shadow: 0 1px 2px rgba(46, 38, 34, .05), 0 16px 40px rgba(46, 38, 34, .09);
    flex: 1;
    gap: 0;
    padding: clamp(18px, 2.3vh, 32px) clamp(22px, 2vw, 40px) clamp(12px, 1.6vh, 22px);
  }

  body.template-warm-counter .col .coltitle {
    letter-spacing: .17em;
    line-height: 1.2;
    margin: 0;
    padding-bottom: clamp(10px, 1.3vh, 18px);
    text-transform: uppercase;
  }
  body.template-warm-counter .col.colMaking .coltitle {
    color: var(--muted);
    font-size: clamp(13px, 1.02vw, 21px);
    font-weight: 600;
  }
  body.template-warm-counter .col.colReady .coltitle {
    color: var(--readyTitle);
    font-size: clamp(15px, 1.18vw, 25px);
    font-weight: 700;
  }

  body.template-warm-counter .col .list {
    align-content: stretch;
    display: grid;
    flex: 1;
    gap: 0;
    grid-auto-rows: minmax(0, 1fr);
    padding-top: clamp(6px, .8vh, 14px);
  }
  /* Quiet service: cap the tracks and centre them rather than stranding three rows
     at the top. Browsers without :has() keep stretching — the safe failure. */
  body.template-warm-counter .col.colMaking .list:has(> .ord:first-child:nth-last-child(-n+3)) {
    align-content: center;
    grid-auto-rows: minmax(0, clamp(84px, 14vh, 190px));
  }
  body.template-warm-counter .col.colReady .list:has(> .ord:first-child:nth-last-child(-n+3)) {
    align-content: center;
    grid-auto-rows: minmax(0, clamp(104px, 19vh, 260px));
  }

  /* The leader row. No rule under the row — the dots ARE the horizontal structure. */
  body.template-warm-counter .col .ord {
    align-items: center;
    background: transparent;
    border: 0;
    border-radius: 0;
    gap: 0;
    min-height: 0;
    padding: 0;
  }
  /* The leader rides the text baseline, not the bottom of the track. The track is a 1fr
     grid row and is far taller than the type, so anything bottom-aligned lands in the gap
     between rows and reads as a divider — the opposite of what a leader is for. Centred
     plus a baseline-sized nudge keeps it on the line through every clamp step. */
  /* Drawn from --muted rather than --border so it follows an owner's palette instead of a
     literal. --border is the hairline tone and lands at 1.35:1 here, which disappears at TV
     distance; --muted at .75 gives 3.13:1, clearing the 3:1 floor for a graphic that
     carries meaning. Opacity is on the element, which holds no text. */
  body.template-warm-counter .col .ord::before {
    border-bottom: 2px dotted var(--muted);
    content: "";
    flex: 1 1 auto;
    margin: .38em clamp(8px, .7vw, 16px) 0;
    min-width: clamp(16px, 2vw, 48px);
    opacity: .75;
    order: 1;
  }
  body.template-warm-counter .col .customer { flex: 0 1 auto; min-width: 0; }
  body.template-warm-counter .col .num { order: 2; }
  body.template-warm-counter .col .src { order: 3; }
  body.template-warm-counter .col .eta { order: 4; }

  body.template-warm-counter .col.colMaking .ord {
    color: var(--text);
    /* vh term guards a wide-and-short panel, where a row-count rule cannot. */
    font-size: clamp(18px, min(2vw, 6.8vh), 48px);
    font-weight: 600;
    letter-spacing: -.014em;
    line-height: 1.1;
  }
  body.template-warm-counter .col.colMaking .ord:first-child:nth-last-child(-n+3),
  body.template-warm-counter .col.colMaking .ord:first-child:nth-last-child(-n+3) ~ .ord {
    font-size: clamp(21px, 2.55vw, 62px);
  }
  body.template-warm-counter .col.colMaking .num {
    color: var(--muted);
    font-size: .58em;
    font-variant-numeric: tabular-nums;
    font-weight: 600;
  }
  body.template-warm-counter .col .src {
    color: var(--muted);
    font-size: .32em;
    font-weight: 700;
    letter-spacing: .1em;
    margin-left: .6em;
    text-transform: uppercase;
  }
  body.template-warm-counter .col .eta {
    background: transparent;
    border-radius: 0;
    color: var(--waitText);
    font-size: .6em;
    font-variant-numeric: tabular-nums;
    font-weight: 600;
    margin-left: .7em;
    padding: 0;
  }

  body.template-warm-counter .col.colReady .ord {
    color: var(--readyText);
    font-size: clamp(24px, min(3.55vw, 7.2vh), 88px);
    font-weight: 600;
    letter-spacing: -.026em;
    line-height: 1.02;
  }
  body.template-warm-counter .col.colReady .ord:first-child:nth-last-child(-n+3),
  body.template-warm-counter .col.colReady .ord:first-child:nth-last-child(-n+3) ~ .ord {
    font-size: clamp(28px, 4.4vw, 108px);
  }
  /* Ready leaders are drawn in the accent, so the collect side reads as one object.
     .8 over readyBg measures 3.54:1 — the collect screen is the one read from furthest. */
  body.template-warm-counter .col.colReady .ord::before {
    border-bottom-color: var(--readyBorder);
    opacity: .8;
  }
  body.template-warm-counter .col.colReady .num {
    color: var(--readyTitle);
    font-size: .46em;
    font-variant-numeric: tabular-nums;
    font-weight: 600;
  }
  body.template-warm-counter .col.colReady .src,
  body.template-warm-counter .col.colReady .ready-mark { display: none; }

  body.template-warm-counter .overflow-note {
    color: var(--muted);
    font-size: clamp(14px, 1.12vw, 24px);
    font-weight: 600;
    padding: clamp(10px, 1.2vh, 18px) 0 0;
    text-align: left;
  }
  body.template-warm-counter #expiredList {
    border-top: 1px solid var(--border);
    gap: 0;
    margin-top: clamp(10px, 1.4vh, 20px);
    padding-top: clamp(8px, 1vh, 14px);
  }
  body.template-warm-counter #expiredList:empty {
    border-top: 0;
    margin-top: 0;
    padding-top: 0;
  }
  body.template-warm-counter .expiredRow {
    background: transparent;
    border: 0;
    border-radius: 0;
    color: var(--muted);
    font-size: clamp(14px, 1.12vw, 24px);
    font-weight: 600;
    padding: clamp(4px, .5vh, 8px) 0;
  }
  /* renderBoard() inline-styles the expired order number at .6 opacity (~2.6:1). */
  body.template-warm-counter .expiredRow span { opacity: 1 !important; }

  body.template-warm-counter .anim,
  body.template-warm-counter .colReady .ord.fresh {
    animation: warm-counter-in .36s cubic-bezier(.22, .61, .36, 1);
  }
  @keyframes warm-counter-in {
    from { opacity: 0; transform: translateY(6px); }
    to { opacity: 1; transform: none; }
  }

  /* Brand Sidebar: the shop identity is a permanent, full-height sign rather than a logo squeezed
     into a shared header. The queue stays deliberately calm beside it: one ruled production list
     and one open pickup field. The fixed rail is the template, so generic layout and card-shape
     controls are scoped out by BBThemes instead of pretending to move these rows. */
  body.template-brand-sidebar {
    display: grid;
    grid-template-columns: clamp(230px, 25vw, 460px) minmax(0, 1fr);
    grid-template-rows: minmax(0, 1fr);
  }
  body.template-brand-sidebar.type-clean {
    font-family: var(--bq-font-stack);
  }
  body.template-brand-sidebar .hdr {
    align-items: flex-start;
    background: var(--headerBg);
    border: 0;
    color: var(--textDark);
    flex-direction: column;
    gap: clamp(14px, 2.2vh, 30px);
    grid-column: 1;
    grid-row: 1;
    height: 100%;
    justify-content: flex-start;
    min-height: 0;
    padding: clamp(28px, 4vh, 64px) clamp(24px, 2.6vw, 50px);
  }
  body.template-brand-sidebar .enso {
    align-items: center;
    background: transparent;
    border: 2px solid var(--textDark);
    border-radius: clamp(12px, 1.2vw, 22px);
    color: var(--textDark);
    display: flex;
    font-size: clamp(54px, min(6.2vw, 11vh), 118px);
    height: clamp(82px, min(9vw, 16vh), 168px);
    justify-content: center;
    overflow: hidden;
    width: clamp(82px, min(9vw, 16vh), 168px);
  }
  body.template-brand-sidebar .wordmark {
    color: var(--textDark);
    font-size: clamp(32px, min(3.6vw, 6.4vh), 72px);
    font-weight: 700;
    letter-spacing: -.035em;
    line-height: .98;
    max-width: 100%;
    overflow: visible;
    overflow-wrap: anywhere;
    text-overflow: clip;
    white-space: normal;
  }
  body.template-brand-sidebar .hdrtag {
    color: var(--textDark);
    font-size: clamp(10px, .82vw, 16px);
    font-weight: 600;
    letter-spacing: .18em;
    margin: auto 0 0;
    opacity: .82;
  }
  body.template-brand-sidebar .clock {
    border-top: 1px solid var(--textDark);
    color: var(--textDark);
    font-size: clamp(15px, 1.25vw, 24px);
    font-variant-numeric: tabular-nums;
    font-weight: 600;
    padding-top: clamp(12px, 1.8vh, 24px);
    width: 100%;
  }
  body.template-brand-sidebar .cols {
    display: grid;
    gap: clamp(18px, 2vw, 38px);
    grid-column: 2;
    grid-row: 1;
    grid-template-columns: minmax(0, .86fr) minmax(0, 1.14fr);
    height: 100%;
    min-width: 0;
    padding: clamp(22px, 3vh, 46px) clamp(24px, 2.8vw, 54px);
  }
  body.template-brand-sidebar .col.colMaking,
  body.template-brand-sidebar .col.colReady {
    border: 0;
    border-radius: 0;
    box-shadow: none;
    gap: 0;
    min-width: 0;
    padding: 0;
  }
  body.template-brand-sidebar .col.colMaking { background: transparent; }
  body.template-brand-sidebar .col.colReady {
    background: var(--readyBg);
    border-left: clamp(5px, .45vw, 9px) solid var(--accent);
    padding: clamp(18px, 2.3vh, 34px) clamp(20px, 2vw, 38px);
  }
  body.template-brand-sidebar .col .coltitle {
    font-size: clamp(11px, .9vw, 17px);
    font-weight: 700;
    letter-spacing: .16em;
    margin: 0;
    padding-bottom: clamp(10px, 1.4vh, 20px);
  }
  body.template-brand-sidebar .col.colMaking .coltitle { color: var(--muted); }
  body.template-brand-sidebar .col.colReady .coltitle { color: var(--readyTitle); }
  body.template-brand-sidebar .col .list {
    align-content: stretch;
    display: grid;
    flex: 1;
    gap: 0;
    grid-auto-rows: minmax(0, 1fr);
  }
  body.template-brand-sidebar .col.colMaking .list:has(> .ord:first-child:nth-last-child(-n+3)),
  body.template-brand-sidebar .col.colReady .list:has(> .ord:first-child:nth-last-child(-n+3)) {
    align-content: center;
    grid-auto-rows: minmax(0, clamp(76px, 13vh, 172px));
  }
  body.template-brand-sidebar .col .list .ord {
    background: transparent;
    border: 0;
    border-bottom: 1px solid var(--border);
    border-radius: 0;
    box-shadow: none;
    min-height: 0;
    padding: clamp(6px, .8vh, 12px) 0;
  }
  body.template-brand-sidebar .col .list .ord:last-child { border-bottom: 0; }
  body.template-brand-sidebar .col.colMaking .list .ord {
    color: var(--text);
    font-size: clamp(18px, min(1.8vw, 5.2vh), 38px);
    font-weight: 600;
    gap: clamp(7px, .7vw, 14px);
    letter-spacing: -.015em;
  }
  body.template-brand-sidebar .col.colReady .list .ord {
    border-bottom-color: var(--readyBorder);
    color: var(--readyText);
    font-size: clamp(24px, min(2.7vw, 7.4vh), 58px);
    font-weight: 700;
    gap: clamp(8px, .8vw, 16px);
    letter-spacing: -.026em;
  }
  body.template-brand-sidebar .col .list:has(> .ord:nth-child(7)) .ord {
    font-size: clamp(16px, min(1.55vw, 4.2vh), 32px);
    padding-block: clamp(3px, .45vh, 7px);
  }
  body.template-brand-sidebar .col.colReady .list:has(> .ord:nth-child(7)) .ord {
    font-size: clamp(21px, min(2.25vw, 5.8vh), 48px);
  }
  body.template-brand-sidebar .col.colMaking .num,
  body.template-brand-sidebar .col.colReady .num {
    color: var(--muted);
    font-size: .48em;
    font-variant-numeric: tabular-nums;
    font-weight: 700;
  }
  body.template-brand-sidebar .col.colReady .num {
    color: var(--readyTitle);
    margin-left: auto;
    order: 2;
  }
  body.template-brand-sidebar .col .src {
    color: var(--muted);
    font-size: .34em;
    font-weight: 700;
    letter-spacing: .08em;
  }
  body.template-brand-sidebar .col .eta {
    background: var(--waitBg);
    color: var(--waitText);
    font-size: .54em;
    font-weight: 600;
  }
  body.template-brand-sidebar .ready-mark,
  body.template-brand-sidebar .col.colReady .src { display: none; }
  body.template-brand-sidebar #makingList:empty::after,
  body.template-brand-sidebar #readyList:empty::after {
    color: var(--muted);
    display: block;
    font-size: clamp(13px, 1.1vw, 21px);
    font-weight: 600;
    padding-top: clamp(10px, 1.3vh, 18px);
  }
  body.template-brand-sidebar #makingList:empty::after { content: "Nothing in progress"; }
  body.template-brand-sidebar #readyList:empty::after { content: "Ready orders appear here"; }
  body.template-brand-sidebar #expiredList {
    border-top: 1px solid var(--readyBorder);
    gap: 0;
    margin-top: clamp(8px, 1vh, 16px);
    padding-top: clamp(6px, .8vh, 12px);
  }
  body.template-brand-sidebar #expiredList:empty { border: 0; margin: 0; padding: 0; }
  body.template-brand-sidebar .expiredRow,
  body.template-brand-sidebar .overflow-note {
    background: transparent;
    border: 0;
    color: var(--muted);
    font-size: clamp(11px, .92vw, 18px);
    font-weight: 600;
    padding: clamp(4px, .5vh, 8px) 0;
    text-align: left;
  }
  body.template-brand-sidebar .expiredRow span { opacity: 1 !important; }
  body.template-brand-sidebar .anim,
  body.template-brand-sidebar .colReady .ord.fresh {
    animation: brand-sidebar-in .32s cubic-bezier(.22, .61, .36, 1);
  }
  @keyframes brand-sidebar-in {
    from { opacity: 0; transform: translateX(10px); }
    to { opacity: 1; transform: none; }
  }

  /* Brand Corner: identity occupies one deliberate corner of the composition instead of a strip.
     Production continues beneath that sign while Ready owns the entire adjacent field, giving a
     rush-length pickup list room without demoting the shop's mark. */
  body.template-brand-corner {
    border: clamp(7px, .7vw, 14px) solid var(--accent);
    display: grid;
    grid-template-columns: minmax(280px, 33vw) minmax(0, 1fr);
    grid-template-rows: minmax(170px, 34vh) minmax(0, 1fr);
  }
  body.template-brand-corner.type-clean {
    font-family: var(--bq-font-stack);
  }
  body.template-brand-corner .hdr {
    align-items: flex-start;
    background: var(--headerBg);
    border: 0;
    color: var(--textDark);
    flex-direction: column;
    gap: clamp(8px, 1.2vh, 18px);
    grid-column: 1;
    grid-row: 1;
    justify-content: center;
    min-height: 0;
    padding: clamp(20px, 3vh, 42px) clamp(22px, 2.3vw, 44px);
    position: relative;
  }
  body.template-brand-corner .enso {
    background: transparent;
    border: 0;
    border-radius: 0;
    color: var(--textDark);
    font-size: clamp(40px, min(4.8vw, 8.5vh), 92px);
    height: auto;
    overflow: visible;
    width: auto;
  }
  body.template-brand-corner .wordmark {
    color: var(--textDark);
    font-size: clamp(28px, min(3.3vw, 5.8vh), 66px);
    font-weight: 700;
    letter-spacing: -.032em;
    line-height: 1;
    max-width: 100%;
    overflow: visible;
    overflow-wrap: anywhere;
    text-overflow: clip;
    white-space: normal;
  }
  body.template-brand-corner .hdrtag {
    color: var(--textDark);
    font-size: clamp(9px, .72vw, 14px);
    font-weight: 600;
    letter-spacing: .17em;
    margin: 0;
    opacity: .8;
  }
  body.template-brand-corner .clock {
    color: var(--textDark);
    font-size: clamp(13px, 1vw, 20px);
    font-variant-numeric: tabular-nums;
    font-weight: 600;
    position: absolute;
    right: clamp(14px, 1.5vw, 28px);
    top: clamp(14px, 1.8vh, 26px);
  }
  body.template-brand-corner.display-full .cols { display: contents; }
  body.template-brand-corner .col.colMaking {
    background: var(--bg);
    border: 0;
    border-radius: 0;
    box-shadow: none;
    gap: 0;
    grid-column: 1;
    grid-row: 2;
    padding: clamp(18px, 2.5vh, 34px) clamp(20px, 2.2vw, 40px);
  }
  body.template-brand-corner .col.colReady {
    background: var(--readyBg);
    border: 0;
    border-left: 1px solid var(--border);
    border-radius: 0;
    box-shadow: none;
    gap: 0;
    grid-column: 2;
    grid-row: 1 / span 2;
    padding: clamp(22px, 3vh, 46px) clamp(24px, 2.8vw, 54px);
  }
  body.template-brand-corner .col .coltitle {
    font-size: clamp(11px, .92vw, 18px);
    font-weight: 700;
    letter-spacing: .16em;
    margin: 0;
    padding-bottom: clamp(10px, 1.3vh, 18px);
  }
  body.template-brand-corner .col.colMaking .coltitle { color: var(--muted); }
  body.template-brand-corner .col.colReady .coltitle {
    color: var(--readyTitle);
    font-size: clamp(13px, 1.05vw, 21px);
  }
  body.template-brand-corner .col .list {
    align-content: stretch;
    display: grid;
    flex: 1;
    gap: 0;
    grid-auto-rows: minmax(0, 1fr);
  }
  body.template-brand-corner .col.colReady .list {
    gap: clamp(10px, 1.1vw, 22px);
    grid-auto-rows: minmax(0, 1fr);
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
  body.template-brand-corner .col .list .ord {
    border-radius: 0;
    box-shadow: none;
    min-height: 0;
  }
  body.template-brand-corner .col.colMaking .list .ord {
    background: transparent;
    border: 0;
    border-bottom: 1px solid var(--border);
    color: var(--text);
    font-size: clamp(16px, min(1.55vw, 4.4vh), 32px);
    font-weight: 600;
    gap: clamp(6px, .6vw, 12px);
    padding: clamp(5px, .65vh, 10px) 0;
  }
  body.template-brand-corner .col.colMaking .list .ord:last-child { border-bottom: 0; }
  body.template-brand-corner .col.colReady .list .ord {
    align-items: flex-start;
    background: var(--readyCard);
    border: 2px solid var(--readyBorder);
    color: var(--readyText);
    flex-direction: column;
    font-size: clamp(24px, min(3.1vw, 6.8vh), 64px);
    font-weight: 700;
    gap: clamp(5px, .7vh, 10px);
    justify-content: center;
    letter-spacing: -.03em;
    padding: clamp(14px, 1.8vh, 28px) clamp(16px, 1.5vw, 30px);
  }
  body.template-brand-corner .col.colMaking .list:has(> .ord:nth-child(7)) .ord {
    font-size: clamp(14px, min(1.35vw, 3.6vh), 27px);
    padding-block: clamp(3px, .4vh, 6px);
  }
  body.template-brand-corner .col.colReady .list:has(> .ord:nth-child(7)) .ord {
    font-size: clamp(21px, min(2.6vw, 5.2vh), 52px);
    padding: clamp(10px, 1.2vh, 18px) clamp(13px, 1.2vw, 24px);
  }
  body.template-brand-corner .col .num {
    color: var(--muted);
    font-size: .45em;
    font-variant-numeric: tabular-nums;
    font-weight: 700;
    order: -1;
  }
  body.template-brand-corner .col.colReady .num {
    color: var(--readyTitle);
    font-size: .4em;
    letter-spacing: .06em;
  }
  body.template-brand-corner .col .src {
    color: var(--muted);
    font-size: .32em;
    font-weight: 700;
    letter-spacing: .08em;
  }
  body.template-brand-corner .col .eta {
    background: var(--waitBg);
    color: var(--waitText);
    font-size: .52em;
    font-weight: 600;
  }
  body.template-brand-corner .ready-mark,
  body.template-brand-corner .col.colReady .src { display: none; }
  body.template-brand-corner #makingList:empty::after,
  body.template-brand-corner #readyList:empty::after {
    color: var(--muted);
    display: block;
    font-size: clamp(13px, 1.05vw, 21px);
    font-weight: 600;
    padding-top: clamp(10px, 1.3vh, 18px);
  }
  body.template-brand-corner #makingList:empty::after { content: "Nothing in progress"; }
  body.template-brand-corner #readyList:empty::after { content: "Ready orders appear here"; }
  body.template-brand-corner #expiredList {
    border-top: 1px solid var(--border);
    gap: 0;
    margin-top: clamp(8px, 1vh, 16px);
    padding-top: clamp(6px, .8vh, 12px);
  }
  body.template-brand-corner #expiredList:empty { border: 0; margin: 0; padding: 0; }
  body.template-brand-corner .expiredRow,
  body.template-brand-corner .overflow-note {
    background: transparent;
    border: 0;
    color: var(--muted);
    font-size: clamp(11px, .92vw, 18px);
    font-weight: 600;
    padding: clamp(4px, .5vh, 8px) 0;
    text-align: left;
  }
  body.template-brand-corner .expiredRow span { opacity: 1 !important; }
  body.template-brand-corner .anim,
  body.template-brand-corner .colReady .ord.fresh {
    animation: brand-corner-in .3s cubic-bezier(.22, .61, .36, 1);
  }
  @keyframes brand-corner-in {
    from { opacity: 0; transform: translateX(10px); }
    to { opacity: 1; transform: none; }
  }

  /* These are wide-screen templates. The portrait fallback preserves a readable board for an
     accidental phone or rotated display, while the capability contract keeps the picker honest
     and does not recommend either composition for that fixture. */
  @media (max-aspect-ratio: 1/1) {
    body.template-brand-sidebar.display-full,
    body.template-brand-corner.display-full {
      border-width: 0;
      display: flex;
      flex-direction: column;
    }
    body.template-brand-sidebar.display-full .hdr,
    body.template-brand-corner.display-full .hdr {
      align-items: center;
      flex-direction: row;
      gap: clamp(8px, 2vw, 16px);
      height: auto;
      min-height: clamp(64px, 10vh, 96px);
      padding: clamp(10px, 1.5vh, 18px) clamp(14px, 4vw, 24px);
    }
    body.template-brand-sidebar.display-full .enso,
    body.template-brand-corner.display-full .enso {
      flex: none;
      font-size: clamp(24px, 7vw, 42px);
      height: clamp(44px, 10vw, 62px);
      width: clamp(44px, 10vw, 62px);
    }
    body.template-brand-sidebar.display-full .wordmark,
    body.template-brand-corner.display-full .wordmark {
      flex: 1 1 auto;
      font-size: clamp(20px, 5.5vw, 34px);
      line-height: 1;
      min-width: 0;
      overflow: hidden;
      text-overflow: ellipsis;
      white-space: nowrap;
    }
    body.template-brand-sidebar.display-full .hdrtag,
    body.template-brand-corner.display-full .hdrtag { display: none; }
    body.template-brand-sidebar.display-full .clock,
    body.template-brand-corner.display-full .clock {
      border: 0;
      flex: none;
      padding: 0;
      position: static;
      width: auto;
    }
    body.template-brand-sidebar.display-full .cols,
    body.template-brand-corner.display-full .cols {
      display: grid;
      flex: 1;
      gap: clamp(10px, 1.5vh, 18px);
      grid-template-columns: minmax(0, 1fr);
      grid-template-rows: minmax(0, .82fr) minmax(0, 1.18fr);
      height: auto;
      padding: clamp(10px, 1.6vh, 18px) clamp(12px, 3vw, 22px);
    }
    body.template-brand-sidebar.display-full .col.colMaking,
    body.template-brand-sidebar.display-full .col.colReady,
    body.template-brand-corner.display-full .col.colMaking,
    body.template-brand-corner.display-full .col.colReady {
      border: 0;
      grid-column: 1;
      min-height: 0;
      padding: clamp(12px, 1.6vh, 20px);
    }
    body.template-brand-sidebar.display-full .col.colMaking,
    body.template-brand-corner.display-full .col.colMaking { grid-row: 1; }
    body.template-brand-sidebar.display-full .col.colReady,
    body.template-brand-corner.display-full .col.colReady { grid-row: 2; }
    body.template-brand-corner.display-full .col.colReady .list {
      grid-template-columns: repeat(2, minmax(0, 1fr));
    }
  }

  /*
   * A paired TV can own one side of the queue. The active status becomes a
   * complete composition; this intentionally comes after the responsive and
   * owner-control layers so every template keeps its own single-screen grammar.
   */
  body.display-making .colReady,
  body.display-ready .colMaking {
    display: none !important;
  }
  body.display-making .cols,
  body.display-ready .cols {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    grid-template-rows: minmax(0, 1fr);
  }
  body.display-making .colMaking,
  body.display-ready .colReady {
    width: 100%;
    height: 100%;
    margin: 0;
    max-width: none;
  }
  body.display-making .coltitle,
  body.display-ready .coltitle {
    font-size: clamp(15px, 1.5vw, 22px);
  }

  /* Brand Corner's full-board wrapper disappears into the body grid. On a paired TV it becomes a
     real one-cell grid beside the sign, so the active status owns all of the remaining screen. */
  body.template-brand-corner.display-making,
  body.template-brand-corner.display-ready {
    grid-template-columns: clamp(250px, 29vw, 520px) minmax(0, 1fr);
    grid-template-rows: minmax(0, 1fr);
  }
  body.template-brand-corner.display-making .hdr,
  body.template-brand-corner.display-ready .hdr {
    grid-column: 1;
    grid-row: 1;
    height: 100%;
  }
  body.template-brand-corner.display-making .cols,
  body.template-brand-corner.display-ready .cols {
    grid-column: 2;
    grid-row: 1;
    height: 100%;
    padding: clamp(22px, 3vh, 46px) clamp(24px, 2.8vw, 54px);
  }
  body.template-brand-corner.display-making .col.colMaking,
  body.template-brand-corner.display-ready .col.colReady {
    border: 0;
    grid-column: 1;
    grid-row: 1;
    padding: 0;
  }
  body.template-brand-corner.display-making .col.colMaking .list {
    align-content: center;
    grid-auto-rows: minmax(0, clamp(72px, 12vh, 170px));
  }
  body.template-brand-corner.display-making .col.colMaking .list .ord {
    font-size: clamp(24px, min(3vw, 7vh), 64px);
  }
  body.template-brand-corner.display-ready .col.colReady .list {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
  body.template-brand-corner.display-ready .col.colReady .list .ord {
    font-size: clamp(30px, min(4vw, 9vh), 86px);
  }

  /* Clean: a full-width production ledger or a spacious pickup-callout wall. The
     compound .col selectors are load-bearing — a later density-compact block would
     otherwise out-order these on equal specificity and shrink the names. */
  body.template-bliss-light.display-making .col.colMaking {
    padding: clamp(18px, 3vh, 32px) clamp(24px, 5vw, 72px) clamp(12px, 1.6vh, 22px);
  }
  body.template-bliss-light.display-making .col.colMaking .ord:first-child:nth-last-child(-n+3),
  body.template-bliss-light.display-making .col.colMaking .ord:first-child:nth-last-child(-n+3) ~ .ord {
    font-size: clamp(28px, 3.4vw, 82px);
  }
  body.template-bliss-light.display-making .col.colMaking .ord:first-child:nth-last-child(n+4),
  body.template-bliss-light.display-making .col.colMaking .ord:first-child:nth-last-child(n+4) ~ .ord {
    font-size: clamp(22px, 2.6vw, 62px);
  }
  body.template-bliss-light.display-ready .col.colReady {
    padding: clamp(20px, 4vh, 42px) clamp(24px, 4vw, 60px) clamp(14px, 2vh, 26px);
  }
  body.template-bliss-light.display-ready .col.colReady .list {
    column-gap: clamp(20px, 3vw, 56px);
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
  /* Ready-only runs a 2-column grid, so 7 and 8 orders both make 4 rows — a row-count rule
     shrinks type exactly where there is most room. Height guard instead of a count step. */
  /* A Ready-only screen is the pickup wall: it owns the whole display and has no Making column to
     share with, so inheriting the full board's 3.55vw left 29-37% of each row as text and the rest
     as air — on the one screen whose only job is being read across a room. The vh term keeps a
     wide-and-short panel from clipping; the 190px ceiling is inert above ~2570px wide, where the
     vw term binds anyway. */
  body.template-bliss-light.display-ready .col.colReady .ord {
    font-size: clamp(28px, min(6.8vw, 13vh), 190px);
  }
  /* Track = 1.5x the type above, expressed the same way so the ratio holds on every panel, then
     centre what's left. Without this a portrait iPad — the pickup-counter case — starves: `vw` is
     its SHORT axis, so type is width-bound at ~55px while 1080px of height goes unused, giving 12%
     fill. Type cannot simply grow, because a long name would then overflow the narrow axis. Capping
     the track and centring turns that leftover height into symmetric air at a steady ~66% fill. */
  body.template-bliss-light.display-ready .col.colReady .list {
    align-content: center;
    grid-auto-rows: minmax(0, clamp(70px, min(10.2vw, 19.5vh), 285px));
  }
  body.template-bliss-light.display-ready #expiredList {
    display: grid;
    gap: 0 clamp(16px, 2vw, 32px);
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  /* Warm Counter stays ONE column here where the others split to two. A leader has to
     cross a real distance to do its job; halve the width and it degrades into a dash
     between two words. One column also gives the pickup wall the widest possible name,
     which is the only thing that screen is for. Same track-cap-and-centre treatment as
     the full board, so a portrait iPad fills instead of stranding rows at the top. */
  body.template-warm-counter.display-ready .col.colReady {
    padding: clamp(20px, 4vh, 42px) clamp(26px, 4.2vw, 64px) clamp(14px, 2vh, 26px);
  }
  body.template-warm-counter.display-ready .col.colReady .ord {
    font-size: clamp(28px, min(6.4vw, 12.4vh), 180px);
  }
  body.template-warm-counter.display-ready .col.colReady .list {
    align-content: center;
    grid-auto-rows: minmax(0, clamp(70px, min(10.2vw, 19.5vh), 285px));
    grid-template-columns: minmax(0, 1fr);
  }
  /* One column means the row count, not the column count, buys the vertical room — and the
     track is a minmax(0, ...) so it compresses silently while the type does not. At eight
     ready orders on a 1080p wall that left 123px type in a 112px track and the names touched.
     Only the vh term steps down: on a portrait iPad the vw term binds and there is no
     crowding to fix, so tightening vh there would shrink a screen that was already correct.
     Browsers without :has() keep the base size — the same safe failure as the quiet rules. */
  /* The quiet-service rule on the full board carries two extra pseudo-classes, so at three
     or fewer orders it outranked the pickup size and the wall rendered 84px type where 123px
     was intended — the screen furthest from the customer showing the smallest names. Restate
     it under .display-ready to win on specificity rather than on source order. */
  body.template-warm-counter.display-ready .col.colReady .ord:first-child:nth-last-child(-n+3),
  body.template-warm-counter.display-ready .col.colReady .ord:first-child:nth-last-child(-n+3) ~ .ord {
    font-size: clamp(28px, min(6.4vw, 12.4vh), 180px);
  }
  body.template-warm-counter.display-ready .col.colReady .list:has(> .ord:nth-child(4)) .ord {
    font-size: clamp(26px, min(6.4vw, 11vh), 150px);
  }
  body.template-warm-counter.display-ready .col.colReady .list:has(> .ord:nth-child(6)) .ord {
    font-size: clamp(24px, min(6.4vw, 8vh), 120px);
  }

  /* Metro: keep the scan-first table full width; pickup becomes a gate grid. */
  body.template-matcha-modern.display-making .col.colMaking {
    padding: clamp(12px, 2.5vh, 24px) clamp(18px, 3vw, 42px);
  }
  body.template-matcha-modern.display-making .col.colMaking .list .ord {
    font-size: clamp(22px, min(2.1vw, 5.6vh), 40px);
    grid-template-columns: minmax(3em, auto) minmax(0, 1fr) auto minmax(4em, auto);
    min-height: clamp(48px, 7.5vh, 76px);
  }
  body.template-matcha-modern.display-ready .col.colReady {
    align-self: stretch;
    padding: clamp(14px, 2.5vh, 26px) clamp(18px, 3vw, 42px);
  }
  body.template-matcha-modern.display-ready .col.colReady .list {
    display: grid;
    flex: 1;
    gap: 0;
    grid-auto-rows: minmax(0, 1fr);
    grid-template-columns: repeat(auto-fit, minmax(min(100%, 22%), 1fr));
  }
  body.template-matcha-modern.display-ready .col.colReady .list .ord {
    align-items: center;
    border-bottom: 1px solid var(--readyBorder);
    min-height: 0;
    padding: clamp(10px, 1.6vh, 20px) clamp(10px, 1vw, 20px);
    text-align: center;
  }
  body.template-matcha-modern.display-ready .col.colReady .list .num {
    font-size: clamp(34px, min(3.8vw, 10vh), 66px);
  }
  body.template-matcha-modern.display-ready .col.colReady .list .customer {
    font-size: clamp(16px, 1.5vw, 28px);
  }
  body.template-matcha-modern.display-ready #expiredList {
    display: grid;
    gap: 0 clamp(10px, 1vw, 20px);
    grid-template-columns: repeat(4, minmax(0, 1fr));
    margin-top: clamp(8px, 1.2vh, 14px);
  }

  /* Spotlight: Ready keeps the stage; Making expands from ticker to a usable queue. */
  body.template-midnight-pearl.display-ready .col.colReady {
    order: initial;
    padding: clamp(18px, 3vh, 34px);
  }
  body.template-midnight-pearl.display-ready .col.colReady .list {
    display: grid;
    flex: 1;
    gap: clamp(8px, 1.2vw, 18px);
    grid-auto-rows: minmax(0, 1fr);
    grid-template-columns: repeat(auto-fit, minmax(min(100%, max(24%, 360px)), 1fr));
    grid-template-rows: none;
  }
  body.template-midnight-pearl.display-ready .col.colReady .list .customer {
    font-size: clamp(34px, min(4vw, 13vh), 76px);
  }
  body.template-midnight-pearl.display-making .col.colMaking {
    border-top: 0;
    order: initial;
    padding: clamp(18px, 3vh, 34px);
  }
  body.template-midnight-pearl.display-making .col.colMaking .list {
    display: grid;
    flex: 1;
    gap: clamp(8px, 1.3vw, 16px);
    grid-auto-rows: minmax(0, 1fr);
    grid-template-columns: repeat(auto-fit, minmax(min(100%, 46%), 1fr));
  }
  body.template-midnight-pearl.display-making .col.colMaking .list .ord {
    font-size: clamp(22px, min(2.4vw, 7vh), 44px);
    min-height: 0;
    padding: clamp(12px, 2vw, 24px);
  }
  body.template-midnight-pearl.display-making .col.colMaking .list .src { display: inline; }

  /* Pickup Gallery: one status, one field. Rail and gallery both become a two-up editorial grid. */
  body.template-boba-pop.display-making .col.colMaking,
  body.template-boba-pop.display-ready .col.colReady {
    border: 0;
    border-radius: 0;
    box-shadow: none;
    padding: clamp(18px, 3vh, 34px) clamp(22px, 3vw, 52px);
  }
  body.template-boba-pop.display-making .col.colMaking .list,
  body.template-boba-pop.display-ready .col.colReady .list {
    align-content: stretch;
    display: grid;
    flex: 1;
    gap: 0 clamp(20px, 2.4vw, 48px);
    grid-auto-rows: minmax(min-content, 1fr);
    grid-template-columns: repeat(auto-fit, minmax(min(100%, 44%), 1fr));
  }
  body.template-boba-pop.display-making .col.colMaking .list .ord {
    font-size: clamp(20px, min(2vw, 5.6vh), 36px);
    min-height: clamp(44px, 6.5vh, 72px);
  }
  body.template-boba-pop.display-ready .col.colReady .list .ord,
  body.template-boba-pop.display-ready .col.colReady .list .ord:first-child:nth-last-child(-n+3),
  body.template-boba-pop.display-ready .col.colReady .list .ord:first-child:nth-last-child(-n+3) ~ .ord {
    font-size: clamp(28px, min(3vw, 8.6vh), 62px);
    min-height: clamp(52px, 8vh, 96px);
  }
  body.template-boba-pop.display-ready #expiredList {
    display: grid;
    gap: 0 clamp(20px, 2.4vw, 48px);
    grid-template-columns: repeat(2, minmax(0, 1fr));
    margin-top: clamp(10px, 1.4vh, 18px);
  }

  /* Pickup Wall: a Ready screen IS the wall, so there is nothing to change there. A Making screen
     is the one thing this template does not claim to do (`screens: [1]`), and it still must not be
     blank — so Making borrows the wall grammar in a subordinate key. */
  body.template-pickup-wall.display-making .col.colMaking {
    background: transparent;
    border: 0;
    border-radius: 0;
    gap: 0;
    padding: 0;
  }
  body.template-pickup-wall.display-making .col.colMaking .coltitle {
    color: var(--muted);
    font-size: clamp(11px, min(.9vw, 1.9vh), 18px);
    font-weight: 700;
    letter-spacing: .22em;
    margin-bottom: 0;
    padding-bottom: clamp(6px, .9vh, 15px);
    text-align: center;
  }
  body.template-pickup-wall.display-making .col.colMaking .list {
    align-content: center;
    display: grid;
    flex: 1;
    gap: 0 clamp(20px, 2.6vw, 56px);
    grid-auto-rows: minmax(0, clamp(36px, min(8vw, 15vh), 240px));
    grid-template-columns: repeat(auto-fit, minmax(min(100%, max(45%, 460px)), 1fr));
    grid-template-rows: none;
  }
  body.template-pickup-wall.display-making .col.colMaking .list .ord {
    align-items: center;
    background: transparent;
    border: 0;
    border-bottom: 1px solid var(--border);
    border-radius: 0;
    color: var(--text);
    font-size: clamp(24px, min(5.3vw, 10vh), 160px);
    font-weight: 600;
    gap: clamp(9px, 1vw, 20px);
    letter-spacing: -.026em;
    line-height: 1.05;
    min-height: 0;
    padding: 0 clamp(8px, 1vw, 20px);
  }
  body.template-pickup-wall.display-making .col.colMaking .list .num {
    color: var(--muted);
    font-size: .42em;
    font-variant-numeric: tabular-nums;
    font-weight: 700;
  }
  body.template-pickup-wall.display-making .col.colMaking .list .eta {
    background: transparent;
    border-radius: 0;
    color: var(--waitText);
    font-size: .4em;
    font-variant-numeric: tabular-nums;
    font-weight: 600;
    padding: 0;
  }
  body.template-pickup-wall.display-making .col.colMaking .list .src { display: none; }

  /* Ticket Numbers: one status per screen means one wider token field. */
  body.template-ticket-numbers.display-making .col.colMaking,
  body.template-ticket-numbers.display-ready .col.colReady {
    padding: clamp(4px, .6vh, 10px) clamp(6px, .8vw, 16px);
  }
  body.template-ticket-numbers.display-making .col.colMaking .list,
  body.template-ticket-numbers.display-ready .col.colReady .list {
    grid-template-columns: repeat(auto-fit, minmax(min(100%, 22%), 1fr));
  }
  body.template-ticket-numbers.display-making .col.colMaking .list,
  body.template-ticket-numbers.display-ready .col.colReady .list {
    grid-auto-rows: minmax(0, clamp(96px, min(11vw, 24vh), 250px));
  }
  body.template-ticket-numbers.display-making .col .list .num,
  body.template-ticket-numbers.display-ready .col .list .num {
    font-size: clamp(32px, min(5.2vw, 12vh), 116px);
  }
  body.template-ticket-numbers.display-making .col.colMaking .list .eta {
    font-size: clamp(12px, min(1.1vw, 2.4vh), 22px);
  }

  /* Marquee: a Ready screen is the call, full frame. A Making screen has no call to make, so the
     strip stops being a strip and becomes a two-up queue. */
  body.template-marquee.display-ready .col.colReady {
    padding: clamp(14px, 2.4vh, 40px) clamp(24px, 2.6vw, 56px);
  }
  body.template-marquee.display-ready .col.colReady .list .num {
    font-size: clamp(26px, min(5vw, 11vh), 130px);
  }
  body.template-marquee.display-making .col.colMaking {
    border-top: 0;
    padding: clamp(14px, 2.4vh, 34px) clamp(24px, 2.6vw, 52px);
  }
  body.template-marquee.display-making .col.colMaking .coltitle {
    font-size: clamp(11px, min(1vw, 2.2vh), 20px);
  }
  /* Capped and centred, not 1fr: stretching four rows over a whole TV measured a 42px name in a
     220px cell — 20% ink on the one screen whose only job is being read. */
  body.template-marquee.display-making .col.colMaking .list {
    align-content: center;
    flex: 1;
    gap: clamp(9px, 1.1vw, 20px);
    grid-auto-rows: minmax(0, clamp(56px, min(6.5vw, 16.4vh), 200px));
    grid-template-columns: repeat(auto-fit, minmax(min(100%, 46%), 1fr));
  }
  body.template-marquee.display-making .col.colMaking .list .ord {
    align-items: center;
    flex-direction: row;
    font-size: clamp(20px, min(3.4vw, 8.6vh), 68px);
    gap: clamp(10px, 1.1vw, 20px);
    min-height: 0;
    padding: clamp(10px, 1.4vh, 20px) clamp(12px, 1.2vw, 24px);
  }
  body.template-marquee.display-making .col.colMaking .list .eta { margin-left: auto; }

  /* Card Grid: the cards get the whole frame, so they get another column rather than more height —
     a card that grows taller than it is wide has stopped being a card. */
  body.template-card-grid.display-ready .col.colReady .list {
    grid-auto-rows: minmax(0, clamp(96px, min(11vw, 26vh), 300px));
    grid-template-columns: repeat(auto-fit, minmax(min(100%, max(22%, 250px)), 1fr));
  }
  body.template-card-grid.display-ready .col.colReady .list .ord {
    font-size: clamp(20px, min(2.4vw, 6.4vh), 58px);
  }
  /* A Making screen owns a whole TV, so the queue's own compact rhythm would waste it: the shared
     cap measured a 36px name using 31% of the frame. Bigger tracks, centred group. */
  body.template-card-grid.display-making .col.colMaking .list {
    align-content: center;
    gap: 0 clamp(20px, 2.4vw, 48px);
    grid-auto-rows: minmax(0, clamp(46px, min(7vw, 19vh), 210px));
    grid-template-columns: repeat(auto-fit, minmax(min(100%, 46%), 1fr));
  }
  body.template-card-grid.display-making .col.colMaking .list .ord {
    font-size: clamp(18px, min(3.4vw, 9vh), 68px);
  }
  body.template-card-grid.display-ready #expiredList {
    display: grid;
    gap: 0 clamp(16px, 2vw, 36px);
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  /* Portrait Rail: the stacked grid leaves an empty second track behind when one column goes, so
     the surviving column spans both rather than settling for 60% of the frame. */
  body.template-portrait-rail.display-making .col.colMaking,
  body.template-portrait-rail.display-ready .col.colReady {
    grid-row: 1 / -1;
  }
  body.template-portrait-rail.display-ready .col.colReady { padding: 0; }
  /* 4.9vw, not 6.2vw: at 6.2vw a fifteen-character display name measured 927px against 780px of
     usable plate — the number keeps a right-hand gutter, so the plate is narrower than the cell. */
  body.template-portrait-rail.display-ready .col.colReady .list {
    grid-auto-rows: minmax(0, clamp(39px, min(7.35vw, 16.5vh), 225px));
  }
  body.template-portrait-rail.display-ready .col.colReady .list .ord {
    font-size: clamp(26px, min(4.9vw, 11vh), 150px);
  }
  body.template-portrait-rail.display-making .col.colMaking {
    border-top: 0;
    padding: 0;
  }
  body.template-portrait-rail.display-making .col.colMaking .list {
    align-content: center;
    flex: 1;
    gap: clamp(5px, .7vh, 11px) clamp(9px, 1vw, 18px);
    grid-auto-rows: minmax(0, clamp(44px, min(7vw, 20vh), 240px));
    grid-template-columns: repeat(auto-fit, minmax(min(100%, 46%), 1fr));
  }
  body.template-portrait-rail.display-making .col.colMaking .list .ord {
    font-size: clamp(18px, min(4.4vw, 13vh), 100px);
  }

  /* Brand Band: the band is unchanged — it is the shop's sign whichever half of the queue is below
     it — and the surviving column becomes a two-up field. */
  /* One status per screen means two-up rows with capped tracks: at 1fr the eight ready names sat in
     206px bands at 27% ink on the one screen that owns a whole TV. Track stays 1.5x the type in the
     same units, so the ratio holds on a short mount as well as a tall one. */
  body.template-brand-band.display-making .col .list,
  body.template-brand-band.display-ready .col .list {
    align-content: center;
    gap: 0 clamp(20px, 2.4vw, 48px);
    grid-template-columns: repeat(auto-fit, minmax(min(100%, 46%), 1fr));
  }
  body.template-brand-band.display-making .col.colMaking .list {
    grid-auto-rows: minmax(0, clamp(30px, min(5.1vw, 13.5vh), 150px));
  }
  body.template-brand-band.display-ready .col.colReady .list {
    grid-auto-rows: minmax(0, clamp(36px, min(6.9vw, 18vh), 190px));
  }
  body.template-brand-band.display-making .col.colMaking .list .ord {
    font-size: clamp(19px, min(3.4vw, 9vh), 100px);
  }
  body.template-brand-band.display-ready .col.colReady .list .ord {
    font-size: clamp(24px, min(4.6vw, 12vh), 126px);
  }
  body.template-brand-band.display-ready #expiredList {
    display: grid;
    gap: 0 clamp(20px, 2.4vw, 48px);
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  @media (max-width: 760px), (max-aspect-ratio: 1/1) {
    body.display-making .cols,
    body.display-ready .cols {
      grid-template-rows: minmax(0, 1fr);
    }
    body.template-bliss-light.display-ready .colReady .list,
    body.template-matcha-modern.display-ready .colReady .list,
    body.template-midnight-pearl.display-ready .colReady .list,
    body.template-midnight-pearl.display-making .colMaking .list,
    body.template-boba-pop.display-making .list,
    body.template-boba-pop.display-ready .list {
      grid-template-columns: repeat(auto-fit, minmax(46%, 1fr));
      grid-auto-rows: minmax(0, 1fr);
    }
    /* The display-* layer above is unconditional, so it re-widens the grids this file already
       narrowed for portrait. These put them back — same arithmetic, long axis. */
    body.template-pickup-wall.display-making .col.colMaking .list {
      gap: 0;
      grid-auto-rows: minmax(0, clamp(36px, min(12.6vw, 9vh), 240px));
      grid-template-columns: minmax(0, 1fr);
    }
    body.template-pickup-wall.display-making .col.colMaking .list .ord {
      font-size: clamp(22px, min(8.4vw, 6vh), 160px);
      padding-inline: 0;
    }
    body.template-marquee.display-making .col.colMaking .list {
      grid-auto-rows: minmax(0, clamp(48px, min(13.3vw, 14vh), 180px));
      grid-template-columns: minmax(0, 1fr);
    }
    body.template-marquee.display-making .col.colMaking .list .ord {
      font-size: clamp(20px, min(7vw, 7.4vh), 80px);
    }
    body.template-ticket-numbers.display-making .col.colMaking .list,
    body.template-ticket-numbers.display-ready .col.colReady .list,
    body.template-card-grid.display-ready .col.colReady .list {
      grid-template-columns: repeat(auto-fit, minmax(min(100%, 46%), 1fr));
    }
    body.template-ticket-numbers.display-making .col.colMaking .list,
    body.template-ticket-numbers.display-ready .col.colReady .list {
      grid-auto-rows: minmax(0, clamp(78px, min(20vw, 13vh), 190px));
    }
    body.template-ticket-numbers.display-making .col .list .num,
    body.template-ticket-numbers.display-ready .col .list .num {
      font-size: clamp(28px, min(9.4vw, 6.2vh), 86px);
    }
    body.template-card-grid.display-ready .col.colReady .list {
      grid-auto-rows: minmax(0, clamp(90px, min(21vw, 15vh), 240px));
    }
    body.template-card-grid.display-ready .col.colReady .list .ord {
      font-size: clamp(18px, min(5vw, 4.4vh), 52px);
    }
    body.template-portrait-rail.display-ready .col.colReady .list {
      grid-auto-rows: minmax(0, clamp(39px, min(14.1vw, 9.9vh), 250px));
      grid-template-columns: minmax(0, 1fr);
    }
    body.template-portrait-rail.display-ready .col.colReady .list .ord {
      font-size: clamp(26px, min(9.4vw, 6.6vh), 166px);
    }
    body.template-portrait-rail.display-making .col.colMaking .list {
      grid-auto-rows: minmax(0, clamp(40px, min(14vw, 10.8vh), 200px));
      grid-template-columns: minmax(0, 1fr);
    }
    body.template-portrait-rail.display-making .col.colMaking .list .ord {
      font-size: clamp(20px, min(9.4vw, 7.2vh), 130px);
    }
    body.template-brand-band.display-making .col .list,
    body.template-brand-band.display-ready .col .list {
      grid-template-columns: minmax(0, 1fr);
    }
    body.template-brand-band.display-making .col.colMaking .list {
      grid-auto-rows: minmax(0, clamp(30px, min(8.4vw, 7.2vh), 150px));
    }
    body.template-brand-band.display-ready .col.colReady .list {
      grid-auto-rows: minmax(0, clamp(36px, min(10.5vw, 9vh), 190px));
    }
    body.template-brand-band.display-making .col.colMaking .list .ord {
      font-size: clamp(17px, min(5.6vw, 4.8vh), 100px);
    }
    body.template-brand-band.display-ready .col.colReady .list .ord {
      font-size: clamp(22px, min(7vw, 6vh), 126px);
    }
  }

  @media (prefers-reduced-motion: reduce) {
    *, *::before, *::after {
      scroll-behavior: auto !important;
      animation-duration: .001ms !important;
      animation-iteration-count: 1 !important;
      transition-duration: .001ms !important;
    }
  }
  /* A ticket is the primary label when the row has no customer name. */
  body .col.colMaking .list .ord.number-only .num,
  body .col.colReady .list .ord.number-only .num { margin:0; order:0; color:inherit; }
  body.template-warm-counter .col .ord.number-only::before { content:none; }
  body.template-warm-counter .col .ord.number-only .eta { margin-left:auto; }
  body.template-matcha-modern .col.colMaking .list .ord.number-only {
    grid-template-columns:minmax(0,1fr) auto auto;
  }
  body.template-matcha-modern .col.colMaking .list .ord.number-only .src { grid-column:2; }
  body.template-matcha-modern .col.colMaking .list .ord.number-only .eta { grid-column:3; }
/* Removing a ticket leaves the customer as the primary label in every grammar. */
  body .col .list .ord.name-only { grid-template-columns:minmax(0,1fr) auto auto; }
  body[class] .col .list .ord.name-only .customer { display:block; grid-column:1; order:0; }
  body .col .list .ord.name-only::before, body .col .list .ord.name-only::after { display:none; }
