/* Extracted from console.html's <style> block, which had reached 2,428 lines in one
   hand-maintained file with no build step — a size this repository has
   already been broken at once (sb/api.py, the studio split). The split is
   also what lets two workers touch the desk in one cycle without editing
   the same file, which the execution protocol's partition rule requires. */
*{box-sizing:border-box}
body{margin:0;background:var(--bg);color:var(--fg);
font:15px/1.55 ui-sans-serif,-apple-system,"Segoe UI",Roboto,sans-serif}
.top{border-bottom:1px solid var(--line);background:var(--panel)}
.topin{max-width:1100px;margin:0 auto;padding:12px 16px;display:flex;
align-items:center;gap:12px;flex-wrap:wrap}
.brand{font-weight:700;font-size:16px;margin-right:auto}
.brand span{color:var(--dim);font-weight:400;font-size:13px;margin-left:8px}
.wrap{max-width:1100px;margin:0 auto;padding:22px 16px 72px}
h2{font-size:16px;margin:0 0 3px}
.sub{color:var(--dim);font-size:13px;margin-bottom:16px}
.card{background:var(--panel);border:1px solid var(--line);border-radius:12px;
padding:18px;margin-bottom:16px}
label{display:block;font-size:12px;text-transform:uppercase;letter-spacing:.06em;
color:var(--dim);margin-bottom:6px}
select,input,textarea{width:100%;background:var(--bg);color:var(--fg);
border:1px solid var(--line);border-radius:8px;padding:10px 12px;font:inherit}
.top select{width:auto;padding:6px 10px;font-size:13px}
textarea{min-height:92px;resize:vertical}
button{background:var(--accent);color:#fff;border:0;border-radius:8px;
padding:10px 18px;font:inherit;font-weight:600;cursor:pointer}
button:disabled{opacity:.55;cursor:default}
button.ghost{background:transparent;color:var(--fg);border:1px solid var(--line)}
button.sm{padding:6px 12px;font-size:13px;font-weight:500}
button.danger{background:var(--bad)}
.row{display:grid;grid-template-columns:1fr 1fr;gap:14px}
@media(max-width:780px){.row{grid-template-columns:1fr}}
.chips{display:flex;flex-wrap:wrap;gap:8px;margin-top:8px}
.chip{display:flex;align-items:center;gap:6px;background:var(--bg);
border:1px solid var(--line);border-radius:999px;padding:5px 12px;font-size:13px;cursor:pointer}
.chip input{width:auto}
.pill{display:inline-block;padding:2px 9px;border-radius:999px;font-size:11.5px;margin-right:6px}
.pill.ok{background:rgba(74,222,128,.15);color:var(--ok)}
.pill.warn{background:rgba(251,191,36,.15);color:var(--warn)}
.pill.dim{background:var(--bg);color:var(--dim);border:1px solid var(--line)}
.pill.bad{background:rgba(248,113,113,.15);color:var(--bad)}
.pill.mute{background:var(--bg);color:var(--dim);border:1px dashed var(--line)}
.creds{display:flex;flex-wrap:wrap;gap:6px}
.creds button{text-transform:capitalize}
/* Readable, not shouting: a visitor leaving is normal, and the row is still
   worth resolving. Dim it and label it; never colour it like a failure. */
.gone{color:var(--dim);font-style:italic}
.hint{color:var(--dim);font-size:13px;margin-top:8px}
.meta{color:var(--dim);font-size:12.5px;margin-top:10px;font-family:ui-monospace,monospace}
.cite{border-left:3px solid var(--accent);padding:8px 12px;margin:8px 0;
background:var(--bg);border-radius:0 8px 8px 0;font-size:13.5px}
.cite b{color:var(--accent)}
.draft{background:var(--bg);border:1px solid var(--line);border-radius:8px;
padding:14px 16px;font-size:15px}
.md p{margin:0 0 10px} .md p:last-child{margin-bottom:0}
.md ul,.md ol{margin:0 0 10px; padding-left:22px} .md li{margin:3px 0}
.md h4.mdh{margin:14px 0 6px;font-size:14px;letter-spacing:.01em}
.md code{background:var(--panel);padding:1px 5px;border-radius:4px;font-size:13px}
.md sup.cn{display:inline-block;min-width:16px;text-align:center;background:var(--accent);
color:#fff;border-radius:4px;font-size:10px;line-height:14px;margin:0 2px;font-weight:700;
vertical-align:super;cursor:default}
.subject{font-weight:600;margin-bottom:10px;padding-bottom:8px;border-bottom:1px solid var(--line)}
mark{background:rgba(110,168,254,.28);color:inherit;border-radius:3px;padding:0 2px;font-weight:600}
table{width:100%;border-collapse:collapse;font-size:13.5px;margin-top:8px}
td,th{text-align:left;padding:7px 8px;border-bottom:1px solid var(--line);vertical-align:top}
th{color:var(--dim);font-weight:500;font-size:11.5px;text-transform:uppercase}
.nav{display:flex;gap:6px}
.nav button{background:transparent;color:var(--dim);border:1px solid transparent;
padding:6px 12px;font-size:13.5px;font-weight:500}
.nav button.on{color:var(--fg);border-color:var(--line);background:var(--bg)}
.view{display:none}.view.on{display:block}
.bad{border-left:3px solid var(--bad);padding:10px 12px;
background:rgba(248,113,113,.08);border-radius:0 8px 8px 0;margin:8px 0}
.warnbox{border-left:3px solid var(--warn);padding:10px 12px;
background:rgba(251,191,36,.08);border-radius:0 8px 8px 0;margin:8px 0}
.spin{color:var(--dim);font-size:13px}
/* ---- inbox (redesigned) ---- */
.stats{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:14px;margin-bottom:16px}
.stat{background:var(--panel);border:1px solid var(--line);border-radius:12px;padding:14px 16px}
/* The Board emits .sv/.sk where the Inbox emits .n/.k. Without these rules the
   five signal tiles rendered as unstyled body text — a dashboard whose numbers
   do not look like numbers. */
