/* Unified TV Board — Hollerbak Supply Co. brand treatment.
   Clean, professional, readable at 10 feet. White page, near-black ink,
   the Hbk. badge in the header, one restrained accent: the warm amber
   the parent site uses for its highlight. No arcade styling anywhere.
   Layout per UNIFIED-TV-BOARD-DESIGN.md §2 as amended by the Oct 23
   addendum (Jim's camera-wall directives): the camera wall dominates and
   runs full-bleed, the business band and live strip below it are slimmed
   (content intact, just shorter), the header is a thin bar. The wall
   stays passive; camera tiles are clickable and drill into a per-camera
   detail view (board.js). A later note the same day (Jim, ~10:01 AM)
   stacked the wall's two buildings into EQUAL, FULL-WIDTH BANDS — home
   on top, business underneath, same height — and made tile media
   whole-frame (contain, never cropped).
   Superseding rule (Jim, Oct 23, ~11:11 AM): "the board is static, you
   can't move it — all you see is two cameras and the other camera.
   Shrink them all so everything fits inside one window, for a phone or
   for a TV — native for that." The stacked bands sized tiles from their
   width, so the wall outgrew short/portrait viewports and scrolled.
   NOW: the whole board — header, the full camera wall (every camera of
   both buildings at once), the mid band and the live strip — fits
   inside ONE viewport with no scrolling at any size. The wall's cells
   are sized in viewport-relative minmax(0,1fr) tracks in both axes, so
   tiles shrink to whatever window they are given; tile type, chips and
   paddings scale with vmin (clamped) so names and state pills stay on
   one line instead of wrapping or pushing the layout out. Frames are
   still never cropped: the media keeps object-fit:contain inside
   whatever cell it gets, letterboxed on the tile's black ground. The
   tap-a-tile detail view remains the way to see one camera big. */
:root{
  --bg:#ffffff; --panel:#ffffff; --panel-alt:#fbfaf7;
  --ink:#16150f; --ink-2:#4c4a41; --ink-3:#8f8b7d;
  --line:#e5e1d6; --line-strong:#cfccc0;
  --amber:#ffe9a8; --amber-ink:#5c4a12; --gold:#c1910a;
  --live:#1e7d46; --warn:#946a08; --bad:#b3271e;
  --radius:16px;
  --sans:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif;
}
*{box-sizing:border-box}
html,body{height:100%}
body{margin:0;background:var(--bg);color:var(--ink);font:18px/1.45 var(--sans);overflow:hidden;display:flex;flex-direction:column;height:100vh;height:100dvh}
h1,h2,h3{font-weight:650}

/* header — a thin bar; the cameras own the screen */
.b-head{display:flex;align-items:center;gap:14px;padding:0 16px;border-bottom:1px solid var(--line);height:56px;flex:none;background:var(--bg)}
.b-brand{display:flex;align-items:center;gap:12px;white-space:nowrap}
.b-badge{width:40px;height:40px;display:block}
.b-wordmark{display:flex;flex-direction:column;line-height:1.15}
.b-company{font-size:17px;font-weight:650;letter-spacing:.01em;color:var(--ink)}
.b-board-name{font-size:10.5px;font-weight:600;letter-spacing:.22em;text-transform:uppercase;color:var(--ink-3)}
.b-home-link{font:600 14.5px var(--sans);color:var(--ink);text-decoration:none;border:1.5px solid var(--line-strong);border-radius:999px;padding:8px 13px;white-space:nowrap;background:var(--bg)}
.b-home-link:hover{border-color:var(--gold);background:var(--amber)}
.b-home-link:focus-visible{outline:3px solid var(--gold);outline-offset:2px}
.b-home-short{display:none}
.b-clock{font-size:24px;font-weight:650;margin-left:auto;white-space:nowrap;font-variant-numeric:tabular-nums}
.b-tz{font-size:13px;font-weight:500;color:var(--ink-3)}
.b-asof{font-size:13px;color:var(--ink-3);white-space:nowrap}

/* main grid — camera wall flexes; business band + strip are slim auto
   rows. The main area takes exactly the viewport height left under the
   header (body is a 100dvh flex column): nothing on this page scrolls,
   at any size — every region below is sized to fit inside its share. */
.b-main{display:grid;grid-template-rows:minmax(0,1fr) auto auto;flex:1 1 auto;min-height:0;background:var(--bg)}
.b-main>section{min-width:0;min-height:0}

