/* CLIENT PRIVILEGED AND CONFIDENTIAL. Not for onward sharing. Not to be used to train any AI model. */
/* Layout: operations console. Fixed left rail of workspaces, a slim command bar, and a wide work
   surface; the agent floor is the one expressive moment, everything else is quiet finance tooling. */
:root {
  --bg: #f3f5f9; --surface: #ffffff; --surface-2: #f2f5f9; --surface-3: #e6e7e8;
  --fg: #4d4d4f; --strong: #23272e; --muted: #686a6d; --line: #d9d9d9;
  --brand: #2d4e9f; --brand-dark: #1f3a7a; --brand-light: #5b7bc4; --brand-tint: #e9eef8; --brand-head: #4567b0;
  --on-brand: #ffffff; --th-bg: #2d4e9f; --th-fg: #ffffff;
  --rag-green: #28a745; --rag-amber: #ffc000; --rag-orange: #ed7d31; --rag-red: #c00000; --rag-info: #5b9bd5;
  --rag-green-bg: #e3f4e7; --rag-amber-bg: #fff4cc; --rag-orange-bg: #fde9dc; --rag-red-bg: #f8dcdc; --rag-info-bg: #e3eef8;
  /* text in a RAG colour (pills, scores, Danger): the same hues, deep enough for 4.5:1 on their backgrounds */
  --rag-green-text: #1e7b34; --rag-amber-text: #7d5e00; --rag-orange-text: #a64d14; --rag-red-text: #c00000; --rag-info-text: #2a64a0;
  --desk: #8b9ab0; --desk-leg: #b3bfcf; --screen: #cfd9e8; --screen-on: #9fd0ff; --stripe: #c9dbf2; --helmet: #ffffff; --shirt: #d6dde8; --hair: #3b3030; --paper: #ffffff;
  --shadow: 0 1px 2px rgba(0, 28, 72, .06), 0 8px 24px rgba(0, 28, 72, .06);
  /* table stripe (see-through, so a table's edge shadow shows under it) and the edge shadow of a table that scrolls */
  --row-alt: rgba(0, 40, 110, .05); --edge-shadow: rgba(0, 28, 72, .2);
  /* the current page in the rail: a light tab in the light theme, a raised dark tab with a ring in the dark themes */
  --nav-on-bg: var(--surface); --nav-on-fg: #002c6b; --nav-on-cnt: #e8eef7; --nav-on-ring: transparent;
  --f-display: "Archivo", "Arial Narrow", "Helvetica Neue", Arial, sans-serif;
  --f-body: "IBM Plex Sans", "Segoe UI", "Helvetica Neue", Arial, sans-serif;
  --f-mono: "IBM Plex Mono", ui-monospace, "Cascadia Mono", Consolas, monospace;
  --r: 10px; --rail: #1f3a7a;
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --bg: #0a1220; --surface: #101b2e; --surface-2: #15233b; --surface-3: #1d2d4a;
    --fg: #c4cddb; --strong: #eef2f8; --muted: #8b97ab; --line: #25365a;
    --brand: #7aa5ea; --brand-dark: #b4cbf1; --brand-light: #86a9dc; --brand-tint: #16284a; --brand-head: #86a9dc;
    --on-brand: #06142b; --th-bg: #12376f; --th-fg: #ffffff;
    --rag-green-bg: #12301d; --rag-amber-bg: #3a3010; --rag-orange-bg: #3b2414; --rag-red-bg: #3c1414; --rag-info-bg: #142c45;
    --rag-green-text: #3fbf5f; --rag-amber-text: #ffc000; --rag-orange-text: #f39a5c; --rag-red-text: #ff6b6b; --rag-info-text: #7fb4e6;
    --desk: #4d5d78; --desk-leg: #3a4862; --screen: #2b3a55; --screen-on: #5fb6ff; --stripe: #9ab9e6; --helmet: #e8edf5; --shirt: #5c6b85; --hair: #1c1616; --paper: #f6f4ee;
    --shadow: 0 1px 2px rgba(0, 0, 0, .3), 0 8px 24px rgba(0, 0, 0, .25); --rail: #06101f;
    --row-alt: rgba(120, 160, 230, .05); --edge-shadow: rgba(0, 6, 20, .65);
    --nav-on-bg: var(--surface-3); --nav-on-fg: var(--strong); --nav-on-cnt: var(--surface-2); --nav-on-ring: var(--brand-light);
    color-scheme: dark;
  }
}
:root[data-theme="dark"] {
  --bg: #0a1220; --surface: #101b2e; --surface-2: #15233b; --surface-3: #1d2d4a;
  --fg: #c4cddb; --strong: #eef2f8; --muted: #8b97ab; --line: #25365a;
  --brand: #7aa5ea; --brand-dark: #b4cbf1; --brand-light: #86a9dc; --brand-tint: #16284a; --brand-head: #86a9dc;
  --on-brand: #06142b; --th-bg: #12376f; --th-fg: #ffffff;
  --rag-green-bg: #12301d; --rag-amber-bg: #3a3010; --rag-orange-bg: #3b2414; --rag-red-bg: #3c1414; --rag-info-bg: #142c45;
  --rag-green-text: #3fbf5f; --rag-amber-text: #ffc000; --rag-orange-text: #f39a5c; --rag-red-text: #ff6b6b; --rag-info-text: #7fb4e6;
  --desk: #4d5d78; --desk-leg: #3a4862; --screen: #2b3a55; --screen-on: #5fb6ff; --stripe: #9ab9e6; --helmet: #e8edf5; --shirt: #5c6b85; --hair: #1c1616; --paper: #f6f4ee;
  --shadow: 0 1px 2px rgba(0, 0, 0, .3), 0 8px 24px rgba(0, 0, 0, .25); --rail: #06101f;
  --row-alt: rgba(120, 160, 230, .05); --edge-shadow: rgba(0, 6, 20, .65);
  --nav-on-bg: var(--surface-3); --nav-on-fg: var(--strong); --nav-on-cnt: var(--surface-2); --nav-on-ring: var(--brand-light);
  color-scheme: dark;
}
* { box-sizing: border-box; }
html, body { height: 100%; }
body { margin: 0; background: var(--bg); color: var(--fg); font: 14px/1.5 var(--f-body); -webkit-font-smoothing: antialiased; }
button, input, select, textarea { font: inherit; color: inherit; }
a { color: var(--brand); }
/* a link inside a line of text: at least 24px tall to tap; its line grows to hold it, so a link on the next line never
   covers part of it */
.lnk-inline { display: inline-block; padding-block: 5px; line-height: 14px; min-height: 24px; vertical-align: middle; }
h1, h2, h3 { font-family: var(--f-display); color: var(--brand); text-wrap: balance; margin: 0; }
h1 { font-size: 22px; font-weight: 700; letter-spacing: -.01em; }
h2 { font-size: 17px; font-weight: 650; color: var(--brand-head); }
h3 { font-size: 14px; font-weight: 650; color: var(--brand-head); }
.num, td.n, .mono { font-variant-numeric: tabular-nums; }
.mono { font-family: var(--f-mono); font-size: 12.5px; }
:focus-visible { outline: 2px solid var(--brand-light); outline-offset: 2px; }