.stat .sv{font-size:24px;font-weight:700;line-height:1.15}
.stat .sk{font-size:12px;color:var(--dim);margin-top:2px}
.stat .n{font-size:24px;font-weight:700;letter-spacing:-.01em}
.stat .k{font-size:12px;color:var(--dim);margin-top:2px}
.stat.alert .n{color:#b45309}
@media(prefers-color-scheme:dark){.stat.alert .n{color:#fbbf24}}
/* The two columns scroll INDEPENDENTLY. Previously this was a plain grid with
   align-items:start and no height, so the PAGE scrolled and both columns moved
   together: reading down a long transcript dragged the queue off screen, and an
   agent could not watch the queue while answering. Giving .ibx a bounded height
   and each pane its own overflow is the whole fix; the card labels stay put
   because they are flex items outside the scroller. */
.ibx{display:grid;grid-template-columns:minmax(0,1.15fr) minmax(0,1fr);gap:16px;
align-items:stretch;height:clamp(440px,calc(100vh - 250px),860px)}
.ibx>.card{display:flex;flex-direction:column;min-height:0;overflow:hidden}
.ibx>.card>label,.ibx>.card>.sub{flex:none}
#queue,#thread{flex:1 1 auto;min-height:0;overflow-y:auto;scrollbar-gutter:stable;
/* contain: reaching the end of a pane must not start scrolling the page behind it */
overscroll-behavior:contain}
@media(max-width:900px){.ibx{grid-template-columns:1fr;height:auto}
.stats{grid-template-columns:repeat(2,1fr)}
/* stacked on a phone, a viewport-tall pane would hide the other one entirely */
#queue,#thread{max-height:68vh}}
tr.waitrow{background:rgba(251,191,36,.07)}
.vis{font-weight:600}
.snip{color:var(--dim);font-size:12.5px;margin-top:2px;max-width:320px;overflow:hidden;
text-overflow:ellipsis;white-space:nowrap}
.why{color:var(--dim);font-size:12px;margin-top:3px;font-style:italic}
.sent{display:inline-flex;align-items:center;gap:6px;font-size:12.5px;white-space:nowrap}
.sd{width:7px;height:7px;border-radius:50%;display:inline-block}
.sd.neg{background:var(--bad)}.sd.neu{background:var(--dim)}.sd.pos{background:var(--ok)}
/* hollow, not grey: 'nobody measured this' must not look like 'measured, calm' */
.sd.unk{background:transparent;border:1px solid var(--dim)}
.age{font-variant-numeric:tabular-nums;font-size:13px}
.age.over{color:#b45309;font-weight:600}
/* A conversation nobody can answer should not compete for attention with one
   that is still live. Dimmed, not hidden: it is still readable and resolvable. */
.gonerow td{opacity:.62}
@media(prefers-color-scheme:dark){.age.over{color:#fbbf24}}
.turn{display:flex;gap:11px;margin-bottom:14px}
.tav{width:30px;height:30px;border-radius:50%;flex:none;display:flex;align-items:center;
justify-content:center;font-size:11px;font-weight:700}
.tav.v{background:rgba(37,99,235,.12);color:var(--accent)}
.tav.b{background:var(--bot,rgba(110,168,254,.14));color:var(--accent)}
.tav.h{background:rgba(23,114,69,.14);color:#2f9e69}
.tbody{flex:1;min-width:0}
.tnm{font-size:12px;color:var(--dim);margin-bottom:4px;display:flex;align-items:center;gap:7px}
.tts{margin-left:auto;font-variant-numeric:tabular-nums;font-size:11.5px;color:var(--dim);
flex:none;cursor:help}
.daysep{display:flex;align-items:center;gap:10px;margin:16px 0 12px;
font-size:11px;text-transform:uppercase;letter-spacing:.06em;color:var(--dim)}
.daysep::before,.daysep::after{content:"";flex:1;height:1px;background:var(--line)}
.tag{font-size:10px;text-transform:uppercase;letter-spacing:.04em;font-weight:700;
padding:1px 6px;border-radius:999px}
.tag.ai{background:rgba(110,168,254,.16);color:var(--accent)}
.tag.hu{background:rgba(23,114,69,.16);color:#2f9e69}
.ttxt{font-size:14px;line-height:1.55;white-space:pre-wrap}
.tnote{color:var(--dim);font-size:11.5px;line-height:1.5;margin-top:5px}
.sysline{text-align:center;color:var(--dim);font-size:12px;padding:4px 0 12px}
.sec{border:1px solid var(--line);border-radius:10px;padding:13px;margin-bottom:14px}
.sl{font-size:11px;text-transform:uppercase;letter-spacing:.06em;color:var(--dim);
font-weight:600;margin-bottom:9px}
.kv{display:flex;justify-content:space-between;font-size:13px;padding:4px 0}
.kv span{color:var(--dim)}
.whybox{background:rgba(251,191,36,.10);border:1px solid rgba(251,191,36,.35);border-radius:9px;
padding:10px 12px;font-size:12.5px;line-height:1.5}
.src{font-size:12.5px;padding:6px 0;border-bottom:1px solid var(--line);display:flex;
justify-content:space-between;gap:8px}
.src:last-child{border-bottom:0}
.src em{color:var(--dim);font-style:normal;font-size:11.5px}
.emptybox{text-align:center;padding:38px 24px;color:var(--dim)}
.emptybox .t{font-weight:600;font-size:14px;color:var(--fg);margin:10px 0 4px}
.emptybox .d{font-size:12.5px;line-height:1.5;max-width:270px;margin:0 auto}


/* ======================================================================
   INSTRUMENTS
   A gauge is honest where there is a scale with a known bad end. On this desk
   there are two — a wait against the tenant's SLA and spend against budget —
   so everything else is a meter, a sparkline or a stacked bar. The panel reads
   like a cockpit because the numbers are laid out like one, not because every
   number was given a dial.
   ====================================================================== */
.inst{background:var(--panel);border:1px solid var(--line);border-radius:12px;
padding:12px 14px;min-width:0;display:flex;flex-direction:column;gap:7px}
.inst .c-label{font-size:10.5px;text-transform:uppercase;letter-spacing:.07em;
color:var(--dim);font-weight:600;line-height:1.3}
.inst .c-body{display:flex;flex-direction:column;gap:6px;min-width:0}
/* An instrument with nothing to say says so, and says why. It never draws a
   zero: zero is a reading. */
.inst .c-refusal{font-size:12px;color:var(--dim);line-height:1.45;
border-left:2px dashed var(--line);padding-left:9px;font-style:italic}
.inst .c-big{font-size:27px;font-weight:700;letter-spacing:-.02em;
font-variant-numeric:tabular-nums;line-height:1.05}
.inst .c-sub{font-size:11.5px;color:var(--dim);font-variant-numeric:tabular-nums}
.inst.c-ok .c-big{color:var(--ok)}
.inst.c-warn .c-big{color:var(--warn)}
.inst.c-bad .c-big{color:var(--bad)}
.inst .c-svg{width:100%;height:26px;display:block}
.inst .c-track{fill:var(--line)}
.inst .c-fill{fill:var(--accent)}
.inst .c-fill.s-ok{fill:var(--ok)}
.inst .c-fill.s-warn{fill:var(--warn)}
.inst .c-fill.s-bad{fill:var(--bad)}
.inst .c-mark{stroke:var(--fg);stroke-width:1.5;opacity:.55}
.inst .c-val{font-size:15px;font-weight:600;font-variant-numeric:tabular-nums}
.inst .c-gsvg{width:118px;height:74px;display:block;margin:0 auto}
.inst .c-gtrack{stroke:var(--line);stroke-width:11;stroke-linecap:round}
.inst .c-gfill{stroke:var(--accent);stroke-width:11;stroke-linecap:round}
.inst .c-gfill.s-ok{stroke:var(--ok)}
.inst .c-gfill.s-warn{stroke:var(--warn)}
.inst .c-gfill.s-bad{stroke:var(--bad)}
.inst .c-gval{text-align:center;font-size:19px;font-weight:700;margin-top:-20px;
font-variant-numeric:tabular-nums}
.inst .c-line{stroke:var(--accent);stroke-width:2;stroke-linejoin:round;stroke-linecap:round}
.inst .c-dot{fill:var(--accent)}
.inst .c-dot.s-bad{fill:var(--bad)}
.inst .c-dot.s-warn{fill:var(--warn)}
.inst .c-dot.s-ok{fill:var(--ok)}
/* A turn nobody measured is a hollow ring on the baseline, never a point on the
   line. The line is only drawn between readings that exist. */
.inst .c-dot.s-gap{fill:none;stroke:var(--dim);stroke-width:1;stroke-dasharray:1.5 1.5}
.inst .c-cap{font-size:11.5px;color:var(--dim);line-height:1.4}
.inst .c-bar{display:flex;height:12px;border-radius:6px;overflow:hidden;background:var(--line)}
.inst .c-bar i{display:block;min-width:2px}
.inst .c-legend{display:flex;flex-wrap:wrap;gap:4px 13px;font-size:11.5px;color:var(--dim)}
.inst .c-legend i{display:inline-block;width:8px;height:8px;border-radius:2px;margin-right:5px}
.inst .c-legend b{color:var(--fg);font-variant-numeric:tabular-nums}
.s-n{background:var(--accent)}.s-ok{background:var(--ok)}
.s-warn{background:var(--warn)}.s-bad{background:var(--bad)}
.s-mute{background:var(--dim);opacity:.45}

/* ---- the cockpit ---------------------------------------------------- */
.cock{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:13px;margin-bottom:16px}
.cock.two{grid-template-columns:repeat(2,minmax(0,1fr))}
.cock .wide{grid-column:span 2}
.bandhead{display:flex;align-items:baseline;gap:12px;margin:22px 0 11px}
.bandhead h2{margin:0;font-size:14.5px}
.bandhead .hint{font-size:12px;color:var(--dim)}
.bandhead .spacer{margin-left:auto}
@media(max-width:1100px){.cock{grid-template-columns:repeat(2,minmax(0,1fr))}}
@media(max-width:620px){.cock,.cock.two{grid-template-columns:1fr}.cock .wide{grid-column:auto}}

/* ---- the conversation workspace -------------------------------------
   Three panes, each its own scroll container, extending the rule `.ibx` already
   established: without a bounded height the PAGE scrolls and reading a long
   transcript drags the queue off screen. */
.wsp{display:grid;grid-template-columns:322px minmax(0,1fr) 340px;gap:14px;
align-items:stretch;
/* Sized from the pane's MEASURED top, not a constant. The 210px this replaced was
   chosen before the headline tiles sat above the workspace, so the card ran ~107px
   past the bottom of a 900px window: the page scrolled, and the compose dock —
   pinned to the bottom of a card that extends past the fold — went with it. The
   tiles can also be hushed with the queue, so the offset is not one number.
   `--wsp-h` is set by `fitWorkspace()` on layout and on resize; the clamp is the
   fallback for the moment before the first measurement. */
height:var(--wsp-h, clamp(460px,calc(100vh - 210px),920px))}
.wsp>.card{display:flex;flex-direction:column;min-height:0;overflow:hidden}
.wsp>.card>label,.wsp>.card>.sub,.wsp>.card>.wshead{flex:none}
.wsp .scroll{flex:1 1 auto;min-height:0;overflow-y:auto;scrollbar-gutter:stable;
overscroll-behavior:contain}
/* THE ORDER IN WHICH THE THREE BANDS GIVE UP SPACE, which is the whole of this
   layout. The assist panel yields first (capped at 30% of the pane); then the
   dock, which scrolls inside its own cap; and the transcript last, down to a
   floor of a few lines. Getting this order wrong in either direction has already
   produced both failures available here: no floor and the conversation vanishes,
   a floor with nothing else capped and the reply box is pushed off the window.

   The caps are `min(percentage, pixels)` rather than percentages alone. With a
   bare percentage the panel and the dock grew in step with the pane, so hiding
   the queue — which hands the workspace about a hundred more pixels — gave the
   transcript only forty of them. The other two need a fixed amount; everything
   spare belongs to the conversation. */
.wsp #thread{min-height:96px}
/* The rail collapses to a drawer rather than stacking: stacked, it puts the
   instruments an agent needs in the first five seconds below a transcript that
   can be a hundred turns long. */
@media(max-width:1279px){.wsp{grid-template-columns:280px minmax(0,1fr)}
.wsp .rail{position:fixed;top:0;right:0;bottom:0;width:340px;z-index:40;
border-radius:0;box-shadow:-18px 0 40px rgba(0,0,0,.28);transform:translateX(102%);
transition:transform .16s ease-out}
.wsp .rail.open{transform:none}
#raildrawer{display:inline-flex}}
@media(min-width:1280px){#raildrawer{display:none}}
@media(max-width:900px){.wsp{grid-template-columns:1fr;height:auto;--wsp-h:auto}
.wsp .scroll{max-height:64vh}}

/* ---- the rail: stacked and collapsible, never tabbed ------------------
   Tabs would hide "why you have this" and the three instruments behind a click
   for anyone who last opened the activity trail. Stacking keeps the first-five-
   seconds content unconditionally visible and lets the rest fold away. */
.rsec{border-bottom:1px solid var(--line)}
.rsec:last-child{border-bottom:0}
.rsec>summary{list-style:none;cursor:pointer;padding:11px 14px;display:flex;
align-items:center;gap:8px;font-size:11px;text-transform:uppercase;
letter-spacing:.06em;color:var(--dim);font-weight:600;user-select:none}
.rsec>summary::-webkit-details-marker{display:none}
.rsec>summary::before{content:"";width:5px;height:5px;border-right:1.5px solid currentColor;
border-bottom:1.5px solid currentColor;transform:rotate(-45deg);transition:transform .12s;
flex:none;margin-right:2px}
.rsec[open]>summary::before{transform:rotate(45deg)}
.rsec>summary:hover{color:var(--fg)}
.rsec .rbody{padding:0 14px 14px}
.rsec .count{margin-left:auto;font-size:10.5px;color:var(--dim);font-weight:600;
background:var(--bg);border:1px solid var(--line);border-radius:999px;padding:1px 7px}
.rgrid{display:grid;grid-template-columns:1fr 1fr;gap:10px}
.rgrid .inst{padding:10px 11px}
.rgrid .full{grid-column:1/-1}
.jump{background:none;border:0;color:var(--accent);cursor:pointer;padding:0;
font:inherit;font-size:12.5px;text-align:left}
.jump:hover{text-decoration:underline}

/* ---- the timeline strip ---------------------------------------------- */
.tl{display:flex;align-items:center;gap:0;padding:9px 14px;border-bottom:1px solid var(--line);
overflow-x:auto;scrollbar-width:thin}
.tl .tick{flex:none;display:flex;flex-direction:column;align-items:center;gap:4px;
padding:0 9px;cursor:pointer;background:none;border:0;color:var(--dim);font:inherit;
min-width:58px;position:relative}
.tl .tick::after{content:"";position:absolute;left:50%;right:-50%;top:5px;height:1px;
background:var(--line);z-index:0}
.tl .tick:last-child::after{display:none}
.tl .tick i{width:9px;height:9px;border-radius:50%;background:var(--line);z-index:1;
border:2px solid var(--panel);box-sizing:content-box}
.tl .tick.k-escalation_requested i,.tl .tick.k-abstained i{background:var(--warn)}
.tl .tick.k-out_of_domain i,.tl .tick.k-sla i{background:var(--bad)}
.tl .tick.k-resolved i,.tl .tick.k-accepted i{background:var(--ok)}
.tl .tick.k-agent_active i{background:var(--accent)}
.tl .tick span{font-size:10px;white-space:nowrap;max-width:88px;overflow:hidden;
text-overflow:ellipsis}
.tl .tick:hover{color:var(--fg)}
.tl .empty{font-size:11.5px;color:var(--dim);font-style:italic}

/* ---- workspace header and segments ----------------------------------- */
.wshead{padding:12px 15px;border-bottom:1px solid var(--line);display:flex;
align-items:center;gap:11px;flex-wrap:wrap}
.wshead .who{font-weight:600;font-size:14.5px}
.wshead .meta{color:var(--dim);font-size:12.5px}
.wshead .spacer{margin-left:auto;display:flex;gap:7px;align-items:center}
.segs{display:flex;gap:6px;padding:11px 13px 0}
.segs button{background:var(--bg);border:1px solid var(--line);color:var(--dim);
border-radius:999px;padding:5px 12px;font-size:12.5px;cursor:pointer;font-weight:500}
.segs button.on{background:var(--accent);border-color:var(--accent);color:#0b0e14;font-weight:600}
.segs button .n{opacity:.75;margin-left:5px;font-variant-numeric:tabular-nums}
@media(prefers-color-scheme:light){.segs button.on{color:#fff}}
/* Why a row is worth looking at, stated on the row rather than folded into a
   score nobody can argue with. */
.chips{display:flex;flex-wrap:wrap;gap:4px;margin-top:3px}
.chips i{font-style:normal;font-size:10.5px;border-radius:999px;padding:1px 7px;
border:1px solid var(--line);color:var(--dim);background:var(--bg)}
.chips i.hot{border-color:var(--bad);color:var(--bad)}
.chips i.warm{border-color:var(--warn);color:var(--warn)}

/* ---- navigation: two groups, one row -------------------------------- */
.nav{display:flex;align-items:center;gap:5px;flex-wrap:wrap}
.navgrp{font-size:9.5px;text-transform:uppercase;letter-spacing:.09em;color:var(--dim);
font-weight:700;opacity:.7;margin:0 3px 0 0;user-select:none}
.navsep{width:1px;height:17px;background:var(--line);margin:0 7px}
/* The set-up destinations are still one click away; they are just no longer
   competing for attention with the queue. */
.nav button.sm{font-size:12px;padding:4px 9px;opacity:.72}
.nav button.sm:hover,.nav button.sm.on{opacity:1}
@media(max-width:820px){.navgrp,.navsep{display:none}}
/* A jumped-to message announces itself briefly. Long enough to find, short
   enough not to become part of the reading. */
.flash{animation:sbflash 1.2s ease-out}
@keyframes sbflash{from{background:rgba(110,168,254,.22)}to{background:transparent}}
@media(prefers-reduced-motion:reduce){.flash{animation:none;outline:2px solid var(--accent)}}

/* ---- nav: one line at desk width -------------------------------------
   Wrapping to a second row put "Widget Studio" on its own line under the work
   destinations, which reads as a third group nobody designed. The set-up
   buttons are the ones that give up space: they are visited by a manager once a
   week, not by an agent every few minutes. */
.nav{flex-wrap:nowrap;overflow-x:auto;scrollbar-width:none}
.nav::-webkit-scrollbar{display:none}
.nav button{white-space:nowrap}
.nav button.sm{padding:4px 7px;font-size:11.5px}
@media(max-width:1180px){.nav button.sm{padding:4px 6px;font-size:11px}}
@media(max-width:820px){.nav{flex-wrap:wrap}}

/* The rail is a column at desk width and a drawer below it, so the control that
   dismisses a drawer has no meaning on the column. */
@media(min-width:1280px){#railclose{display:none}}

/* ---- the queue in a 320px column ------------------------------------
   The queue table was designed for a pane half the page wide. In a workspace
   column the same four columns wrap every visitor name onto three lines. Status
   and mood move under the name, where they read as attributes of the row rather
   than as columns fighting for width. */
.wsp .qt{table-layout:fixed;width:100%}
.wsp .snip{max-width:none;white-space:normal}

/* The queue's header row is a <tr><th> inside <tbody>, so `thead` never matched
   it. In a 322px column those four headings and their columns cannot coexist. */
.wsp .qt th{display:none}
/* One row, three areas: who and why on top, then the wait and the action on one
   line beneath. Stacking all three made every row about 90px tall, so four
   conversations filled the column. */
/* Two lines, nothing dropped. The first CSS pass hid the status and mood cells
   to make the row fit, which is not de-crowding — status and mood are the two
   things an agent scans a queue FOR, and "Visitor left" is the difference
   between a conversation worth opening and one nobody can answer. They move
   under the name instead, where they read as attributes of the row rather than
   as columns competing for 320px. */
.wsp .qt tr{display:flex;flex-wrap:wrap;align-items:center;gap:0 9px;
border-bottom:1px solid var(--line);padding-bottom:9px}
.wsp .qt tr:last-child{border-bottom:0}
.wsp .qt td{display:block;padding:0}
.wsp .qt td.q-vis{flex:0 0 100%;padding:10px 12px 4px}
.wsp .qt td.q-status{padding-left:12px}
.wsp .qt td.q-age{font-size:11.5px;color:var(--dim);white-space:nowrap}
.wsp .qt td.q-act{margin-left:auto;padding-right:12px}
.wsp .qt td.q-act button{white-space:nowrap;background:none;border:0;
color:var(--accent);font:inherit;font-size:12px;padding:0;cursor:pointer}
.wsp .qt td.q-act button:hover{text-decoration:underline}
.wsp .snip{max-width:none;white-space:normal}

/* ---- putting the queue away -----------------------------------------
   Reported by the owner: the queue beside an open conversation takes an agent's
   attention and pushes them to answer quickly because other people are visibly
   waiting. The depth is real and an agent mid-reply cannot act on it, so the
   only thing it can change is the quality of the reply they are writing. */
.qcol{position:relative}
.qcol .qhead{display:flex;justify-content:flex-end;padding:9px 10px 0;flex:none}
.qcol .qt-show{display:none;font-size:15px;line-height:1}
.qstrip{display:none}

.wsp.qtucked{grid-template-columns:46px minmax(0,1fr) 340px}
.wsp.qtucked .qcol .qbody{display:none}
.wsp.qtucked .qcol .qhead{justify-content:center;padding:9px 0 0}
.wsp.qtucked .qcol .qt-hide{display:none}
.wsp.qtucked .qcol .qt-show{display:inline}
.wsp.qtucked #qtoggle{padding:5px 8px}
/* Vertical, because 46px is not a label's worth of width and the alternative is
   an icon nobody can read on their first day. */
.wsp.qtucked .qstrip{display:flex;flex-direction:column;align-items:center;
gap:11px;padding:13px 0;flex:1 1 auto;min-height:0}
.qstrip .qs-label{writing-mode:vertical-rl;text-orientation:mixed;font-size:11px;
text-transform:uppercase;letter-spacing:.1em;color:var(--dim);font-weight:600;
user-select:none}
/* The one thing allowed through. Not a count — a state. */
.qstrip .qs-late{writing-mode:vertical-rl;text-orientation:mixed;font-size:10.5px;
text-transform:uppercase;letter-spacing:.09em;font-weight:700;color:var(--bad);
background:rgba(248,113,113,.12);border:1px solid rgba(248,113,113,.4);
border-radius:999px;padding:9px 3px;cursor:pointer}
.qstrip .qs-late:hover{background:rgba(248,113,113,.2)}

@media(max-width:1279px){.wsp.qtucked{grid-template-columns:46px minmax(0,1fr)}}
@media(max-width:900px){.wsp.qtucked{grid-template-columns:1fr}
.wsp.qtucked .qcol .qbody{display:block}
.wsp.qtucked .qstrip{display:none}
.wsp.qtucked .qcol .qt-hide{display:inline}
.wsp.qtucked .qcol .qt-show{display:none}}

/* The headline tiles go with the queue. Same fact, louder, equally unactionable
   mid-reply — and hiding them hands another ~100px of height to the transcript,
   which is the point of the gesture rather than a side effect. */
#v-inbox.qhushed #inboxstats{display:none}

/* ---- the compose dock ------------------------------------------------
   A flex row that does not grow, sitting after the scroller that does. The
   transcript keeps its own scrollbar and the reply box keeps its place. */
.dock{flex:none;border-top:1px solid var(--line);padding:0 15px 13px;
background:var(--panel);max-height:min(46%,260px);overflow-y:auto;
overscroll-behavior:contain}
.dock:empty{display:none;border-top:0;padding:0}
/* The action row is the first thing in the dock and needs no extra gap above it;
   the rule inside `composeBlockHTML` assumes it is following a transcript. */
.dock>div:first-child{margin-top:11px!important}
.dock textarea{width:100%;min-height:74px}
/* A long assist result must not push Send off the bottom of the pane. */
.dock #sugout{max-height:22vh;overflow-y:auto}
@media(max-width:900px){.dock{max-height:60vh}}

/* A working surface uses the window it is given. The 1100px measure is right for
   reading a settings page and wrong for three panes side by side. */
.wrap.wide{max-width:1600px}

/* The send row on one line. Send is the primary action and keeps its weight; the
   two assists sit beside it rather than under it. */
.dock #composeReply > div:last-child{flex-wrap:nowrap;align-items:center}
.dock #composeReply > div:last-child button{white-space:nowrap}
@media(max-width:1100px){.dock #composeReply > div:last-child{flex-wrap:wrap}}

/* ---- an assist result ------------------------------------------------
   A panel, not a hint and a blob. It sits ABOVE the reply box because it is
   input to the reply; it used to sit below, where a long result pushed the box
   it was meant to improve out of a dock with a bounded height.

   Visually it is deliberately NOT the reply box: tinted, bordered on the leading
   edge, and captioned with where it came from — because the one thing an agent
   must never be unsure of is whether they are reading their own words. */
/* A band of its own: the transcript above it shrinks, the dock below it does not
   move. Capped as a SHARE of the pane rather than in viewport units, because what
   it has to leave room for is the other two bands, not the window. */
.wsp #sugout{flex:none;padding:0 15px;max-height:min(34%,224px);display:flex;
flex-direction:column;min-height:0}
#sugout:empty{display:none}
.assist{border:1px solid var(--line);border-left:3px solid var(--accent);
border-radius:0 10px 10px 0;background:var(--bg);margin:11px 0 0;overflow:hidden;
display:flex;flex-direction:column;min-height:0;flex:1 1 auto}
.assist .ahead,.assist .achanges,.assist .afoot{flex:none}
.assist.k-polish{border-left-color:var(--ok)}
.assist .ahead{display:flex;align-items:baseline;gap:9px;padding:9px 12px 7px;
border-bottom:1px solid var(--line)}
.assist .atag{font-size:10.5px;text-transform:uppercase;letter-spacing:.06em;
font-weight:700;color:var(--accent);white-space:nowrap}
.assist.k-polish .atag{color:#2f9e69}
.assist .anote{font-size:11.5px;color:var(--dim);line-height:1.4;min-width:0}
.assist .axc{margin-left:auto;background:none;border:0;color:var(--dim);
font-size:17px;line-height:1;cursor:pointer;padding:0 2px;flex:none}
.assist .axc:hover{color:var(--fg)}
/* Bounded and scrollable, so no length of result can crowd out the conversation
   it is meant to help answer. */
/* The only scroller in the panel. Head, changes and footer stay put, so "Use
   this" is never the thing that scrolls away. */
.assist .abody{padding:10px 12px;font-size:13.5px;line-height:1.55;
flex:1 1 auto;min-height:40px;overflow-y:auto;overscroll-behavior:contain;
white-space:pre-wrap}
.assist .achanges{margin:0;padding:0 12px 2px 28px;font-size:11.5px;color:var(--dim);
line-height:1.6;max-height:54px;overflow-y:auto}
.assist .afoot{display:flex;align-items:center;gap:10px;padding:9px 12px 11px}
.assist .afoot .hint{font-size:11.5px}

/* ---- speaking instead of typing -------------------------------------
   Interim words get their own line. They must never be written into the field
   somebody is typing in: a string that rewrites itself there destroys the caret
   and the undo stack, and a half-heard phrase is not yet anybody's words. */
.dictline{min-height:0;font-size:12.5px;color:var(--dim);font-style:italic;
line-height:1.5;padding:0 2px}
.dictline:not(:empty){margin-top:6px}
#adictate.listening{background:var(--bad);border-color:var(--bad);color:#fff;
font-weight:600}
#adictate.listening::before{content:"";display:inline-block;width:7px;height:7px;
border-radius:50%;background:#fff;margin-right:6px;vertical-align:baseline;
animation:sbpulse 1.1s ease-in-out infinite}
@keyframes sbpulse{0%,100%{opacity:1}50%{opacity:.25}}
@media(prefers-reduced-motion:reduce){#adictate.listening::before{animation:none}}
#dictnote:not(:empty){margin-top:6px}

/* A running clock, in tabular figures so it does not jitter as the digits change. */
.kv b.tick{font-variant-numeric:tabular-nums;letter-spacing:.01em}

/* A caveat on a suggestion, not an error. It sits ABOVE the draft rather than
   below it because a warning read after the text has been skimmed has already
   failed. Amber, not red: the draft is usable, it is just built on less.
   `--warn` is theme-independent by design in tokens.css, and it is used here
   only as a rule and a wash — amber text would fail contrast on the light
   panel, so the words are `--fg`. */
.assist .awarn{margin:8px 10px 0;padding:7px 9px;border-left:3px solid var(--warn);
  background:rgba(251,191,36,.10);border-radius:0 4px 4px 0;font-size:12px;
  line-height:1.45;color:var(--fg)}

/* ======================================================================
   BRAND LAYER — SenseBridge identity (logo/ palette, tokens.css).

   Appended LAST and written as overrides on purpose: every selector above is
   still the contract the browser gates click through (`data-v`, ids, classes),
   so the redesign changes how those elements look and where they sit, never
   what they are. Remove this block and the console is exactly what it was.
   ====================================================================== */
html{-webkit-text-size-adjust:100%}
body{font-family:var(--font);font-size:14.5px;line-height:1.55;letter-spacing:-.003em;
  background:var(--bg);-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;
  font-feature-settings:"cv11","ss01"}
::selection{background:color-mix(in srgb,var(--azure) 28%,transparent)}
a{color:var(--accent)} a:hover{color:var(--accent-ink)}
:focus-visible{outline:none;box-shadow:var(--ring);border-radius:8px}

/* ---------------------------------------------------------- typography */
h2{font-size:21px;font-weight:700;letter-spacing:-.018em;color:var(--fg);margin:0 0 4px}
.wrap>.view>h2:first-child,.view>h2:first-child{font-size:24px}
.sub{color:var(--dim);font-size:13.5px;max-width:78ch}
label{font-size:11.5px;font-weight:650;letter-spacing:.07em;color:var(--dim)}
.stat .n,.stat .sv,.inst .c-big,.inst .c-val,.inst .c-gval{font-variant-numeric:tabular-nums}

/* ---------------------------------------------------------- surfaces */
.card{border-radius:var(--radius);border:1px solid var(--line);background:var(--panel);
  box-shadow:var(--shadow-1);padding:20px 22px}
.card:hover{box-shadow:var(--shadow-2)}
.stats{gap:16px}
.stat{position:relative;overflow:hidden;border-radius:var(--radius);border:1px solid var(--line);
  background:var(--panel);box-shadow:var(--shadow-1);padding:18px 20px 16px}
.stat::before{content:"";position:absolute;inset:0 0 auto 0;height:3px;background:var(--grad-warm)}
.stat .n,.stat .sv{font-size:30px;font-weight:750;letter-spacing:-.03em;color:var(--fg);line-height:1.15}
.stat .k,.stat .sk{color:var(--dim);font-size:12.5px;font-weight:500;margin-top:4px}
.stat.alert::before{background:linear-gradient(90deg,var(--orange),var(--amber))}
.inst{border-radius:var(--radius)!important;box-shadow:var(--shadow-1)}

/* ---------------------------------------------------------- controls */
button{background:var(--primary);color:var(--on-primary);border-radius:10px;
  padding:9px 16px;font-weight:600;font-size:13.5px;letter-spacing:-.005em;
  box-shadow:0 1px 2px rgba(6,32,79,.18),inset 0 1px 0 rgba(255,255,255,.12);
  transition:background .15s,box-shadow .15s,transform .05s,border-color .15s,color .15s}
button:hover:not(:disabled){background:var(--primary-hover)}
button:active:not(:disabled){transform:translateY(1px)}
button.ghost{background:var(--panel);color:var(--fg);border:1px solid var(--line-2);box-shadow:var(--shadow-1)}
button.ghost:hover:not(:disabled){background:var(--panel-2);border-color:var(--accent)}
button.sm{padding:6px 12px;font-size:12.5px;border-radius:8px}
button.danger{background:var(--bad)}
select,input,textarea{background:var(--panel);border:1px solid var(--line-2);border-radius:10px;
  padding:10px 12px;color:var(--fg);transition:border-color .15s,box-shadow .15s}
select:hover,input:hover,textarea:hover{border-color:color-mix(in srgb,var(--accent) 45%,var(--line-2))}
select:focus,input:focus,textarea:focus{outline:none;border-color:var(--accent);box-shadow:var(--ring)}
input::placeholder,textarea::placeholder{color:var(--faint)}
input[type=checkbox],input[type=radio]{accent-color:var(--primary)}

/* ---------------------------------------------------------- pills & notes */
.pill{font-weight:600;font-size:11px;letter-spacing:.01em;padding:2px 9px}
.pill.ok{background:var(--ok-soft);color:var(--ok)}
.pill.warn{background:var(--warn-soft);color:var(--warn)}
.pill.bad{background:var(--bad-soft);color:var(--bad)}
.pill.dim{background:var(--panel-2);color:var(--dim);border:1px solid var(--line)}
.cite{border-left-color:var(--azure);background:var(--accent-soft)}
.cite b{color:var(--accent-ink)}
.md sup.cn{background:var(--grad)}
.bad{background:var(--bad-soft)} .warnbox{background:var(--warn-soft)}
mark{background:color-mix(in srgb,var(--amber) 32%,transparent)}

/* ---------------------------------------------------------- tables */
table{font-size:13.5px}
th{background:var(--panel-2);color:var(--dim);font-weight:650;font-size:11px;letter-spacing:.06em}
th:first-child{border-top-left-radius:8px} th:last-child{border-top-right-radius:8px}
td,th{padding:9px 10px;border-bottom-color:var(--line)}
tbody tr:hover td{background:color-mix(in srgb,var(--accent-soft) 60%,transparent)}

/* ---------------------------------------------------------- brand block */
.brand{display:grid;grid-template-columns:auto 1fr;align-items:center;column-gap:11px;row-gap:3px;
  font-weight:700;margin-right:auto;min-width:0}
.brand .brandmark{grid-row:1 / span 2}
.brand span.wordmark{font-size:20px;margin:0;color:inherit;align-self:end}
.brand #whoami:empty{display:none}
.brand .brandmark:only-of-type{grid-row:auto}
.brandmark{width:34px;height:34px;flex:0 0 auto;filter:drop-shadow(0 2px 6px rgba(10,132,232,.35))}
.wordmark{font-size:19px;letter-spacing:-.025em;line-height:1;white-space:nowrap}
.wordmark b{font-weight:800;color:var(--navy)}
.wordmark i{font-style:normal;font-weight:800;background:linear-gradient(90deg,#0B63CE,#0A84E8 55%,#14B8B0);
  -webkit-background-clip:text;background-clip:text;color:transparent}
.brand #whoami{display:block;font-size:11.5px;font-weight:500;color:var(--dim);margin:0;align-self:start;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;min-width:0}

/* ---------------------------------------------------------- nav icons */
.nav button::before,#studiolink::before,#logout::before,#alertbtn::before{content:"";
  width:18px;height:18px;flex:0 0 auto;background:currentColor;
  -webkit-mask:var(--ico) center/contain no-repeat;mask:var(--ico) center/contain no-repeat}
.nav button,#logout,#alertbtn{display:inline-flex;align-items:center;gap:10px}
.nav button .pill{margin:0 0 0 auto}

/* ---------------------------------------------------------- signed-out */
body:not(.authed) .top{display:none}
body:not(.authed) .wrap{max-width:none;padding:0;margin:0}
#v-login.on{display:block}
.auth{min-height:100vh;display:grid;grid-template-columns:minmax(380px,46%) 1fr}
.auth-hero{position:relative;overflow:hidden;color:#EAF1FC;padding:48px 56px;display:flex;
  flex-direction:column;gap:40px;
  background:radial-gradient(1200px 600px at -10% 110%,rgba(242,113,28,.28),transparent 55%),
             radial-gradient(900px 600px at 110% -10%,rgba(20,184,176,.30),transparent 55%),
             linear-gradient(160deg,#06204F 0%,#0A2E6E 55%,#0B4FA8 100%)}
.auth-hero::after{content:"";position:absolute;right:-180px;bottom:-180px;width:560px;height:560px;
  border-radius:50%;border:1px solid rgba(255,255,255,.08);box-shadow:0 0 0 70px rgba(255,255,255,.025),
  0 0 0 140px rgba(255,255,255,.02)}
.auth-logo{width:300px;height:auto;max-width:100%}
.auth-copy{margin-top:auto;position:relative;z-index:1}
.auth-kicker{text-transform:uppercase;letter-spacing:.14em;font-size:12px;font-weight:700;color:#7FD8D2}
.auth-title{font-size:38px;line-height:1.12;font-weight:800;letter-spacing:-.03em;margin:12px 0 24px;color:#fff}
.auth-points{list-style:none;padding:0;margin:0;display:grid;gap:14px;max-width:460px}
.auth-points li{position:relative;padding-left:30px;color:#C9D7EE;font-size:15px}
.auth-points li::before{content:"";position:absolute;left:0;top:3px;width:18px;height:18px;border-radius:50%;
  background:linear-gradient(135deg,#14B8B0,#0A84E8);box-shadow:0 0 0 4px rgba(20,184,176,.15)}
.auth-points li::after{content:"";position:absolute;left:5px;top:8px;width:7px;height:4px;
  border-left:2px solid #fff;border-bottom:2px solid #fff;transform:rotate(-45deg)}
.auth-points b{color:#fff;font-weight:650}
.auth-foot{font-size:12px;color:#8FA3C7;position:relative;z-index:1}
.auth-main{display:flex;flex-direction:column;justify-content:center;padding:48px clamp(24px,6vw,96px);
  max-width:620px;width:100%;margin:0 auto}
.auth-main h2{font-size:28px;letter-spacing:-.03em}
.auth-main .card{max-width:none!important;box-shadow:var(--shadow-2);padding:24px}
.auth-main #lgo{width:100%;padding:12px;font-size:14.5px;background:var(--grad);border-radius:11px}
.auth-main #lgo:hover{filter:brightness(1.06)}
.auth-main .creds button{border-radius:999px}
.auth-logo-sm{display:none;width:200px;height:auto;margin-bottom:24px}
@media(prefers-color-scheme:dark){.auth-logo-sm{content:url(/static/brand/logo-dark.png)}}
@media(max-width:900px){
  .auth{grid-template-columns:1fr}
  .auth-hero{display:none}
  .auth-logo-sm{display:block}
  .auth-main{padding:32px 20px;justify-content:flex-start}
}

/* ---------------------------------------------------------- signed-in shell */
@media(min-width:1024px){
  body.authed .top{position:fixed;inset:0 auto 0 0;width:256px;z-index:50;border:0;
    background:linear-gradient(180deg,var(--side) 0%,var(--side-2) 100%);color:var(--side-fg);
    box-shadow:inset -1px 0 0 rgba(255,255,255,.06)}
  body.authed .topin{max-width:none;height:100%;margin:0;padding:18px 12px 14px;flex-direction:column;
    align-items:stretch;flex-wrap:nowrap;gap:8px}
  body.authed .brand{order:0;padding:4px 8px 14px;margin:0 0 4px;
    border-bottom:1px solid rgba(255,255,255,.08)}
  body.authed .wordmark b{color:#fff}
  body.authed .brand #whoami{color:var(--side-dim)}
  body.authed .nav{order:1;flex:1 1 auto;flex-direction:column;align-items:stretch;gap:2px;
    overflow-y:auto;overflow-x:hidden;flex-wrap:nowrap;padding:4px 0;margin:0;scrollbar-width:thin}
  body.authed .nav .navgrp{display:block;color:var(--side-dim);font-size:10.5px;font-weight:700;
    letter-spacing:.14em;text-transform:uppercase;padding:14px 12px 6px;margin:0}
  body.authed .nav .navsep{display:none}
  body.authed .nav button,body.authed .nav button.sm,body.authed #studiolink{
    width:100%;justify-content:flex-start;background:transparent;color:var(--side-fg);
    border:0;border-radius:9px;padding:9px 12px;font-size:13.5px;font-weight:550;box-shadow:none;
    text-align:left;opacity:.86}
  body.authed .nav button:hover,body.authed #studiolink:hover{background:var(--side-hover);opacity:1}
  body.authed .nav button.on{background:var(--side-on);color:#fff;opacity:1;
    box-shadow:inset 3px 0 0 #0A84E8}
  body.authed .nav button.on::before{background:#7CC4FF}
  body.authed .nav button .pill{background:rgba(247,168,35,.18);color:#FFC565;border:0}
  body.authed .nav button .pill.dim{background:rgba(255,255,255,.08);color:var(--side-fg)}
  body.authed #signedin{order:2;margin-top:6px;align-self:stretch;text-align:left;
    background:rgba(255,255,255,.06);color:var(--side-fg);border:1px solid rgba(255,255,255,.08);
    border-radius:10px;padding:8px 12px;font-size:12px;font-weight:600;white-space:normal}
  body.authed #alertbtn,body.authed #logout{order:3;width:100%;justify-content:flex-start;
    background:transparent;color:var(--side-dim);border:0;box-shadow:none;padding:8px 12px;font-weight:550}
  body.authed #alertbtn:hover,body.authed #logout:hover{background:var(--side-hover);color:#fff}
  body.authed .wrap{margin-left:256px;max-width:none;padding:32px 36px 72px}
  body.authed .wrap>.view{max-width:1480px;margin:0 auto}
}
@media(max-width:1023px){
  body.authed .top{position:sticky;top:0;z-index:50;border:0;
    background:linear-gradient(90deg,var(--side),var(--side-2));color:var(--side-fg)}
  body.authed .topin{max-width:none}
  body.authed .wordmark b{color:#fff}
  body.authed .brand #whoami{color:var(--side-dim)}
  body.authed #signedin{background:rgba(255,255,255,.08);color:var(--side-fg);border-color:transparent}
  body.authed #alertbtn,body.authed #logout{background:rgba(255,255,255,.08);color:#fff;border:0;box-shadow:none}
  body.authed .nav button,body.authed .nav button.sm,body.authed #studiolink{background:transparent;
    color:var(--side-fg);border:0;box-shadow:none;opacity:.85}
  body.authed .nav button.on{background:var(--side-on);color:#fff;opacity:1}
  body.authed .nav .navgrp{color:var(--side-dim)}
  body.authed .wrap{padding:20px 16px 72px}
}
@media(prefers-reduced-motion:reduce){button{transition:none}}
/* ---- nav icon masks (generated; see git history of this block) ---- */
.nav button[data-v="inbox"]{--ico:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M22 12h-6l-2 3h-4l-2-3H2'/%3E%3Cpath d='M5.45 5.11 2 12v6a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2v-6l-3.45-6.89A2 2 0 0 0 16.76 4H7.24a2 2 0 0 0-1.79 1.11z'/%3E%3C/svg%3E")}
.nav button[data-v="assistant"]{--ico:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M12 3l1.9 5.1L19 10l-5.1 1.9L12 17l-1.9-5.1L5 10l5.1-1.9z'/%3E%3Cpath d='M19 15l.8 1.9 1.9.8-1.9.8-.8 1.9-.8-1.9-1.9-.8 1.9-.8z'/%3E%3C/svg%3E")}
.nav button[data-v="tickets"]{--ico:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M3 7a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2v3a2 2 0 0 0 0 4v3a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-3a2 2 0 0 0 0-4z'/%3E%3Cpath d='M13 5v2'/%3E%3Cpath d='M13 11v2'/%3E%3Cpath d='M13 17v2'/%3E%3C/svg%3E")}
.nav button[data-v="cockpit"]{--ico:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M12 14l4-4'/%3E%3Cpath d='M3.34 19a10 10 0 1 1 17.32 0'/%3E%3C/svg%3E")}
.nav button[data-v="desk"]{--ico:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M12 20h9'/%3E%3Cpath d='M16.5 3.5a2.12 2.12 0 0 1 3 3L7 19l-4 1 1-4z'/%3E%3C/svg%3E")}
.nav button[data-v="board"]{--ico:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M4 4h4v16H4z'/%3E%3Cpath d='M10 4h4v10h-4z'/%3E%3Cpath d='M16 4h4v13h-4z'/%3E%3C/svg%3E")}
.nav button[data-v="quality"]{--ico:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z'/%3E%3Cpath d='M9 12l2 2 4-4'/%3E%3C/svg%3E")}
.nav button[data-v="library"]{--ico:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M4 19.5A2.5 2.5 0 0 1 6.5 17H20'/%3E%3Cpath d='M6.5 2H20v20H6.5A2.5 2.5 0 0 1 4 19.5v-15A2.5 2.5 0 0 1 6.5 2z'/%3E%3C/svg%3E")}
.nav button[data-v="glossary"]{--ico:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M5 8l6 6'/%3E%3Cpath d='M4 14l6-6 2-3'/%3E%3Cpath d='M2 5h12'/%3E%3Cpath d='M7 2h1'/%3E%3Cpath d='M22 22l-5-10-5 10'/%3E%3Cpath d='M14 18h6'/%3E%3C/svg%3E")}
.nav button[data-v="ops"]{--ico:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M22 12h-4l-3 9L9 3l-3 9H2'/%3E%3C/svg%3E")}
.nav button[data-v="settings"]{--ico:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M4 21v-7'/%3E%3Cpath d='M4 10V3'/%3E%3Cpath d='M12 21v-9'/%3E%3Cpath d='M12 8V3'/%3E%3Cpath d='M20 21v-5'/%3E%3Cpath d='M20 12V3'/%3E%3Cpath d='M1 14h6'/%3E%3Cpath d='M9 8h6'/%3E%3Cpath d='M17 16h6'/%3E%3C/svg%3E")}
.nav button[data-v="usage"]{--ico:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M3 3v18h18'/%3E%3Cpath d='M8 17v-6'/%3E%3Cpath d='M13 17V7'/%3E%3Cpath d='M18 17v-4'/%3E%3C/svg%3E")}
#studiolink{--ico:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M3 3h18v18H3z'/%3E%3Cpath d='M3 9h18'/%3E%3Cpath d='M9 21V9'/%3E%3C/svg%3E")}
#logout{--ico:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4'/%3E%3Cpath d='M16 17l5-5-5-5'/%3E%3Cpath d='M21 12H9'/%3E%3C/svg%3E")}
#alertbtn{--ico:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 8a6 6 0 0 1 12 0c0 7 3 9 3 9H3s3-2 3-9'/%3E%3Cpath d='M10.3 21a1.94 1.94 0 0 0 3.4 0'/%3E%3C/svg%3E")}/* ---- native file picker, in the button language of the rest of the page ---- */
input[type=file]{padding:8px}
input[type=file]::file-selector-button{font:inherit;font-weight:600;font-size:12.5px;color:var(--fg);
  background:var(--panel-2);border:1px solid var(--line-2);border-radius:8px;padding:6px 12px;
  margin-right:12px;cursor:pointer}
input[type=file]::file-selector-button:hover{border-color:var(--accent)}
/* A destructive action repeated on every row must not shout on every row: it is
   outlined until hovered, and only then takes the full danger fill. */
td button.danger{background:transparent;color:var(--bad);border:1px solid color-mix(in srgb,var(--bad) 40%,transparent);
  box-shadow:none;padding:5px 11px;font-size:12.5px}
td button.danger:hover:not(:disabled){background:var(--bad);color:#fff}
/* ---- small screens: ONE row of swipeable tabs, icon-only account actions.
   The rail's full list wrapped to four rows and took a third of a phone's
   height before any work was visible. ---- */
@media(max-width:1023px){
  body.authed .topin{display:grid;grid-template-columns:1fr auto auto auto;align-items:center;
    gap:8px;padding:10px 14px 0}
  body.authed .brand{grid-column:1}
  body.authed #signedin{display:none}
  body.authed #alertbtn,body.authed #logout{font-size:0;gap:0;padding:8px;border-radius:10px;width:36px;height:36px;
    justify-content:center}
  body.authed .nav{grid-column:1 / -1;display:flex;flex-wrap:nowrap!important;overflow-x:auto;
    gap:4px;margin:4px -14px 0;padding:6px 14px 10px;scrollbar-width:none;-webkit-overflow-scrolling:touch}
  body.authed .nav::-webkit-scrollbar{display:none}
  body.authed .nav .navgrp,body.authed .nav .navsep{display:none}
  body.authed .nav button,body.authed .nav button.sm,body.authed #studiolink{flex:0 0 auto;
    white-space:nowrap;padding:7px 12px;font-size:13px;border-radius:999px}
}
/* Explicit cells: auto-placement put the org name under the mark and let a
   narrow-screen rule push the wordmark to the far edge. */
.brand .brandmark{grid-column:1;grid-row:1 / span 2}
.brand span.wordmark{grid-column:2;grid-row:1;justify-self:start}
.brand #whoami{grid-column:2;grid-row:2;justify-self:start;max-width:100%}
/* Branded chevron on selects (native arrows differ per OS and ignore the theme). */
select:not([multiple]){-webkit-appearance:none;appearance:none;padding-right:36px;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%2356637D' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
  background-repeat:no-repeat;background-position:right 12px center;background-size:16px}

/* The brand block is the full logo image (owner decision: no typed wordmark,
   no organisation name beside it). */
.brand{display:flex!important;align-items:center}
.brand .brandlogo{display:block;height:auto;width:196px;max-width:100%}
.brand #whoami{display:none!important}
@media(max-width:1023px){.brand .brandlogo{width:150px}}