/* camera wall — full-bleed; buildings are two stacked, equal bands
   (home on top, business underneath, each band the same height).
   The wall is a 2-row grid of minmax(0,1fr) tracks and each building's
   tiles live in a single minmax(0,1fr) row of minmax(0,1fr) columns,
   so every camera of both buildings is on screen at once and the
   cells — never the page — absorb the size of the window. Tile media
   keeps object-fit:contain inside its cell: the whole frame, always,
   letterboxed on the tile's black ground. Overflow cameras beyond a
   band's slots keep the board.js rotation (hidden attr), unchanged. */
.b-wall{display:grid;grid-template-rows:minmax(0,1fr) minmax(0,1fr);gap:min(8px,1vmin);padding:min(8px,1vmin) min(8px,1vmin) min(4px,.6vmin);min-height:0}
.b-building{border:1px solid var(--line);border-radius:12px;background:var(--panel-alt);padding:min(8px,1.2vmin) min(10px,1.4vmin) min(10px,1.4vmin);display:flex;flex-direction:column;min-height:0;min-width:0}
.b-building-name{font-size:clamp(9px,1.5vmin,11.5px);font-weight:650;letter-spacing:.16em;text-transform:uppercase;margin:0 0 clamp(3px,.8vmin,6px);color:var(--ink-2);display:flex;align-items:center;gap:10px;white-space:nowrap;overflow:hidden}
.b-building-name::before{content:"";width:22px;height:3px;border-radius:2px;background:var(--gold);flex:none}
.b-tiles{display:grid;gap:min(8px,1vmin);flex:1;min-height:0;min-width:0;grid-template-rows:minmax(0,1fr)}
#tiles-home{grid-template-columns:repeat(2,minmax(0,1fr))}
#tiles-business{grid-template-columns:repeat(3,minmax(0,1fr))}