/* shell */
.shell { display: grid; grid-template-columns: 228px minmax(0, 1fr); min-height: 100%; background: linear-gradient(to right, var(--rail) 228px, transparent 228px); }
.rail { background: var(--rail); color: #dfe8f6; display: flex; flex-direction: column; gap: 4px; padding: 18px 12px; position: sticky; top: 0; height: 100vh; }
.mark { display: flex; flex-direction: column; gap: 10px; align-items: flex-start; padding: 4px 8px 16px; }
.mark-logo { background: #ffffff; border-radius: 8px; padding: 8px 12px; display: flex; }
.mark-logo img { display: block; width: 132px; height: auto; }
.mark-glyph { width: 34px; height: 34px; border-radius: 9px; background: #ffffff; display: grid; place-items: center; }
.mark-t { font-family: var(--f-display); font-weight: 750; color: #ffffff; font-size: 15px; line-height: 1.15; letter-spacing: .01em; }
.mark-s { font-size: 11px; color: #a9bddc; }
.nav a { display: flex; align-items: center; justify-content: space-between; gap: 8px; padding: 8px 10px; border-radius: 8px; color: #dfe8f6; text-decoration: none; font-weight: 500; }
.nav a:hover { background: rgba(255, 255, 255, .08); }
.nav a.on { background: var(--nav-on-bg); color: var(--nav-on-fg); box-shadow: inset 0 0 0 1px var(--nav-on-ring); }
/* counts: a badge is work waiting (amber when some is yours); a total is plain text; an alert is in words */
.nav .cnt, .menu-btn .cnt { font-size: 11px; min-width: 20px; text-align: center; border-radius: 10px; padding: 0 6px; background: rgba(255, 255, 255, .16); font-variant-numeric: tabular-nums; }
.nav a.on .cnt { background: var(--nav-on-cnt); }
.nav .cnt.hot, .menu-btn .cnt.hot { background: #ffc000; color: #2b2200; }
.nav .cnt { white-space: nowrap; }
.nav .cnt .short, .menu-btn .cnt .long { display: none; }   /* the wide nav names its numbers; the phone's Menu button keeps them short */
.nav .cnt-plain { font-size: 11.5px; color: #a9bddc; font-variant-numeric: tabular-nums; }
.nav a.on .cnt-plain { color: inherit; opacity: .75; }
.nav .cnt-alert { font-size: 11px; font-weight: 600; padding: 0 7px; border-radius: 10px; color: var(--rag-red-text); background: var(--rag-red-bg); white-space: nowrap; }
/* text for screen readers only */
.sr { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }
.menu-btn { display: none; }
.rail-foot { margin-top: auto; font-size: 10.5px; color: #a9bddc; padding: 8px; line-height: 1.45; }
.main { min-width: 0; display: flex; flex-direction: column; }
.bar { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; padding: 10px 24px; background: var(--surface); border-bottom: 1px solid var(--line); position: sticky; top: 0; z-index: 20; }
.bar .title { font-family: var(--f-display); font-weight: 700; color: var(--brand); font-size: 18px; margin-right: auto; }
/* who is signed in, Sign out and Theme stay together: when the bar wraps they form one right-aligned row */
.bar-me { display: flex; align-items: center; justify-content: flex-end; gap: 6px 12px; flex-wrap: wrap; margin-left: auto; }
.chip { display: inline-flex; align-items: center; gap: 6px; font-size: 12px; padding: 3px 10px; border-radius: 999px; border: 1px solid var(--line); background: var(--surface-2); white-space: nowrap; }
.chip[hidden] { display: none; }
/* the chips' full text as one wrapped line under the bar: a phone only, where the chips show their short text */
.status-line { display: none; }
.chip .d { flex: none; width: 8px; height: 8px; border-radius: 50%; background: var(--rag-info); }
.chip .long { min-width: 0; overflow: hidden; text-overflow: ellipsis; }   /* the full text is also the chip's tooltip */
.chip .short { display: none; }
.chip.live .d { background: var(--rag-green); }
.chip.sim .d { background: var(--rag-amber); }
.chip.off .d { background: var(--rag-red); }
.chip.ai.local { background: var(--rag-green-bg); border-color: var(--rag-green); font-weight: 600; color: var(--strong); }
.chip.ai.local .d { background: var(--rag-green); }
.chip.ai.cloud .d { background: var(--rag-info); }
.chip.ai.sim .d { background: var(--rag-amber); }
.content { padding: 20px 24px 40px; display: flex; flex-direction: column; gap: 18px; min-width: 0; }
.notice { font-size: 11.5px; color: var(--muted); padding: 10px 24px 18px; border-top: 1px solid var(--line); }
/* tone surfaces (banner, toast): a 1px border in the tone, a tinted background and a leading status dot; the words say
   what happened, the tone only supports them. Tones: info (default), ok, warn, err. */
.banner, .toast { --tone: var(--rag-info); --tone-bg: var(--rag-info-bg); position: relative; border: 1px solid color-mix(in srgb, var(--tone) 55%, var(--line)); background: var(--tone-bg); border-radius: 8px; }
.banner.ok, .toast.ok { --tone: var(--rag-green); --tone-bg: var(--rag-green-bg); }
.banner.warn, .toast.warn { --tone: var(--rag-amber); --tone-bg: var(--rag-amber-bg); }
.banner.err, .toast.err { --tone: var(--rag-red); --tone-bg: var(--rag-red-bg); }
.banner::before, .toast::before { content: ""; position: absolute; left: 13px; top: 16px; width: 8px; height: 8px; border-radius: 50%; background: var(--tone); }
.banner { display: flex; flex-wrap: wrap; gap: 12px; align-items: flex-start; padding: 10px 14px 10px 31px; font-size: 13px; color: var(--fg); }
.banner > .grow { flex: 1 1 240px; }   /* the text keeps a readable width; a button that does not fit goes below it */
.banner.stack { flex-direction: column; align-items: stretch; gap: 8px; }   /* a question with its choices below it */

/* controls */
.btn { display: inline-flex; align-items: center; justify-content: center; gap: 6px; padding: 7px 14px; border-radius: 8px; border: 1px solid var(--line); background: var(--surface); cursor: pointer; font-weight: 550; white-space: nowrap; }
a.btn { text-decoration: none; color: inherit; }   /* a link drawn as a button looks like the buttons beside it */
.btn:hover { border-color: var(--brand-light); }
.btn.primary { background: var(--brand); color: var(--on-brand); border-color: var(--brand); }
.btn.primary:hover { filter: brightness(1.08); }
.btn.danger { color: var(--rag-red-text); border-color: color-mix(in srgb, var(--rag-red) 45%, var(--line)); }
.btn.small { padding: 4px 10px; font-size: 12.5px; }
.btn[disabled] { opacity: .5; cursor: not-allowed; }
.inp, select.inp, textarea.inp { padding: 7px 10px; border-radius: 8px; border: 1px solid var(--line); background: var(--surface); min-width: 0; }
textarea.inp { width: 100%; min-height: 80px; resize: vertical; }
label.fld { display: flex; flex-direction: column; gap: 4px; font-size: 12px; color: var(--muted); min-width: 0; }
label.fld > span { font-weight: 550; }
.row { display: flex; gap: 10px; align-items: center; flex-wrap: wrap; }
.grow { flex: 1 1 auto; min-width: 0; }
/* a tick box or radio stays on the line of its text; long text wraps beside it */
label.row { flex-wrap: nowrap; align-items: flex-start; }
label.row > input, label.row > b { flex: none; }
label.row > input { margin-top: 4px; }
/* a title with its tag or status pill: the title wraps, the tag or pill stays at its right */
.qitem > .row, .msg > .row:first-child { flex-wrap: nowrap; align-items: flex-start; }
.qitem .t1 { min-width: 0; }
.pill, .tag { flex: none; }
.switch { position: relative; width: 44px; height: 24px; border-radius: 24px; background: var(--surface-3); border: 1px solid var(--line); cursor: pointer; flex: none; }   /* at least 24px to tap */
.switch::after { content: ""; position: absolute; top: 2px; left: 2px; width: 18px; height: 18px; border-radius: 50%; background: #ffffff; box-shadow: 0 1px 2px rgba(0, 0, 0, .3); transition: left .15s; }
.switch.on { background: var(--rag-green); border-color: var(--rag-green); }
.switch.on::after { left: 22px; }
summary { min-height: 24px; padding-block: 2px; }   /* disclosure lines are at least 24px to tap */

/* cards, kpis */
.card { background: var(--surface); border: 1px solid var(--line); border-radius: var(--r); padding: 16px; min-width: 0; }
.card > h2 { margin-bottom: 10px; }
/* the 1px gaps show each tile's own right and bottom rule, so an unfilled cell of the last row stays plain */
.kpis { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 1px; background: var(--surface); border: 1px solid var(--line); border-radius: var(--r); overflow: hidden; }
.kpi { background: var(--surface); padding: 12px 14px; box-shadow: 1px 0 0 var(--line), 0 1px 0 var(--line); }
.kpi .k { font-size: 11px; text-transform: uppercase; letter-spacing: .06em; color: var(--muted); }
.kpi .v { font-family: var(--f-display); font-size: 24px; font-weight: 700; color: var(--strong); font-variant-numeric: tabular-nums; line-height: 1.2; }
.kpi .s { font-size: 11.5px; color: var(--muted); }
/* independent cards side by side keep their own height (no empty block under the shorter one) */
.grid2 { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 18px; align-items: start; }
.grid3 { display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); gap: 14px; }

/* tables
   The mono face (td.mono, .mono) is only for system identifiers a person copies: invoice refs, invoice numbers, PO and
   receipt numbers, Oracle ids, org ids, tax registrations, batch, group and request ids, account combinations. Codes
   that are business vocabulary (entity, currency, country, EX code, agent A-number, state) and every name or free
   text use the body face, with tabular figures where they hold numbers. */
/* a table wider than its box scrolls inside it: a shadow at the right edge says there is more (a cover at the end of the
   content hides it once scrolled to the end), and the first column stays in place */
.tw { overflow-x: auto; border: 1px solid var(--line); border-radius: var(--r);
  background: linear-gradient(to left, var(--surface) 45%, transparent) right center / 36px 100% no-repeat local,
    linear-gradient(to left, var(--edge-shadow), transparent) right center / 12px 100% no-repeat scroll, var(--surface); }
table.t { width: 100%; border-collapse: collapse; font-size: 13px; }
table.t th { background: var(--th-bg); color: var(--th-fg); text-align: left; font-weight: 600; padding: 8px 10px; white-space: nowrap; font-size: 12px; position: sticky; top: 0; }
table.t td { padding: 7px 10px; border-top: 1px solid var(--line); vertical-align: top; }
table.t tbody tr:nth-child(even) td { background: var(--row-alt); }
table.t th:first-child, table.t td:first-child:not([colspan]) { position: sticky; left: 0; z-index: 1; }
table.t th:first-child { z-index: 2; }
table.t td:first-child:not([colspan]) { background: var(--surface); }
table.t tbody tr:nth-child(even) td:first-child:not([colspan]) { background: linear-gradient(var(--row-alt), var(--row-alt)), var(--surface); }
table.t tbody tr.click { cursor: pointer; }
table.t tbody tr.click:hover td, table.t tbody tr.click:hover td:first-child:not([colspan]) { background: var(--brand-tint); }
/* once the table is scrolled, the first column casts a shadow over what passes under it (where the browser can tell) */
@property --tw-scrolled { syntax: "<number>"; inherits: true; initial-value: 0; }
@keyframes tw-scrolled { 0% { --tw-scrolled: 0; } 2%, 100% { --tw-scrolled: 1; } }
@supports (animation-timeline: scroll()) { .tw { animation: tw-scrolled linear both; animation-timeline: scroll(self inline); } }
table.t th:first-child::after, table.t td:first-child:not([colspan])::after { content: ""; position: absolute; top: 0; bottom: 0; right: -9px; width: 8px; pointer-events: none; border-left: 1px solid var(--line); background: linear-gradient(to right, var(--edge-shadow), transparent); opacity: var(--tw-scrolled); }
/* a row that holds a control (a select, a button, a switch): its cells line up on the control's middle */
table.t tr:has(select, .btn, .switch, input) > td { vertical-align: middle; }
/* a button that opens its row (keyboard path; the row itself still opens with a click) */
.rowlink { background: none; border: 0; min-height: 24px; padding: 4px 0; margin: -4px 0; font: inherit; color: inherit; cursor: pointer; text-align: left; white-space: nowrap; }
.rowlink:hover, .rowlink:focus-visible { color: var(--brand); text-decoration: underline; }
/* the actions of a row, side by side on one line */
.acts { display: flex; align-items: center; gap: 6px; flex-wrap: nowrap; }
/* inline row edit (cost centre owner, DoA approver): the select, its Inactive pill and the row's Saving, Saved or
   Not saved status side by side; the status wraps below when the cell is narrow */
.rowedit { display: flex; align-items: center; flex-wrap: wrap; gap: 4px 8px; }
.rowst { font-size: 12px; color: var(--muted); }
.rowst:empty { display: none; }
.rowst.ok { color: var(--rag-green-text); }
.rowst.err { color: var(--rag-red-text); }
/* a question asked in a row of its own, under the row it is about (DoA Remove) */
table.t tr.ask > td { background: var(--surface); }
/* the DoA add form: three fields, then Add level with their inputs */
.doa-add { align-items: end; }
.doa-add + .hint { margin: 8px 0 0; }
table.t td.n, table.t th.n { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }
/* ids, references, codes and times never break mid-word; a table that cannot fit scrolls inside its .tw box */
table.t td.mono, table.t td.nw { white-space: nowrap; }
/* a business code (entity, country, currency, cost centre, EX code, A-number): the body face, whole, figures aligned */
table.t td.code { white-space: nowrap; font-variant-numeric: tabular-nums; }
table.t td.who { min-width: 18ch; }
table.t td.cov { min-width: 22ch; }   /* Users, Covers: four entity codes on one line before it wraps at a comma */   /* a supplier's name wraps at word ends, never into a narrow column */
table.t td.mono.wrap { white-space: normal; }   /* free text in the mono face (a field's value, an account and its name) wraps at spaces */
table.t td.val { min-width: 14ch; }   /* a field's value as read on the document */
table.t td.sum { min-width: 28ch; }   /* an event's summary takes the free width; its model and confidence sit below it */
table.t td.agent, table.t td.src-of { min-width: 12ch; }   /* an agent or a log source by name */
/* an agent in the event log: id and name on one line where the table fits its box (from a 1280px laptop); narrower, the
   line may break only between the id and the name (the name's own spaces do not break) */
table.t td.agent { white-space: nowrap; }
@media (max-width: 1279px) { table.t td.agent { white-space: normal; } }
table.t td { min-width: 4.5em; }
table.t td .src { overflow-wrap: break-word; }   /* wraps at spaces first, so a column never narrows to one character */
/* Invoices on a phone: each invoice is a stacked row that fits the screen, nothing scrolls sideways. Line 1 the Ref
   (it opens the invoice, as in the table) and the status; line 2 the supplier and the gross at the right; line 3 every
   other value, muted, each after its column name. The column names stay in the table for screen readers */
@media (max-width: 560px) {
  table.t.inv, table.t.inv tbody { display: block; }
  table.t.inv thead { position: absolute; width: 1px; height: 1px; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); }
  table.t.inv tr { display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 12px; padding: 9px 12px; border-top: 1px solid var(--line); }
  table.t.inv tr:first-child { border-top: 0; }
  table.t.inv tbody tr:nth-child(even) { background: var(--row-alt); }
  table.t.inv tbody tr.click:hover { background: var(--brand-tint); }
  table.t.inv tr::before, table.t.inv tr::after { content: ""; flex-basis: 100%; height: 0; order: 3; }   /* the line breaks */
  table.t.inv tr::after { order: 6; }
  table.t.inv td, table.t.inv tbody tr:nth-child(even) td, table.t.inv tbody tr.click:hover td, table.t.inv tbody tr.click td:first-child:not([colspan]) { display: block; padding: 0; border: 0; min-width: 0; position: static; background: none; }
  table.t.inv tbody tr.click td:first-child:not([colspan])::after { content: none; }   /* no sticky column, so no edge shadow */
  table.t.inv td:nth-child(1) { order: 1; }
  table.t.inv td.status { order: 2; margin-left: auto; text-align: right; }
  table.t.inv td.who { order: 4; flex: 1 1 0; font-weight: 600; color: var(--strong); }
  table.t.inv td.who + td.n { order: 5; }
  table.t.inv td[data-l] { order: 7; font-size: 12px; color: var(--muted); }
  table.t.inv td[data-l]::before { content: attr(data-l) " "; font-family: var(--f-body); }
  table.t.inv td.empty { order: 0; flex-basis: 100%; }
}
.empty { padding: 26px; text-align: center; color: var(--muted); }
/* an empty state (emptyState() in ui/app.js): the message, what happens next, one action */
.es { display: flex; flex-direction: column; align-items: center; gap: 6px; }
.es p { margin: 0; }
.es .es-msg { color: var(--fg); }
/* placeholder rows while a page loads */
.loading { display: flex; flex-direction: column; gap: 10px; padding: 6px 0; }
.sk { height: 14px; border-radius: 6px; background: var(--surface-3); animation: sk 1.4s ease-in-out infinite; }
.sk:nth-child(3n) { width: 82%; } .sk:nth-child(3n + 1) { width: 94%; } .sk:nth-child(2) { width: 100%; height: 32px; }
@keyframes sk { 50% { opacity: .55; } }
.inp.search { width: min(280px, 100%); }

/* status pills: RAG only in status columns */
.pill { display: inline-flex; align-items: center; gap: 5px; padding: 1px 9px; border-radius: 999px; font-size: 11.5px; font-weight: 600; white-space: nowrap; border: 1px solid transparent; }
.pill::before { content: ""; width: 7px; height: 7px; border-radius: 50%; background: currentColor; }
.pill.g { color: var(--rag-green-text); background: var(--rag-green-bg); }
.pill.a { color: var(--rag-amber-text); background: var(--rag-amber-bg); }
.pill.o { color: var(--rag-orange-text); background: var(--rag-orange-bg); }
.pill.r { color: var(--rag-red-text); background: var(--rag-red-bg); }
.pill.i { color: var(--rag-info-text); background: var(--rag-info-bg); }
.pill.n { color: var(--muted); background: var(--surface-2); }
/* a business code (EX code, agent A-number) as a small chip in the body face */
.tag { display: inline-block; font: 600 11.5px/1.5 var(--f-body); font-variant-numeric: tabular-nums; color: var(--strong); padding: 0 6px; border-radius: 4px; background: var(--surface-2); border: 1px solid var(--line); }
.conf { font-family: var(--f-mono); font-size: 12px; }
.conf.lo { color: var(--rag-red-text); font-weight: 600; } .conf.mid { color: var(--rag-amber-text); font-weight: 600; }

/* floor */
.floor-wrap { display: flex; flex-direction: column; gap: 18px; }
.floor-card { padding: 8px; overflow-x: auto; }
.floor-svg { width: 100%; height: auto; display: block; }
.floor-svg text { font-family: var(--f-body); }
.panel { fill: var(--surface); stroke: var(--line); }
.floor-panel { fill: var(--surface); }
.lane { fill: var(--surface-2); stroke: var(--line); stroke-dasharray: 3 4; }
/* floor text sizes are in picture units: the picture is drawn at about 0.7 of its size on a 1280px laptop, so the
   smallest label (--floor-fs) is set to draw at 10px or more there; on a phone or tablet the picture keeps its 900px
   width and scrolls in its box, so its labels take the largest size the picture holds without colliding */
.floor-svg { --floor-fs: 14.5px; --floor-name: 15px; }
.zone-label, .lane-label { font-family: var(--f-display) !important; font-size: var(--floor-fs); letter-spacing: .12em; fill: var(--brand-light); font-weight: 700; }
.lane-label { letter-spacing: .06em; }
.flow-line { fill: none; stroke: var(--brand-light); stroke-opacity: .28; stroke-width: 2; stroke-dasharray: 2 8; stroke-linecap: round; animation: flow 1.6s linear infinite; }
@keyframes flow { to { stroke-dashoffset: -20; } }
.chan-box { fill: var(--surface); stroke: var(--brand-light); }
.chan-ico { fill: none; stroke: var(--brand); stroke-width: 1.6; }
.chan-line { fill: none; stroke: var(--brand); stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round; }
.chan-line.thick { stroke-width: 2.2; }
.chan-label { font-size: var(--floor-fs); fill: var(--muted); }
.desk { fill: var(--desk); } .desk-leg { fill: var(--desk-leg); }
.vest { fill: var(--brand); } .stripe { fill: var(--stripe); } .shirt { fill: var(--shirt); }
.helmet { fill: var(--helmet); stroke: var(--desk-leg); stroke-width: .8; } .helmet-band { fill: var(--brand-light); }
.hair { fill: var(--hair); } .eye { fill: #1d1d1d; } .mouth { fill: none; stroke: #1d1d1d; stroke-width: 1.2; stroke-linecap: round; } .mouth.lips { stroke: #b0485a; stroke-width: 1.6; }
.screen-back { fill: #5b6474; } .screen { fill: var(--screen); transition: fill .3s; }
.plate-name { font-size: var(--floor-name); font-weight: 650; fill: var(--strong); }
.plate-sub { font-size: var(--floor-fs); fill: var(--muted); }
.worker, .desk-person { cursor: pointer; }
.worker:hover .plate-name, .desk-person:hover .plate-name { fill: var(--brand); text-decoration: underline; }
.worker .bob { animation: bob 3.2s ease-in-out infinite; }
@keyframes bob { 50% { transform: translateY(-1.2px); } }
.worker .hand, .worker .qmark, .worker .zzz, .worker .bang, .worker .gear { display: none; }
.worker.working .screen { fill: var(--screen-on); }
.worker.working .arm-l { animation: type .22s ease-in-out infinite alternate; transform-origin: -18px -30px; transform-box: view-box; }
.worker.working .arm-r { animation: type .22s ease-in-out infinite alternate-reverse; transform-origin: 18px -30px; transform-box: view-box; }
.worker .arm-l, .worker .arm-r { transform-box: fill-box; transform-origin: 50% 0; }
@keyframes type { from { transform: rotate(-7deg); } to { transform: rotate(7deg); } }
.worker.working .gear { display: block; animation: spin 1.2s linear infinite; }
.gear-c { fill: var(--brand-light); } .gear-h { fill: var(--surface); }
@keyframes spin { to { transform: translate(32px, -18px) rotate(360deg); } }
.worker.waiting .hand { display: block; } .worker.waiting .arm-r { display: none; }
.worker.waiting .qmark { display: block; animation: pop 1.4s ease-in-out infinite; }
.q-c { fill: var(--rag-amber); } .q-t { font-size: 13px; font-weight: 800; fill: #2b2200; }
.bang-c { fill: var(--rag-red); }
.worker.error .bang { display: block; } .worker.error .bang .q-t { fill: #ffffff; }
@keyframes pop { 50% { transform: translateY(-3px); } }
.worker.offline .bob { filter: grayscale(1); opacity: .45; animation: none; }
.worker.offline .zzz { display: block; }
.z-t { font-size: 13px; font-weight: 700; fill: var(--muted); animation: zz 2.4s ease-in-out infinite; }
.z-t.z2 { animation-delay: .6s; font-size: 10px; }
@keyframes zz { 0% { opacity: 0; transform: translateY(4px); } 40% { opacity: 1; } 100% { opacity: 0; transform: translateY(-8px); } }
.sdot { fill: var(--rag-green); stroke: var(--surface); stroke-width: 2; }
.worker.working .sdot { fill: var(--rag-info); } .worker.waiting .sdot { fill: var(--rag-amber); } .worker.offline .sdot { fill: var(--rag-red); } .worker.error .sdot { fill: var(--rag-red); }
.qb-r { fill: var(--paper); stroke: var(--desk); } .qb-t { font-size: var(--floor-fs); font-weight: 700; fill: #23272e; font-family: var(--f-mono); }
.bubble { opacity: 0; transition: opacity .25s, transform .25s; pointer-events: none; }
.bubble.show { opacity: 1; }
.bub-r { fill: var(--surface); stroke: var(--brand-light); stroke-width: 1.2; }
.bub-t { font-size: var(--floor-fs); fill: var(--strong); }
.badge { display: none; } .desk-person.has-work .badge { display: block; animation: pop 1.6s ease-in-out infinite; }
.badge-c { fill: var(--rag-amber); } .badge-t { font-size: var(--floor-fs); font-weight: 800; fill: #2b2200; }
.desk-person.has-work .screen { fill: #ffe38a; }
.ping { fill: none; stroke: var(--rag-amber); stroke-width: 3; opacity: 0; }
.ping.go { animation: ping 1.1s ease-out 2; }
@keyframes ping { 0% { opacity: .9; r: 12; } 100% { opacity: 0; r: 46; } }
.bldg-top { stop-color: var(--brand); } .bldg-bot { stop-color: var(--brand-dark); }
:root[data-theme="dark"] .bldg-top { stop-color: #1b3f7a; } :root[data-theme="dark"] .bldg-bot { stop-color: #0d2247; }
@media (prefers-color-scheme: dark) { :root:not([data-theme="light"]) .bldg-top { stop-color: #1b3f7a; } :root:not([data-theme="light"]) .bldg-bot { stop-color: #0d2247; } }
.bldg-sign { fill: var(--surface); stroke: var(--brand); stroke-width: 2; }
.bldg-sign-t { font-family: var(--f-display) !important; font-weight: 800; font-size: var(--floor-fs); letter-spacing: .08em; fill: var(--brand); }
.win { fill: #1a3566; transition: fill .4s; } .win.lit { fill: #8fb8ee; } .win.flash { fill: #ffe38a; }
.door { fill: #0b1d3d; stroke: #8fb8ee; stroke-width: 1.5; }
.bldg-small { font-size: var(--floor-fs); fill: #cfe0f7; }
/* the building's counts: small figures, the number strong, its word muted, rejections in red when there are some */
.bldg-count { font-size: var(--floor-fs); fill: var(--muted); font-variant-numeric: tabular-nums; }
.bldg-count .fig-n { font-weight: 700; fill: var(--strong); }
.bldg-count .fig.bad, .bldg-count .fig.bad .fig-n { fill: var(--rag-red-text); }
.job-box { fill: var(--surface-2); stroke: var(--line); } .job-id { font-family: var(--f-body) !important; font-size: var(--floor-fs); font-weight: 650; fill: var(--brand); } .job-n { font-size: var(--floor-fs); fill: var(--muted); }
.tray-box { fill: var(--surface-3); stroke: var(--desk); } .tray-count { font-size: var(--floor-name); font-weight: 800; fill: var(--strong); }
.env-r { fill: var(--paper); stroke: var(--brand); stroke-width: 1.3; } .env-f { fill: none; stroke: var(--brand); stroke-width: 1.1; }
.env.copy .env-r { stroke: var(--brand-light); } .env.copy { opacity: .85; }
.env.rec .env-r { fill: #dff0e3; stroke: var(--rag-green); }
.env-tag { font-family: var(--f-mono) !important; font-size: var(--floor-fs); font-weight: 700; fill: var(--brand); paint-order: stroke; stroke: var(--surface); stroke-width: 3px; }
.crate-r { fill: #c98a3c; stroke: #7a4e17; } .crate-l { stroke: #7a4e17; }
.env.land { transition: opacity .25s; opacity: 0; }

.side { display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); gap: 14px; min-width: 0; align-items: start; }
.ticker { max-height: 300px; overflow: auto; display: flex; flex-direction: column; gap: 0; }
.tick { display: grid; grid-template-columns: 42px minmax(0, 1fr); gap: 8px; padding: 6px 0; border-top: 1px solid var(--line); font-size: 12px; }
.tick:first-child { border-top: 0; }
.tick .ag { font-weight: 700; color: var(--strong); font-variant-numeric: tabular-nums; }   /* an agent id, named in the line below */
.tick .when { color: var(--muted); font-size: 11px; }
/* the page's actions and the live activity come first: on a laptop a compact strip above the floor (sending and running
   side by side, the activity wider and shorter), so all three are on the first screen; on a phone or tablet the floor
   stays first and the cards follow it */
@media (min-width: 861px) and (max-width: 1599px) {
  .floor-wrap > .side { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr) minmax(0, 2fr); }
  .floor-wrap .ticker { max-height: 132px; }
}
@media (max-width: 860px) { .floor-wrap > .floor-card { order: -1; } }
/* wide screens: the page's actions and the live activity stand beside the floor, the activity filling the height. From
   1600px the picture beside them is still drawn at least as large as on a 1280px laptop */
@media (min-width: 1600px) {
  .floor-wrap { display: grid; grid-template-columns: minmax(0, 1fr) 320px; align-items: stretch; }
  .floor-wrap > .floor-card { grid-column: 1; grid-row: 1; }
  .floor-wrap > .side { grid-column: 2; grid-row: 1; display: flex; flex-direction: column; align-items: stretch; }
  .floor-wrap > .side > .card:last-child { flex: 1 1 auto; display: flex; flex-direction: column; min-height: 0; }
  .floor-wrap .ticker { flex: 1 1 auto; height: 0; min-height: 200px; max-height: none; }
}
.drop { border: 2px dashed var(--brand-light); border-radius: var(--r); padding: 14px; text-align: center; color: var(--muted); font-size: 12.5px; cursor: pointer; }
.drop.over { background: var(--brand-tint); }
.speed { width: 100%; }

/* workbench */
.wb { display: grid; grid-template-columns: 340px minmax(0, 1fr); gap: 18px; align-items: start; }
.qlist { display: flex; flex-direction: column; gap: 8px; }
.qitem { text-align: left; background: var(--surface); border: 1px solid var(--line); border-radius: var(--r); padding: 10px 12px; cursor: pointer; display: flex; flex-direction: column; gap: 3px; }
.qitem:hover { border-color: var(--brand-light); }
.qitem.sel { border-color: var(--brand); box-shadow: inset 3px 0 0 var(--brand); }
.qitem .t1 { font-weight: 600; color: var(--strong); }
.qitem .t2 { font-size: 12px; color: var(--muted); }
/* a queue item's rows: what is left (title, invoice, kind and owner) wraps between words; the EX code, amount and due time
   stay whole at the right, and a due time drops below the owner when the row is too narrow for both */
.qitem > span { display: flex; align-items: baseline; justify-content: space-between; gap: 2px 10px; }
.qitem > .q1 { align-items: flex-start; }
.qitem > .q2 > .t2, .qitem > .q1 > .t1 { min-width: 0; }
.qitem > .q3 { flex-wrap: wrap; }
.qitem .amt { flex: none; white-space: nowrap; font-size: 12px; font-weight: 600; color: var(--strong); font-variant-numeric: tabular-nums; }
.qitem .due { margin-left: auto; white-space: nowrap; font-size: 12px; color: var(--muted); font-variant-numeric: tabular-nums; }
.qitem .pill { margin-left: auto; }
/* the list is empty: its message spans the page, with no decision panel beside it */
.wb.none { grid-template-columns: minmax(0, 1fr); }
.wb.none > #decision { display: none; }
/* decision header: the title with its EX code and status, Open invoice alone at the right, the facts on a line below */
.dhead { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 6px 12px; align-items: start; }
.dtitle { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 10px; }
.hfacts { grid-column: 1 / -1; display: flex; flex-wrap: wrap; gap: 2px 18px; margin: 0; font-size: 12.5px; }
.hfacts > div { display: flex; gap: 6px; min-width: 0; }
.hfacts dt { color: var(--muted); }
.hfacts dd { margin: 0; color: var(--strong); }
/* the decision's options, the server's order and styles, side by side and of one height; they wrap when they must */
.actions { display: flex; flex-wrap: wrap; gap: 8px; align-items: stretch; }
.actions > .btn { min-height: 36px; }
/* a decision column of 480px or more keeps up to three options on one row: a long label takes a second line inside its
   button rather than pushing the next option to a row of its own; a narrower column wraps the options as above */
@container (min-width: 480px) {
  .decide .actions { flex-wrap: nowrap; }
  .decide .actions > .btn { flex: 0 1 auto; min-width: 0; white-space: normal; text-wrap: balance; text-align: center; }
}
/* the evidence beside the decision: the image takes the larger share, the facts, fields and options keep at least 300px
   beside it, so the options stay as high on the page as the fields allow (the decision first); only a decision card too
   narrow for both (under 620px) puts the image above, full width. On a laptop (a decision card up to 900px) the facts
   run across the whole card above the image and the fields, so their labels and values stay on one line each and
   the options come no lower than with the facts in the narrow column */
.decide { display: grid; grid-template-columns: minmax(0, 1.25fr) minmax(300px, 1fr); grid-template-rows: auto 1fr; grid-template-areas: "img facts" "img rest"; gap: 12px 16px; }
.decide > div { min-width: 0; display: flex; flex-direction: column; gap: 12px; }
.decide > .dimg { grid-area: img; gap: 8px; } .decide > .dfacts { grid-area: facts; } .decide > .drest { grid-area: rest; }
@container (max-width: 1000px) { .decide { grid-template-rows: auto; grid-template-areas: "facts facts" "img rest"; } }   /* up to a 1600px screen */
@container (max-width: 900px) { .decide { grid-template-columns: minmax(0, 1fr) minmax(300px, 1fr); } }   /* laptop, and one column near 1180: half and half, the fields two to a row */
.inv-frame { width: 100%; height: 560px; border: 1px solid var(--line); border-radius: 6px; }
.dcard { container-type: inline-size; }
@container (max-width: 620px) {
  .decide { grid-template-columns: minmax(0, 1fr); grid-template-areas: "img" "facts" "rest"; }
  .decide .inv-frame { height: 480px; }
}
.facts { font-size: 13px; gap: 4px 14px; }
.facts dd { color: var(--strong); }
.proposal { padding: 10px 12px; background: var(--brand-tint); border-radius: 8px; font-size: 13px; }
.fgrid { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 10px; }
.fgrid:not(:has(.src, .hint)) { align-items: end; }   /* inputs of one row line up when a label wraps (fields with help text below keep the top) */
.fld.flag .inp { border-color: var(--rag-amber); }
/* help and secondary prose */
.hint { font: 12px/1.45 var(--f-body); color: var(--muted); }
/* page intro: the lead text under a page's heading, and notes under a table, at a readable line length */
.lede { margin: 4px 0 0; font-size: 12.5px; line-height: 1.5; color: var(--muted); max-width: 75ch; }
.lede.status { color: var(--fg); margin-top: 6px; }
.measure { max-width: 75ch; }
/* text as it stands on the document (and the AI's suggestion beside it): the value a person checks, so it reads clearly */
.src { font: 12px/1.45 var(--f-body); color: var(--fg); font-variant-numeric: tabular-nums; overflow-wrap: break-word; }
label.fld > :is(.hint, .src) { font-weight: 400; }   /* below a field: not the label's weight */

/* drawer, modal, toasts */
.scrim { position: fixed; inset: 0; background: rgba(0, 20, 50, .35); z-index: 40; }
.drawer { position: fixed; top: 0; right: 0; bottom: 0; width: min(760px, 100%); background: var(--bg); z-index: 41; display: flex; flex-direction: column; box-shadow: -10px 0 30px rgba(0, 0, 0, .2); }
.drawer-h { display: flex; gap: 10px; align-items: center; padding: 14px 18px; background: var(--surface); border-bottom: 1px solid var(--line); padding-top: calc(14px + env(safe-area-inset-top, 0px)); }
.drawer-h h2:focus { outline: none; }   /* the heading takes the focus when a layer opens; it is not a control */
.drawer-b { flex: 1 1 auto; min-height: 0; overflow: auto; padding: 16px 18px 40px; display: flex; flex-direction: column; gap: 14px; }
/* a drawer's actions: a bar at its foot, always in view; the message at the left, Cancel, then the primary at the right */
.drawer-f { flex: none; display: flex; align-items: center; justify-content: flex-end; flex-wrap: wrap; gap: 8px 10px; padding: 12px 18px calc(12px + env(safe-area-inset-bottom, 0px)); background: var(--surface); border-top: 1px solid var(--line); }
/* the same for a form inside a card */
.form-actions { display: flex; align-items: center; justify-content: flex-end; flex-wrap: wrap; gap: 8px 10px; margin-top: 12px; }
:is(.drawer-f, .form-actions) > .grow { flex: 1 1 180px; }
.form-msg { color: var(--rag-red-text); font-size: 12.5px; }
.form-msg.note { color: var(--muted); }   /* a passing state: Saving..., changes not saved yet */
.form-msg.ok { color: var(--rag-green-text); }
/* an edit-then-save form (Settings): a field that differs from its saved value says so until it is saved or discarded */
.fld.changed .inp { border-color: var(--rag-amber); }
.fld.changed > span:first-child::after { content: " (not saved)"; font-weight: 400; }
.fld .inp[aria-invalid="true"] { border-color: var(--rag-red); }
.drawer-b > * { flex-shrink: 0; }   /* the body scrolls; its parts (the tab strip first) keep their height */
.tabs { display: flex; flex-wrap: wrap; gap: 2px; border-bottom: 1px solid var(--line); }   /* labels wrap to a second row, never cut at the edge */
.tabs button { background: none; border: 0; padding: 8px 12px; cursor: pointer; color: var(--muted); font-weight: 550; border-bottom: 2px solid transparent; white-space: nowrap; }
.tabs button.on { color: var(--brand); border-bottom-color: var(--brand); }
/* a drawer whose tabs keep every panel (the agent drawer): the open one shows, the others stay hidden with their input */
.tabpanel { display: flex; flex-direction: column; gap: 14px; }
.tabpanel[hidden] { display: none; }
.modal { position: fixed; inset: 5% 8%; background: var(--surface); z-index: 51; border-radius: 12px; display: flex; flex-direction: column; overflow: hidden; box-shadow: var(--shadow); }
.modal pre { margin: 0; padding: 16px; overflow: auto; font: 12px/1.5 var(--f-mono); white-space: pre-wrap; overflow-wrap: anywhere; flex: 1; }
.toasts { position: fixed; right: 16px; bottom: calc(16px + env(safe-area-inset-bottom, 0px)); display: flex; flex-direction: column; gap: 8px; z-index: 60; max-width: min(380px, calc(100% - 32px)); }
.toast { display: flex; gap: 10px; align-items: flex-start; padding: 9px 12px 9px 29px; box-shadow: var(--shadow); font-size: 12.5px; color: var(--fg); animation: tin .25s ease-out; }
.toast::before { left: 12px; top: 15px; }
.toast > .grow { flex: 1 1 auto; }
.toast b { color: var(--strong); }
@keyframes tin { from { transform: translateY(8px); opacity: 0; } }
/* the invoice's path: steps done carry a tick and a tinted border, the current step is filled; a state off the path
   shows as its status pill after the last step reached */
.timeline { display: flex; flex-wrap: wrap; align-items: center; gap: 4px; }
.timeline .step { font-size: 11.5px; padding: 2px 7px; border-radius: 4px; background: var(--surface-2); color: var(--muted); border: 1px solid var(--line); }
.timeline .step.done { background: var(--brand-tint); color: var(--brand); border-color: color-mix(in srgb, var(--brand) 45%, transparent); }
.timeline .step.done::before { content: "\2713"; margin-right: 4px; }
.timeline .step.now { background: var(--brand); color: var(--on-brand); border-color: var(--brand); }
.ev { display: grid; grid-template-columns: max-content minmax(0, 1fr); gap: 10px; padding: 7px 0; border-top: 1px solid var(--line); font-size: 12.5px; }
.ev .ag { font-family: var(--f-mono); font-weight: 700; color: var(--strong); white-space: nowrap; }   /* a reference stays whole; not link blue, it is not a link */
.ev .ag.aid { font-family: var(--f-body); }   /* an agent's A-number is business vocabulary: the body face */
/* an event's rule results: failures first in red, then the others, passes muted */
.rules { list-style: none; margin: 3px 0 0; padding: 0; display: flex; flex-wrap: wrap; gap: 0 14px; font-size: 12px; line-height: 1.5; }
.rules li { color: var(--fg); }
.rules li.fail { color: var(--rag-red-text); font-weight: 600; }
.rules li.pass { color: var(--muted); }
/* the invoice record (Envelope tab): one card per section, nested parts indented under their label */
.card.env { padding: 12px 14px; }
.card.env > h3 { margin-bottom: 6px; }
.env .kv .kv { padding-left: 10px; border-left: 1px solid var(--line); }
.env .env-item + .env-item { margin-top: 8px; }
.env .env-n { font-weight: 600; color: var(--strong); font-size: 12px; margin-bottom: 2px; }
.env .mono { font-size: 12px; overflow-wrap: anywhere; }
.open-doc { margin: 0; }
.drawer .fgrid { grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); }   /* fields in a drawer: two columns, values not cut */
/* a subtitle or meta line under a title: muted, its parts separated by a middle dot (meta() in ui/fmt.js) */
.meta { font-size: 12px; color: var(--muted); }
.meta .sep { padding: 0 2px; }
.ev .meta { color: var(--muted); font-size: 11px; }
.msg { border: 1px solid var(--line); border-radius: 8px; background: var(--surface); padding: 10px 12px; display: flex; flex-direction: column; gap: 4px; }
/* the channel of a message (E-mail, Teams), a small neutral label before its subject */
.chan { display: inline-block; font: 600 11px/1.6 var(--f-body); color: var(--muted); padding: 0 6px; margin-right: 6px; border-radius: 4px; background: var(--surface-2); border: 1px solid var(--line); vertical-align: 1px; }
.msg .body { white-space: pre-wrap; font-size: 12.5px; color: var(--fg); }
/* a message's meta: who to whom on one line, then when, the agent and its invoice */
.msg .meta > div + div { margin-top: 1px; }
/* a button that reads as a link inside a line of text (a message's invoice): 24px to tap without moving the line */
.lnk-btn { background: none; border: 0; padding: 5px 0; margin: -5px 0; min-height: 24px; font: inherit; color: var(--brand); text-decoration: underline; cursor: pointer; }
.lnk-btn:hover { color: var(--brand-dark); }
/* every agent group in one grid: a group's heading spans the full width, its cards share the columns. 420px keeps a
   card's labels beside their values (the label/value list stacks in a card under 380px inside) */
.agent-cards { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(420px, 100%), 1fr)); gap: 12px; }
.agent-cards > .grp { grid-column: 1 / -1; margin-top: 10px; }
.agent-cards > .grp:first-child { margin-top: 0; }
.acard { display: flex; flex-direction: column; gap: 8px; }
.acard > .row:last-child { margin-top: auto; }   /* cards in a row end level: the switch and its button sit on the bottom edge */
/* card header: id and name on the first row; type and autonomy with the status pill at the end of the second */
.acard .top { display: grid; grid-template-columns: max-content minmax(0, 1fr) max-content; gap: 2px 10px; align-items: center; }
.acard .top .nm { grid-column: 2 / -1; }
.acard .top .ty { grid-column: 1 / 3; }
.acard .top .pill { grid-column: 3; justify-self: end; }
.acard .id { font-family: var(--f-mono); font-weight: 700; color: var(--on-brand); background: var(--brand); border-radius: 6px; padding: 2px 7px; font-size: 12px; justify-self: start; }
.acard .nm { font-weight: 650; color: var(--strong); }
.nw { white-space: nowrap; }
/* a list of named things, one per line: the name in the body face, its mode as a small pill after it */
.chip-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 3px; }
.chip-list li { display: flex; align-items: baseline; justify-content: space-between; gap: 8px; }
.chip-list .cn { min-width: 0; color: var(--strong); font: 12.5px/1.45 var(--f-body); }
/* small figures: each count with its word on one line, tabular numbers; a figure that needs attention in red */
.figs { display: inline-flex; flex-wrap: wrap; gap: 2px 12px; font-variant-numeric: tabular-nums; }
.figs > span { white-space: nowrap; }
.figs b { color: var(--strong); font-weight: 650; }
.figs .bad, .figs .bad b { color: var(--rag-red-text); }
table.t.jobs .btn.small { padding-block: 2px; margin-block: -3px; }   /* a row with its Run now button keeps the height of the rows without one; the button stays 24px to tap */
/* label/value list (.kv; the Workbench facts too): labels take the width they need (at most 45% of the list), values the
   rest and break only between words; in a narrow card the label sits above its value */
:is(.kv, .facts) { display: grid; grid-template-columns: fit-content(45%) minmax(0, 1fr); }
.kv { gap: 2px 12px; font-size: 12.5px; }
:is(.kv, .facts) dt { color: var(--muted); }
:is(.kv, .facts) dd { margin: 0; min-width: 0; overflow-wrap: break-word; }
.acard, .card:has(> .kv), .decide > div { container-type: inline-size; }
@container (max-width: 380px) {
  .kv { grid-template-columns: minmax(0, 1fr); row-gap: 0; }
  .kv dt { font-size: 11.5px; margin-top: 6px; }
  .kv dt:first-child { margin-top: 0; }
}
/* the Workbench facts sit above the decision's options: they stay side by side down to a narrower column, so the
   options are not pushed down */
@container (max-width: 260px) {
  .facts { grid-template-columns: minmax(0, 1fr); row-gap: 0; }
  .facts dt { font-size: 11.5px; margin-top: 6px; }
  .facts dt:first-child { margin-top: 0; }
}
/* an e-mail address breaks only after its "@" (fmtEmail) */
.email > span { white-space: nowrap; }
.conn-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(360px, 1fr)); gap: 14px; }
/* closed cards in a row end level, their "Credentials and settings" lines near the bottom edge; once a card is open,
   the cards keep their own height, so the open one grows alone */
.card.conn { display: flex; flex-direction: column; }
.card.conn > p { flex: 1 0 auto; }
.conn-grid:has(details[open]) > .conn { align-self: start; }
/* card header: the connection's name at the left (it wraps), its status pill and mode at the right; the category is
   the section heading above the cards, so in the card it is for screen readers only (.cat.sr) */
.conn .hd { display: grid; grid-template-columns: minmax(0, 1fr) max-content; gap: 4px 10px; align-items: start; }
.conn .hd .st { display: flex; flex-direction: column; align-items: flex-end; gap: 2px; }
.conn .mode { font-size: 12px; color: var(--muted); white-space: nowrap; }
.conn .mode b { font-weight: 600; color: var(--fg); }
.conn .mode.live b { color: var(--rag-green-text); }
.conn .conn-req { margin: 0 0 6px; }
.conn details summary { cursor: pointer; color: var(--brand); font-weight: 550; margin: 6px 0; }
/* Reports, cut-off listing: the totals above the table, in view before the rows */
.cut-total { margin: 0 0 8px; display: flex; flex-wrap: wrap; align-items: baseline; gap: 2px 12px; font-size: 13px; color: var(--strong); }
.cut-total .meta { font-size: 12.5px; }
.bar-meter { height: 8px; border-radius: 4px; background: var(--surface-3); position: relative; overflow: hidden; }
.bar-meter i { position: absolute; left: 0; top: 0; bottom: 0; background: var(--brand-light); border-radius: 4px; }
.bar-meter b { position: absolute; top: -3px; bottom: -3px; width: 2px; background: var(--strong); }

/* one column: the queue scrolls in its own box so the decision panel follows close below it */
/* wide screens: the bar stays one row whatever the page title. The status chips are shown data and keep their full
   text; the page title gives way (ellipsis; its full name is in its tooltip and is the current link in the rail). In the
   last resort the signed-in line wraps inside itself rather than push the bar wider than the screen. */
@media (min-width: 1181px) {
  .bar { flex-wrap: nowrap; }
  .bar .title { flex: 1 1 0; max-width: max-content; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }   /* the room left over, up to its full name */
  .bar .chip { flex: none; }
  .bar-me { flex: 0 1 auto; min-width: 0; flex-wrap: nowrap; }
  .bar-me > span { min-width: 0; }
}
/* side by side: the queue scrolls in its own box beside the decision, so a pick low in the queue keeps the decision in view */
@media (min-width: 1181px) { .wb .qlist { position: sticky; top: 64px; max-height: calc(100vh - 140px); overflow-y: auto; padding: 4px; } }
@media (min-width: 1181px) and (max-width: 1500px) { .wb { grid-template-columns: 300px minmax(0, 1fr); } }
@media (max-width: 1180px) { .wb { grid-template-columns: minmax(0, 1fr); } .wb .qlist { max-height: min(60vh, 520px); overflow-y: auto; padding: 4px; } }
@media (max-width: 860px) {
  /* rows sized to their content: the rail and the bar never stretch on a short page */
  .shell { grid-template-columns: minmax(0, 1fr); grid-template-rows: auto 1fr; background: none; }
  .floor-svg { min-width: 900px; --floor-fs: 15.5px; --floor-name: 16px; }
  .bar .title { flex: 1 1 auto; min-width: 0; font-size: 17px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  /* one row: the logo and a Menu button; the page links (all of them, with their counts) open below it in one tap */
  .rail { position: static; height: auto; flex-direction: row; flex-wrap: wrap; align-items: center; padding: 8px 12px; gap: 6px; }
  .mark { padding: 0 8px 0 0; flex-direction: row; align-items: center; } .mark-logo { padding: 6px 10px; } .mark-logo img { width: 84px; } .mark-s, .rail-foot { display: none; }
  .menu-btn { display: inline-flex; align-items: center; gap: 8px; margin-left: auto; min-height: 36px; padding: 6px 12px; border-radius: 8px; border: 1px solid rgba(255, 255, 255, .35); background: transparent; color: #dfe8f6; font-weight: 600; cursor: pointer; }
  .menu-btn[aria-expanded="true"] { background: rgba(255, 255, 255, .12); }
  .menu-btn[hidden] { display: none; }   /* signed out or server unreachable: no pages to list */
  .nav { display: none; flex-wrap: wrap; gap: 4px; width: 100%; padding-top: 4px; } .nav a { white-space: nowrap; padding: 6px 10px; font-size: 13.5px; }
  .rail.open .nav { display: flex; }
  .nav .cnt .long { display: none; } .nav .cnt .short { display: inline; }   /* compact inside the Menu */
  .content { padding: 14px 16px 30px; }
  /* the bar scrolls with the page instead of holding a quarter of the screen */
  .bar { position: static; padding: 8px 16px; gap: 6px 8px; }
  .bar-me { margin-left: 0; justify-content: flex-start; gap: 6px 8px; }
  .grid2, .decide { grid-template-columns: minmax(0, 1fr); }
  .decide { grid-template-areas: "img" "facts" "rest"; }
  .modal { inset: 2% 2%; }
  .conn-grid { grid-template-columns: minmax(0, 1fr); }
  /* tables scroll sideways in their box only as far as they must: ids, codes, dates and amounts stay whole (td.mono,
     td.nw, td.n) and text keeps a readable column; an empty-table message starts at the left, in view */
  table.t td:not(.n, .nw, .mono, .code, .cov, .empty) { min-width: 7em; }
  table.t td.empty { text-align: left; }
  table.t td.empty .es { align-items: flex-start; }
}
/* phone: the status chips show their short text beside the title (the full text stays for screen readers and in the
   tooltip); who is signed in on one line, the two buttons side by side below */
@media (max-width: 560px) {
  .bar .chip .long { position: absolute; width: 1px; height: 1px; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
  .bar .chip .short { display: inline; }
  .bar .chip { padding: 2px 8px; font-size: 11.5px; }
  .status-line { display: block; flex-basis: 100%; font-size: 12px; line-height: 1.4; color: var(--fg); }
  .status-line:empty { display: none; }
  .bar-me > span { flex-basis: 100%; }
}
@media (prefers-reduced-motion: reduce) { *, *::before, *::after { animation: none !important; transition: none !important; } }