.tile{position:relative;background:#101010;border:1px solid var(--line-strong);border-radius:12px;overflow:hidden;min-height:0;min-width:0}
.tile:not(.tile-placeholder):not(.tile-waiting){cursor:pointer}
.tile:focus-visible{outline:3px solid var(--gold);outline-offset:2px}
.tile video,.tile .tile-frame{position:absolute;inset:0;width:100%;height:100%;object-fit:contain;background:#101010}
.tile .tile-frame{display:none}
.tile[data-state="idle"] .tile-frame,.tile[data-state="offline"] .tile-frame{display:block}
.tile[data-state="offline"] .tile-frame{filter:grayscale(1) brightness(.75)}
.tile[data-state="live"] video{display:block}
.tile video{display:none}
.tile .tile-label{position:absolute;left:0;right:0;bottom:0;padding:clamp(8px,2.6vmin,22px) clamp(8px,1.6vmin,12px) clamp(5px,1vmin,8px);background:linear-gradient(transparent,rgba(0,0,0,.78));color:#fff;font-size:clamp(10px,2vmin,19px);font-weight:600;display:flex;gap:clamp(5px,1.2vmin,10px);align-items:baseline;min-width:0}
.tile .tile-name{flex:0 1 auto;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.tile .tile-sub{font-size:clamp(9px,1.7vmin,15px);color:rgba(255,255,255,.75);font-weight:400;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.tile .tile-chip{position:absolute;top:clamp(4px,1.2vmin,10px);left:clamp(4px,1.2vmin,10px);font-size:clamp(8px,1.3vmin,11px);font-weight:700;letter-spacing:.14em;text-transform:uppercase;padding:clamp(3px,.7vmin,5px) clamp(6px,1.2vmin,11px);border-radius:999px;background:rgba(16,16,16,.72);color:#f2f0e9;white-space:nowrap}
.tile[data-state="live"] .tile-chip{background:var(--live);color:#fff}
.tile[data-state="error"] .tile-chip,.tile[data-state="offline"] .tile-chip{background:var(--warn);color:#fff}
.tile.tile-flash{animation:tileflash 10s ease-out}
@keyframes tileflash{0%,60%{box-shadow:inset 0 0 0 3px var(--gold)}100%{box-shadow:inset 0 0 0 0 transparent}}
.tile.tile-placeholder{align-items:center;justify-content:center;display:flex;background:#f4f1ea}
.tile.tile-placeholder .tile-ph{text-align:center;color:var(--ink-3);padding:clamp(6px,1.4vmin,12px);font-size:clamp(10px,1.8vmin,17px);max-width:100%;min-width:0;overflow-wrap:break-word}
.tile.tile-placeholder .tile-ph b{display:block;font-size:clamp(12px,2.4vmin,20px);font-weight:600;color:var(--ink-2);margin-bottom:clamp(2px,.6vmin,6px)}
.tile.tile-waiting{align-items:center;justify-content:center;display:flex;background:#f4f1ea}
.tile.tile-waiting .tile-ph{text-align:center;color:var(--ink-3);padding:clamp(6px,1.4vmin,12px);font-size:clamp(10px,1.8vmin,17px);max-width:100%;min-width:0;overflow-wrap:break-word}

/* Camera OFFLINE state (Oct 23): a camera that cannot stream (offline,
   asleep, charging) gets a labeled warm panel, never a black void — one
   dead camera must not read as a broken board. Shown only in the offline
   state; the state chip + label line carry the same message. */
.tile .tile-offline{display:none}
.tile[data-state="offline"]{background:#2a2620}
.tile[data-state="offline"] .tile-offline{display:flex;position:absolute;inset:0;flex-direction:column;align-items:center;justify-content:center;gap:clamp(2px,.6vmin,6px);color:#f2ead8;text-align:center;padding:8px}
.tile .tile-offline b{font-size:clamp(12px,2.4vmin,22px);font-weight:650;letter-spacing:.06em;text-transform:uppercase}
.tile .tile-offline span{font-size:clamp(9px,1.7vmin,15px);color:rgba(242,234,216,.75)}
.tile[data-state="offline"] video,.tile[data-state="offline"] .tile-frame{display:none}

/* Orders wall (Oct 23): the mid band's orders stream + today counters.
   The stream is grouped by brand, then by collection within the brand
   (Jim's design change — no combined all-channels list); the channel is
   a small tag on each row (.b-ochan). Each brand→collection group gets
   ONE compact heading line (brand in ink, collection in spaced caps
   after it) so the grouped stream stays close to the flat stream's
   height inside the mid band's cap; the panel clips, never scrolls. */
.b-ghead{font-size:clamp(9.5px,1.6vmin,14.5px);line-height:1.3;margin:clamp(3px,.7vmin,6px) 0 clamp(1px,.25vmin,2px);color:var(--ink-2)}
.b-ghead b{font-weight:700;color:var(--ink)}
.b-ghead span{font-weight:650;letter-spacing:.12em;text-transform:uppercase}
.b-gblock:first-child .b-ghead{margin-top:0}
/* Wide screens: the grouped stream flows in two columns inside the
   orders panel so every brand group stays on the wall at TV size —
   groups never split across the column break. Narrow screens keep one
   column in Jim's brand order. */
@media (min-width:900px){
  #orders-body{column-count:2;column-gap:clamp(12px,2vmin,24px)}
  .b-gblock{break-inside:avoid}
}
.b-orow{display:flex;align-items:baseline;gap:clamp(5px,1.1vmin,10px);padding:clamp(1px,.35vmin,3px) 0;border-bottom:1px solid var(--line);min-width:0;font-size:clamp(10px,1.75vmin,15.5px)}
.b-orow:last-of-type{border-bottom:none}
.b-ochip{flex:none;font-size:clamp(7.5px,1.25vmin,10.5px);font-weight:700;letter-spacing:.08em;text-transform:uppercase;padding:clamp(2px,.5vmin,4px) clamp(5px,1vmin,8px);border-radius:999px;background:#e8e2d4;color:#5c4a12;white-space:nowrap}
.b-ochip.o-production{background:#dcebf5;color:#17557f}
.b-ochip.o-shipped{background:#dcefe2;color:#1e7d46}
.b-ochip.o-delivered{background:#1e7d46;color:#fff}
.b-ochip.o-hold,.b-ochip.o-flag{background:#f6e0dc;color:#b3271e}
.b-omain{flex:1 1 auto;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.b-omain b{font-weight:650}
.b-ochan{color:var(--ink-2)}
.b-oitems{color:var(--ink-3)}
.b-oitems::before{content:" — "}
.b-ototal{flex:none;font-weight:650;font-variant-numeric:tabular-nums}
.b-otime{flex:none;color:var(--ink-3);font-size:.86em;font-variant-numeric:tabular-nums;white-space:nowrap}
.b-onote{font-size:clamp(9px,1.4vmin,12px);color:var(--warn);margin:clamp(3px,.7vmin,6px) 0 0}
.b-trow{display:flex;justify-content:space-between;gap:10px;padding:clamp(1px,.35vmin,3px) 0;border-bottom:1px solid var(--line);font-size:clamp(10px,1.75vmin,15.5px);min-width:0}
.b-trow span:first-child{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.b-trow span:last-child{flex:none;font-variant-numeric:tabular-nums}
.b-trow.b-ttotal{font-weight:650;border-bottom:2px solid var(--line-strong)}
/* Phone widths: the stream stays legible by shedding its softest parts —
   items text and clock time go; chip, order, channel and total remain.
   Group heads go single-line: the brand always fits; a long collection
   name ellipsizes rather than eating a second line of panel height. */
@media (max-width:560px){
  .b-oitems{display:none}
  .b-oitems::before{content:""}
  .b-otime{display:none}
  .b-ghead{display:flex;gap:6px;white-space:nowrap;overflow:hidden}
  .b-ghead span{overflow:hidden;text-overflow:ellipsis}
}

/* middle band — slimmed (addendum b): same content, less height.
   Three columns at EVERY size now (the old small-screen stack is gone):
   stacking is what pushed the board past one viewport. Type and
   padding scale with vmin so the band stays inside its 26vh cap on a
   phone exactly as it does on a TV. */
.b-mid{display:grid;grid-template-columns:minmax(0,1.9fr) minmax(0,1fr) minmax(0,1.1fr);gap:min(8px,1vmin);padding:min(4px,.6vmin) min(8px,1vmin);min-height:0;max-height:26vh}
.b-panel{border:1px solid var(--line);border-radius:12px;background:var(--panel);padding:clamp(6px,1.4vmin,10px) clamp(8px,1.8vmin,14px);overflow:hidden;min-width:0}
.b-panel h3{font-size:clamp(9px,1.5vmin,12px);font-weight:650;letter-spacing:.16em;text-transform:uppercase;margin:0 0 clamp(3px,.8vmin,8px);color:var(--ink-2);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.b-panel-body{font-size:clamp(11px,1.9vmin,16.5px)}
.b-panel-body p{margin:0 0 clamp(3px,.7vmin,6px)}
.b-waiting{color:var(--ink-3)}
.b-stale-tag{display:inline-block;font-size:12px;font-weight:700;letter-spacing:.08em;text-transform:uppercase;color:var(--amber-ink);background:var(--amber);border-radius:999px;padding:2px 9px;margin-left:8px;vertical-align:middle}
.b-big{font-size:clamp(17px,3.2vmin,28px);font-weight:700}
.b-row{display:flex;justify-content:space-between;gap:12px;padding:3px 0;border-bottom:1px solid var(--line)}
.b-row:last-child{border-bottom:0}
.b-sev{font-weight:700}
.b-sev1{color:var(--bad)}.b-sev2{color:var(--warn)}
.b-quiet{color:var(--ink-3)}
.b-age{color:var(--ink-3);font-size:clamp(10px,1.8vmin,16px);white-space:nowrap}

/* live strip — slimmed (addendum b); type scales with vmin like the rest */
.b-strip{background:#16150f;color:#f5f3ec;border-radius:12px;display:flex;flex-direction:column;padding:clamp(4px,.8vmin,6px) clamp(8px,1.8vmin,14px) clamp(3px,.7vmin,5px);margin:min(4px,.6vmin) min(8px,1vmin) min(8px,1vmin);min-height:0;overflow:hidden}
.b-strip-zones{display:flex;gap:clamp(10px,2.6vmin,24px);overflow:hidden;flex:1;align-items:flex-start;min-width:0}
.b-zone{display:flex;gap:clamp(8px,2vmin,20px);white-space:nowrap;overflow:hidden;font-size:clamp(11px,1.9vmin,16.5px);min-width:0}
.b-zone .z-item{display:inline-flex;gap:8px;align-items:baseline}
.b-zone .z-when{color:#a49f8f;font-size:clamp(9px,1.5vmin,13.5px)}
.b-zone .z-dot{font-size:clamp(9px,1.5vmin,13px);align-self:center}
.b-zone .z-dot-new{color:#4ade80}.b-zone .z-dot-shipped{color:#7cc4ff}.b-zone .z-dot-delivered{color:#c9c4b4}
.b-zone .z-cam{color:var(--gold);font-size:clamp(9px,1.5vmin,13px);align-self:center}
.b-zone-flags{color:#ffd97a;font-weight:600;margin-left:auto}
.b-strip-label{font-size:clamp(9px,1.4vmin,12px);color:#a49f8f;text-align:right}

/* camera detail (addendum d) — a drill-in over the wall; the wall keeps
   updating behind it and the back button always returns to it. */
.b-detail{position:fixed;inset:0;z-index:60;background:var(--bg);display:flex;flex-direction:column}
.b-detail[hidden]{display:none}
.b-detail-head{display:flex;align-items:center;gap:16px;padding:10px 16px;border-bottom:1px solid var(--line);min-height:60px}
.b-detail-back{font:600 15px var(--sans);background:var(--ink);color:#fff;border:0;border-radius:10px;padding:11px 18px;cursor:pointer;white-space:nowrap}
.b-detail-back:hover{background:#000}
.b-detail-back:focus-visible{outline:3px solid var(--gold);outline-offset:2px}
.b-detail-title{display:flex;flex-direction:column;line-height:1.2;min-width:0}
.b-detail-room{font-size:22px;font-weight:650}
.b-detail-sub{font-size:12px;font-weight:600;letter-spacing:.18em;text-transform:uppercase;color:var(--ink-3)}
.b-detail-chip{font-size:11px;font-weight:700;letter-spacing:.14em;text-transform:uppercase;padding:5px 11px;border-radius:999px;background:rgba(16,16,16,.72);color:#f2f0e9;white-space:nowrap}
.b-detail[data-state="live"] .b-detail-chip{background:var(--live);color:#fff}
.b-detail[data-state="error"] .b-detail-chip,.b-detail[data-state="offline"] .b-detail-chip{background:var(--warn);color:#fff}
.b-detail-gh{margin-left:auto;font:600 14.5px var(--sans);color:var(--ink);text-decoration:none;border:1.5px solid var(--line-strong);border-radius:10px;padding:10px 14px;white-space:nowrap}
.b-detail-gh:hover{border-color:var(--gold);background:var(--amber)}
.b-detail-body{flex:1;display:grid;grid-template-columns:minmax(0,1fr) 360px;gap:12px;padding:12px;min-height:0}
.b-detail-stage{position:relative;background:#101010;border-radius:12px;overflow:hidden;display:flex;align-items:center;justify-content:center;min-height:0}
.b-detail-stage video{width:100%;height:100%;object-fit:contain;display:block;background:#000}
.b-detail-stage .b-detail-still{width:100%;height:100%;object-fit:contain;display:block}
.b-detail-nopic{color:#c9c4b4;font-size:18px;text-align:center;padding:24px;max-width:520px}
.b-detail-side{overflow-y:auto;min-height:0;padding-right:2px}
.b-detail-side h3{font-size:12.5px;font-weight:650;letter-spacing:.16em;text-transform:uppercase;margin:2px 0 10px;color:var(--ink-2)}
.b-ev{border:1px solid var(--line);border-radius:10px;padding:9px 11px;margin:0 0 9px;background:var(--panel-alt)}
.b-ev-head{display:flex;justify-content:space-between;gap:10px;align-items:baseline}
.b-ev-kind{font-weight:650;font-size:16.5px}
.b-ev-time{color:var(--ink-3);font-size:14px;white-space:nowrap}
.b-ev img{width:100%;aspect-ratio:16/9;object-fit:cover;border-radius:7px;display:block;margin-top:8px;background:#101010}
.b-detail-note{color:var(--ink-3);font-size:14px;margin:10px 0}
.b-detail-caps{border-top:1px solid var(--line);margin-top:14px;padding-top:10px;font-size:14.5px;color:var(--ink-2)}
.b-detail-caps p{margin:0 0 6px}

/* small screens: the board does NOT stack or scroll (that was the old
   behavior Jim overruled — the whole wall fits one window, native to
   the device). The grid above already shrinks everything; here the
   header just compacts and the detail view adapts. */
@media (max-width:860px){
  .b-head{gap:8px;padding:0 8px;height:48px}
  .b-brand{gap:6px}
  .b-badge{width:30px;height:30px}
  .b-company{font-size:13.5px}
  .b-board-name{font-size:8.5px;letter-spacing:.14em}
  .b-home-link{font-size:13px;padding:7px 8px}
  .b-home-full{display:none}
  .b-home-short{display:inline}
  .b-clock{font-size:16px}
  .b-tz{display:none}
  .b-asof{display:none}
  .b-detail-head{flex-wrap:wrap;gap:8px;padding:8px 10px}
  .b-detail-back{font-size:14px;padding:9px 12px}
  .b-detail-body{grid-template-columns:1fr;grid-template-rows:minmax(220px,46vh) auto;overflow-y:auto}
  .b-detail-side{overflow:visible}
  .b-detail-gh{font-size:13px;padding:9px 10px;margin-left:0}
  .b-detail-home{margin-left:auto}
  .b-detail-room{font-size:18px}
}

/* short screens (landscape phones, small windows): compress the fixed
   furniture so the wall keeps the height. Nothing scrolls here either;
   the mid band's cap tightens and the header thins. */
@media (max-height:480px){
  .b-head{height:44px}
  .b-badge{width:30px;height:30px}
  .b-company{font-size:13.5px}
  .b-board-name{font-size:8.5px;letter-spacing:.14em}
  .b-clock{font-size:16px}
  .b-tz{display:none}
  .b-asof{display:none}
  .b-mid{max-height:20vh}
  .b-strip-label{display:none}
}

/* gate */
.b-gate-body{overflow:auto;background:var(--bg);display:block;height:auto;min-height:100vh;min-height:100dvh}
.b-gate{max-width:520px;margin:9vh auto;padding:42px 44px 36px;border:1px solid var(--line);border-radius:20px;background:var(--panel);box-shadow:0 14px 44px rgba(22,21,15,.08);text-align:center}
.b-gate-badge{width:104px;height:104px;display:block;margin:0 auto 18px}
.b-gate h1{font-size:25px;font-weight:650;margin:0 0 4px;color:var(--ink)}
.b-gate-sub{font-size:12px;font-weight:600;letter-spacing:.22em;text-transform:uppercase;color:var(--ink-3);margin:0 0 20px}
.b-gate-notice{font-size:16.5px;color:var(--ink-2);margin:0 0 6px}
.b-gate-form{display:grid;gap:10px;margin:22px 0 6px;text-align:left}
.b-gate-signin{margin:22px 0 6px}
.b-gate-form label{font-size:12.5px;font-weight:600;letter-spacing:.14em;text-transform:uppercase;color:var(--ink-2)}
.b-gate-form input{font-size:17px;padding:13px 14px;background:#fff;color:var(--ink);border:1.5px solid var(--line-strong);border-radius:10px;font-family:var(--sans)}
.b-gate-form input:focus{outline:3px solid var(--amber);outline-offset:1px;border-color:var(--gold)}
.b-gate-form button{font-size:16.5px;font-weight:600;background:var(--ink);color:#fff;border:0;border-radius:10px;padding:14px;cursor:pointer;font-family:var(--sans)}
.b-gate-form button:hover{background:#000}
.b-gate-err{color:var(--bad);min-height:1.2em;margin:0;font-size:15.5px}
.b-gate-google{display:inline-block;font-size:16.5px;font-weight:600;background:var(--ink);color:#fff;border:0;border-radius:10px;padding:14px 26px;cursor:pointer;font-family:var(--sans);text-decoration:none}
.b-gate-google:hover{background:#000}
.b-gate-help{color:var(--ink-3);font-size:14.5px;margin:14px 0 0}

/* Alert bell toggle (public/bell.js) — lives in the header bar, right
   of the as-of stamp. Three honest states: off, on, and on-but-the-
   browser-is-holding-the-sound (gold outline, "tap to enable"). */
.ub-bell{font:600 12.5px var(--sans);color:var(--ink-3);background:var(--bg);border:1.5px solid var(--line-strong);border-radius:999px;padding:7px 12px;cursor:pointer;white-space:nowrap;flex:none}
.ub-bell.on{color:#0c2410;background:#5ec46a;border-color:#5ec46a}
.ub-bell.on.blocked{color:var(--gold);background:var(--bg);border-color:var(--gold)}
.ub-bell.ringing{animation:ub-bell-flash .9s ease-in-out}
@keyframes ub-bell-flash{0%,100%{transform:scale(1)} 25%{transform:scale(1.12) rotate(-6deg)} 60%{transform:scale(1.12) rotate(6deg)}}
