[data-chat-workbench] > [data-chat-selector] > div { overflow: auto; min-height: 0; flex: 1; }
[data-chat-selector] [data-modes] { flex-wrap: wrap; border-radius: var(--r-sm); }
[data-chat-selector] [data-modes] > [role="button"] { flex: 1 0 90px; }
/* ADR-0015 D48/C1 — Chat-local split; no universal shell geometry changes.
   Two tracks, 3a and 3b, and a hairline seam positioned at the boundary
   (founder, 2026-09-04) — never a third column for the handle. */
[data-chat-workbench] { display: grid; position: relative; min-width: 0; min-height: 440px; height: calc(100dvh - 190px); }
[data-chat-workbench] > section { display: flex; flex-direction: column; min-width: 0; min-height: 0; overflow: hidden; }
[data-chat-workbench] > section[hidden], [data-chat-workbench] [hidden] { display: none !important; }
/* A folded 3a is a 44px strip that is its own way back; the stacked
   conversation keeps a back control. Nothing else in the workbench is a
   chrome button. */
[data-chat-expand], [data-chat-back] { font-family: var(--font-body); font-size: inherit; min-height: var(--tap); flex-shrink: 0; background: var(--surface-2); color: var(--text); border: 1px solid var(--border); border-radius: var(--r-sm); }
[data-chat-expand] { width: 100%; min-width: 0; padding: 0; }
[data-chat-back] { align-self: flex-start; min-width: 44px; padding: 0 12px; }
[data-chat-workbench="split"] > [data-chat-conversation] > div { height: 100%; min-height: 0; }
[data-chat-workbench="stack"] > [data-chat-conversation] > div { height: calc(100% - var(--tap)); min-height: 0; }
/* The seam: a 2px line AT the boundary with a 10px hit area into 3b — the
   shell's own handle contract, so the two feel like one mechanism. */
[data-chat-resizer] { position: absolute; top: 0; bottom: 0; width: 10px; z-index: 2; cursor: col-resize; touch-action: none; background: linear-gradient(to right, var(--border-strong) 0, var(--border-strong) 2px, transparent 2px); }
[data-chat-resizer]:hover, [data-chat-resizer]:focus-visible { background: linear-gradient(to right, var(--action) 0, var(--action) 2px, transparent 2px); outline: 2px solid var(--action); outline-offset: -2px; }
[data-chat-workbench="stack"] { grid-template-columns: minmax(0, 1fr); }
/* ============================================================
   Clerim — primitive set (the component vocabulary). Composes on
   tokens.css + shell.css. Every surface builds from these;
   nothing else is invented per-surface. Component appearance
   lives HERE (this file + tokens.css are the design round-trip
   surface — docs/design/ROUNDTRIP.md). Overlays position against
   the SHELL, never the viewport.
   Ported from the v1.0 prototype's responsive/primitives.css.
   ============================================================ */

/* Account-setting actions stay to the right while there is room, then stack
   inside their own row instead of overflowing a manually narrowed pane. */
[data-settings-fields] { container: settings-fields / inline-size; }
@container settings-fields (max-width: 260px) {
  .app-shell [data-setting-row] { flex-direction: column; align-items: stretch; }
  .app-shell [data-setting-row] > :last-child { justify-content: flex-start; }
}

/* ---------- CounterStrip ---------- */
.counter-strip { display: grid; grid-template-columns: repeat(auto-fit, minmax(104px, 1fr)); gap: 6px; margin-bottom: 10px; }

/* Number band promotes the real CounterStrip; it never copies a count. */
.app-shell[data-fx~="number-band"] [data-counter-strip] {
  position: sticky; top: 0; z-index: 2; grid-template-columns: repeat(auto-fit, minmax(76px, 1fr));
  padding: 7px; border: .5px solid var(--glass-border); border-radius: var(--r-lg);
  background: var(--glass-strong); box-shadow: inset 0 1px var(--glass-highlight);
  -webkit-backdrop-filter: blur(18px); backdrop-filter: blur(18px);
}
.app-shell[data-fx~="number-band"] [data-counter-strip] .n { font-size: calc(28px * var(--ts)); }

/* Number roll remounts only the changed numeric Text node. */
.app-shell[data-fx~="number-roll"] [data-fx-number] { animation: clerim-number-roll 220ms var(--ease); }
@keyframes clerim-number-roll {
  from { opacity: 0; transform: translateY(.55em); }
  to { opacity: 1; transform: none; }
}

/* A stable activity trace per real row. The bars are decoration, so the
   title and actions remain the row's only accessible content. */
.app-shell[data-fx~="sparklines"] [data-fx-row] {
  background-image: repeating-linear-gradient(90deg, transparent 0 3px, var(--action-tint) 3px 5px);
  background-size: 42px 15px; background-repeat: no-repeat; background-position: calc(100% - 34px) center;
}

/* Timeline spine appears only around the canonical event-chain renderer. */
.app-shell[data-fx~="spine"] [data-timeline] { position: relative; padding-left: 15px; }
.app-shell[data-fx~="spine"] [data-timeline]::before {
  content: ""; position: absolute; left: 5px; top: 12px; bottom: 58px; width: 1px; background: var(--action-border);
}
.app-shell[data-fx~="spine"] [data-timeline-event] { position: relative; }
.app-shell[data-fx~="spine"] [data-timeline-event]::before {
  content: ""; position: absolute; left: -14px; top: 50%; width: 7px; height: 7px;
  transform: translateY(-50%); border-radius: 50%; background: var(--action); box-shadow: 0 0 0 3px var(--action-tint);
}

/* RecordTop emits this from the same ChainStep array as the pill chain. */
[data-lineage-graph] { display: none; }
.app-shell[data-fx~="lineage"] [data-lineage-graph] {
  display: flex; align-items: stretch; gap: 14px; margin: 2px 0 12px; overflow-x: auto;
}
.app-shell[data-fx~="lineage"] [data-lineage-node] {
  position: relative; flex: 0 0 auto; min-width: 72px; padding: 7px 9px; text-align: center;
  border: .5px solid var(--border-strong); border-radius: var(--r-md); background: var(--wa06);
  color: var(--text-secondary); font-size: calc(10px * var(--ts));
}
.app-shell[data-fx~="lineage"] [data-lineage-node="current"] { border-color: var(--action); background: var(--action-tint); color: var(--action-tint-text); }
.app-shell[data-fx~="lineage"] [data-lineage-node] + [data-lineage-node]::before {
  content: ""; position: absolute; width: 14px; left: -15px; top: 50%; border-top: .5px solid var(--action-border);
}

[data-fx-settings] [data-fx-setting] { margin-top: 12px; }
[data-fx-settings] [data-fx-setting] [data-no-print] { margin-top: 2px; }
@media (prefers-reduced-motion: reduce) {
  .app-shell[data-fx~="number-roll"] [data-fx-number] { animation: none; }
}

/* First-time setup — a derived checklist, not a wizard. Done steps stay
   listed and dim rather than disappearing: seeing what is already handled is
   most of what makes a list feel finishable. */
.setup-card { border-color: var(--brand-border); }
.setup-step { align-items: flex-start; gap: 10px; }
.setup-step .setup-tick { flex: none; width: 18px; margin-top: 2px; text-align: center; font-size: calc(13px * var(--ts)); color: var(--text-muted); }
.setup-step.is-done .setup-tick { color: var(--ok-fg); }
.setup-step.is-done .row-title { color: var(--text-secondary); font-weight: 500; }
.setup-step.is-done .row-sub { color: var(--text-muted); }
.counter {
  text-align: center; padding: 10px 6px;
  background: var(--wa05); border: 0.5px solid var(--wa06);
  border-radius: var(--r-md); box-shadow: inset 0 1px 0 var(--wa04);
}
.counter .n { font-size: calc(22px * var(--ts)); font-weight: 700; margin: 0; line-height: 1.1; color: var(--text); }
.counter .l { font-size: calc(10px * var(--ts)); color: var(--text-muted); margin: 2px 0 0; }
.counter.ok { background: var(--ok-bg); } .counter.ok .n { color: var(--ok-fg); }
.counter.wait { background: var(--wait-bg); } .counter.wait .n { color: var(--wait-fg); }
.counter.warn { background: var(--warn-bg); } .counter.warn .n { color: var(--warn-fg); }

/* The four data states (clerim.js setCount / initDataStates). A counter
   reading "–" is four different facts wearing one face — still loading,
   genuinely zero, not applicable here, or a call that failed — and the reader
   cannot act on any of them without knowing which. Each state looks like
   itself, and each carries a title so the answer is also readable aloud. */
.counter .n[data-state="loading"] { color: transparent; }
.counter .n[data-state="loading"]::after {
  content: ""; display: block; height: 15px; width: 34px; margin: 4px auto 5px;
  border-radius: var(--r-sm);
  background: linear-gradient(90deg, var(--wa06) 25%, var(--wa14) 50%, var(--wa06) 75%);
  background-size: 220% 100%;
  animation: clerim-skeleton 1.3s var(--ease) infinite;
}
@keyframes clerim-skeleton { from { background-position: 120% 0; } to { background-position: -120% 0; } }
@media (prefers-reduced-motion: reduce) {
  .counter .n[data-state="loading"]::after { animation: none; background: var(--wa08); }
}
/* A real zero is a fact, not an absence — it keeps the number and loses the
   emphasis, so a strip of zeros reads as a quiet building rather than a
   broken screen. */
.counter .n[data-state="zero"] { color: var(--text-muted); }
/* Not applicable to this role or this building. An em dash, and it says so. */
.counter .n[data-state="na"] { color: var(--text-muted); font-size: calc(18px * var(--ts)); }
/* The call failed. Distinct from all three above, and the only one that is
   the reader's problem to act on. */
.counter .n[data-state="error"] { color: var(--warn-fg); }

/* A placeholder that never resolved, replaced in place with a way out. */
.stalled { color: var(--text-muted); }
.link-btn {
  background: none; border: 0; padding: 0; font: inherit; cursor: pointer;
  color: var(--action-tint-text); text-decoration: underline; text-underline-offset: 2px;
}

/* ---------- Card ---------- */
.card {
  background: var(--surface-card);
  -webkit-backdrop-filter: blur(12px); backdrop-filter: blur(12px);
  border: 0.5px solid var(--wa10);
  border-radius: var(--r-md); padding: 12px 14px; margin-bottom: 8px;
  box-shadow: inset 0 1px 0 var(--wa06);
}
.card .card-title { margin: 0 0 2px; font-size: calc(13.5px * var(--ts)); font-weight: 600; color: var(--text); }
.card .card-sub { margin: 0; font-size: calc(12px * var(--ts)); color: var(--text-secondary); line-height: 1.5; }

/* ---------- the record's section bands (visual pass, 2026-09-03) ----------
   Inside column 4 a card that opens with a heading wears the mockup's
   .sec-head: a sticky uppercase band bleeding to the card's edges, a glyph
   at its left, and the whole band is the fold control Card renders. A
   folded section hides its body and keeps its band. */
.pane-record [data-card]:has(> [data-sec-toggle]) { position: relative; padding-top: 0; }
.pane-record [data-card] > [data-sec-toggle] + [role="heading"] {
  display: flex; align-items: center; min-height: 34px;
  margin: 0 -14px 12px; padding: 8px 14px 8px 30px;
  font-size: calc(12px * var(--ts)); font-weight: 700; letter-spacing: 0.05em; text-transform: uppercase;
  color: var(--text-secondary); line-height: 1.4;
  background: var(--wa06); border-bottom: 0.5px solid var(--wa10);
  border-radius: var(--r-md) var(--r-md) 0 0;
  position: sticky; top: -12px; z-index: 3;
}
.pane-record [data-card] > [data-sec-toggle] { cursor: pointer; border-radius: var(--r-md) var(--r-md) 0 0; }
.pane-record [data-card] > [data-sec-toggle]:hover + [role="heading"] { background: var(--wa10); }
.pane-record [data-card] > [data-sec-toggle]:focus-visible { outline: 2px solid var(--action); outline-offset: -2px; }
.pane-record [data-card] > [data-sec-toggle] > div { transition: transform var(--dur-fast) var(--ease); }
.pane-record [data-card][data-open="1"] > [data-sec-toggle] > div { transform: rotate(90deg); }
.pane-record [data-card][data-open="0"] > [data-sec-toggle] + [role="heading"] { margin-bottom: 0; border-bottom: 0; border-radius: var(--r-md); }
.pane-record [data-card][data-open="0"] { padding-bottom: 0; }
.pane-record [data-card][data-open="0"] > :not([data-sec-toggle]):not([role="heading"]) { display: none; }
@media (prefers-reduced-motion: reduce) { .pane-record [data-card] > [data-sec-toggle] > div { transition: none; } }
/* A record body's own section headings — outside any card — wear the same
   band, so a record reads as one set of sections whichever way its panel
   composed it. No fold control here: there is no card to fold. */
.pane-record [data-record-pane] > div > [role="heading"]:not([data-record-title]) {
  display: flex; align-items: center; min-height: 34px; margin: 12px 0 8px; padding: 8px 14px;
  font-size: calc(12px * var(--ts)); font-weight: 700; letter-spacing: 0.05em; text-transform: uppercase;
  color: var(--text-secondary); line-height: 1.4; background: var(--wa06); border-radius: var(--r-md);
}

/* ---------- GroupCard (a list-pane group that can stand closed) ----------
   Grouping a long rail is only half of "reduce the choices at each moment" —
   four captions over fourteen rows is still fourteen rows in one scrolling
   column. A group that opens on demand is the other half. <details> because
   the browser already knows how to do this with a keyboard and a screen
   reader, and nothing hand-rolled here would do it as well. */
details.group-card { padding-bottom: 4px; }
details.group-card > summary {
  display: flex; align-items: baseline; gap: 10px; cursor: pointer;
  min-height: var(--tap); padding: 2px 0; list-style: none;
}
details.group-card > summary::-webkit-details-marker { display: none; }
details.group-card > summary .section-title { margin: 0; }
details.group-card > summary .group-note {
  flex: 1; min-width: 0; font-size: calc(11px * var(--ts)); color: var(--text-muted);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
details.group-card > summary::after {
  content: "›"; flex: none; font-size: calc(15px * var(--ts)); color: var(--text-muted);
  transition: transform var(--dur-fast) var(--ease);
}
details.group-card[open] > summary::after { transform: rotate(90deg); }
details.group-card[open] > summary { margin-bottom: 12px; }
@media (prefers-reduced-motion: reduce) {
  details.group-card > summary::after { transition: none; }
}

/* ---------- Pill ---------- */
.pill { display: inline-block; font-size: calc(10.5px * var(--ts)); font-weight: 600; padding: 2px 9px; border-radius: var(--r-pill); white-space: nowrap; background: var(--wa08); color: var(--text-secondary); }
.pill.ok { background: var(--ok-bg); color: var(--ok-fg); }
.pill.wait { background: var(--wait-bg); color: var(--wait-fg); }
.pill.warn { background: var(--warn-bg); color: var(--warn-fg); }
.pill.action { background: var(--action-tint); color: var(--action-tint-text); }
.pill.violet { background: var(--violet-bg); color: var(--violet-fg); }

/* ---------- Button ---------- */
.btn {
  font: inherit; font-size: calc(12.5px * var(--ts)); font-weight: 600;
  min-height: var(--tap); padding: 8px 16px;
  border-radius: var(--r-md); border: 0.5px solid var(--wa15);
  background: var(--wa08); color: var(--text-secondary);
  cursor: pointer; display: inline-flex; align-items: center; justify-content: center; gap: 6px;
}
.btn:hover { background: var(--wa12); color: var(--text); }
.btn.primary { background: var(--action-tint); border-color: var(--btn-primary-border); color: var(--action-tint-text); box-shadow: inset 0 1px 0 var(--btn-primary-highlight); }
.btn.primary:hover { background: var(--btn-primary-hover); }
.btn.danger { background: var(--warn-bg); border-color: rgba(212,110,100,0.35); color: var(--warn-fg); }
.btn.block { display: flex; width: 100%; }
.btn.tight { min-height: 36px; padding: 5px 12px; font-size: calc(11.5px * var(--ts)); position: relative; }
.btn.tight::after { content: ""; position: absolute; left: 0; right: 0; top: 50%; height: var(--tap); transform: translateY(-50%); }
/* Hover is the browser-only half of the RN Button's Pressable contract. */
[data-rn-button="default"]:hover { background: var(--wa12); }
[data-rn-button="default"]:hover [data-rn-button-label] { color: var(--text); }
[data-rn-button="primary"]:hover { background: var(--btn-primary-hover); }
[data-rn-button^="submit-"]:hover { background: linear-gradient(180deg, var(--action-hover), var(--action)); filter: brightness(1.06); }
[data-rn-button="submit-danger"]:hover { background: linear-gradient(180deg, var(--warn-fg), color-mix(in srgb, var(--warn-fg) 78%, #000)); }

/* ---------- Row ---------- */
.row {
  display: flex; align-items: center; gap: 10px; width: 100%; text-align: left;
  /* The row is the most-read type in the product — every list on every
     surface — and it takes its size from a DENSITY token rather than a
     literal, which is how it slipped past the sweep that scaled the literals.
     Found by the rendered pass in scripts/a11y-scan.mjs, which measures what
     the engine computed rather than what the source says. */
  font: inherit; font-size: calc(var(--t-row) * var(--ts)); color: var(--text);
  min-height: var(--tap); padding: var(--row-pad-y) 12px; margin-bottom: var(--row-gap);
  background: var(--wa06); border: 0.5px solid var(--wa10); border-radius: var(--r-md);
}
button.row { cursor: pointer; }
button.row:hover { background: var(--wa08); }
.row[aria-current="true"] { background: var(--action-tint); border-color: rgba(107,159,212,0.4); }
.row .row-main { flex: 1; min-width: 0; }
.row .row-title { display: block; font-weight: 600; }
.row .row-sub { display: block; font-size: calc(var(--t-row-sub) * var(--ts)); color: var(--text-muted); }
.row .row-time { font-family: var(--font-mono); font-size: calc(10px * var(--ts)); color: var(--text-muted); white-space: nowrap; }
.row.queued { border-style: dashed; opacity: 0.85; }

/* ---------- Field ---------- */
.field { display: flex; justify-content: space-between; gap: 12px; padding: 4px 0; font-size: calc(12px * var(--ts)); border-bottom: 0.5px solid var(--wa05); }
.field:last-child { border-bottom: 0; }
.field .k { color: var(--text-muted); flex: none; }
.field .v { font-weight: 500; color: var(--text); text-align: right; flex: 1; min-width: 0; overflow-wrap: break-word; }

/* ---------- Group: accordion below wide, FLAT at wide+ ----------
   Collapse is decided by the shell container, not a prop. */
.group { margin-bottom: 8px; border: 1px solid var(--wa14); border-radius: var(--r-md); overflow: hidden; background: var(--wa04); }
.group-hdr {
  font: inherit; display: flex; align-items: center; gap: 10px; width: 100%; text-align: left;
  min-height: var(--tap); padding: 0 14px;
  border: 0; background: transparent; color: var(--text); cursor: pointer;
}
.group-hdr:hover { background: var(--wa05); }
.group-hdr .group-title { font-size: calc(13px * var(--ts)); font-weight: 700; }
.group-hdr .spacer { flex: 1; }
.group-hdr .chev { font-size: calc(11px * var(--ts)); color: var(--text-muted); }
.group-hdr .chev::after { content: "▸ expand"; }
.group[data-open="1"] .group-hdr .chev::after { content: "▾ collapse"; }
.group-body { display: none; border-top: 0.5px solid var(--wa10); padding: 12px 14px; }
.group[data-open="1"] .group-body { display: block; }
@container shell (min-width: 1120px) {
  .group { background: transparent; border-color: var(--wa10); }
  .group-hdr { cursor: default; }
  .group-hdr:hover { background: transparent; }
  .group-hdr .chev { display: none; }
  .group-body { display: block !important; }
}

/* ---------- DetailHeader ---------- */
.detail-header { display: flex; align-items: center; gap: 8px; margin-bottom: 10px; min-height: var(--tap); }
.detail-header h2 { margin: 0; font-size: calc(16px * var(--ts)); font-weight: 600; letter-spacing: -0.01em; flex: 1; min-width: 0; }
.detail-header .detail-back, [data-detail-header="1"] [data-back="1"] { margin: 0 0 0 -6px; }

.row-actions { display: flex; align-items: center; gap: 8px; flex: none; flex-wrap: wrap; justify-content: flex-end; }

/* ---------- CaptureStrip ---------- */
.capture-strip { display: grid; grid-template-columns: repeat(4, 1fr); gap: 6px; margin-bottom: 10px; }
.capture-tile {
  font: inherit; text-align: center; padding: 12px 4px; min-height: var(--tap);
  background: var(--wa05); border: 0.5px solid var(--wa08);
  border-radius: var(--r-md); color: var(--text-secondary); cursor: pointer;
}
.capture-tile .icon { display: block; font-size: calc(18px * var(--ts)); margin-bottom: 2px; }
.capture-tile .label { font-size: calc(9.5px * var(--ts)); color: var(--text-muted); }
.capture-tile[aria-pressed="true"] { background: var(--action-tint); border-color: rgba(107,159,212,0.3); }
.capture-tile[aria-pressed="true"] .label { color: var(--action-tint-text); }

/* ---------- EmptyState ---------- */
.empty-state { text-align: center; padding: 28px 16px; }
.empty-state .glyph { font-size: calc(26px * var(--ts)); color: var(--text-muted); display: block; margin-bottom: 6px; }
.empty-state .title { margin: 0 0 2px; font-size: calc(13.5px * var(--ts)); font-weight: 600; color: var(--text-secondary); }
.empty-state .sub { margin: 0; font-size: calc(12px * var(--ts)); color: var(--text-muted); line-height: 1.5; }

/* ---------- StaleBadge ---------- */
.stale-badge {
  display: inline-flex; align-items: center; gap: 5px;
  font-size: calc(10.5px * var(--ts)); font-weight: 600; padding: 3px 10px;
  border-radius: var(--r-pill); background: var(--wait-bg); color: var(--wait-fg);
  border: 0.5px solid rgba(212,180,90,0.3);
}
.stale-badge::before { content: "◷"; font-size: calc(12px * var(--ts)); }

/* ---------- Scrim + Sheet (scoped to the SHELL) ---------- */
.scrim {
  position: absolute; inset: 0; z-index: 30;
  background: rgba(10,12,18,0.55);
  -webkit-backdrop-filter: blur(10px); backdrop-filter: blur(10px);
  display: flex; align-items: flex-end; justify-content: center;
}
[data-theme="light"] .scrim { background: rgba(40,44,52,0.35); }
.sheet {
  width: 100%; max-height: 88%; overflow-y: auto;
  background: var(--glass-strong);
  -webkit-backdrop-filter: blur(32px) saturate(200%); backdrop-filter: blur(32px) saturate(200%);
  border: 0.5px solid var(--glass-border);
  border-radius: var(--r-xl) var(--r-xl) 0 0; padding: 16px;
  box-shadow: inset 0 1px 0 var(--glass-highlight), 0 -12px 48px rgba(0,0,0,0.35);
}
@container shell (min-width: 720px) {
  .scrim { align-items: center; padding: 24px; }
  .sheet { max-width: 520px; border-radius: var(--r-xl); box-shadow: inset 0 1px 0 var(--glass-highlight), 0 24px 80px rgba(0,0,0,0.45); }
}
.sheet h3 { margin: 0 0 4px; font-size: calc(15px * var(--ts)); font-weight: 700; }
.sheet .sheet-sub { margin: 0 0 12px; font-size: calc(12px * var(--ts)); color: var(--text-secondary); line-height: 1.5; }

/* ---------- HandoverOverlay (blocks the PANEL, not the screen) ---------- */
.handover-overlay {
  position: absolute; inset: 0; z-index: 40;
  background: rgba(10,12,18,0.8);
  -webkit-backdrop-filter: blur(8px); backdrop-filter: blur(8px);
  overflow-y: auto; padding: 20px 14px;
}
[data-theme="light"] .handover-overlay { background: rgba(60,64,72,0.45); }
.handover-panel {
  max-width: 560px; margin: 0 auto;
  background: var(--glass-strong);
  -webkit-backdrop-filter: blur(32px) saturate(200%); backdrop-filter: blur(32px) saturate(200%);
  border: 0.5px solid var(--glass-border);
  border-radius: var(--r-xl); padding: 16px;
  box-shadow: inset 0 1px 0 var(--glass-highlight), 0 12px 48px rgba(0,0,0,0.4);
}
.handover-panel h3 { margin: 0 0 2px; font-size: calc(16px * var(--ts)); }
.handover-panel .ho-sub { margin: 0 0 12px; font-size: calc(12px * var(--ts)); color: var(--text-secondary); }
/* ---------- Today and Tasks: bounded staff header overlays (D42) ---------- */
/* Keep the native checkbox semantics, but make the whole labelled row its
   exclusive hit target instead of leaving a 13px control inside a 52px floor. */
[data-today-log] .check-label { position: relative; min-height: var(--tap); align-items: center; margin: 0; padding-left: 28px; }
[data-today-log] .check-label input { position: absolute; inset: 0; width: 100%; height: 100%; margin: 0; opacity: 0; cursor: pointer; }
[data-today-log] .check-label::before { content: ''; position: absolute; left: 0; width: 18px; height: 18px; border: 1px solid var(--border); border-radius: 4px; text-align: center; line-height: 18px; }
[data-today-log] .check-label:has(input:checked)::before { content: '✓'; background: var(--action-tint); color: var(--action-tint-text); }
[data-today-log] .check-label:focus-within { outline: 2px solid var(--action); outline-offset: 2px; }
/* Email selection keeps the native checkbox semantics while making the full
   52px lead cell its exclusive touch target. The visible mark stays compact. */
[data-email-select-target] { position: relative; display: block; flex: 0 0 var(--tap); width: var(--tap); height: var(--tap); }
[data-email-select-target] input { position: absolute; inset: 0; width: 100%; height: 100%; margin: 0; opacity: 0; cursor: pointer; }
[data-email-select-target]::before { content: ''; position: absolute; pointer-events: none; left: 50%; top: 50%;
  width: 18px; height: 18px; transform: translate(-50%, -50%); border: 1px solid var(--border);
  border-radius: 4px; text-align: center; line-height: 18px; color: var(--action-tint-text); }
[data-email-select-target]:has(input:checked)::before { content: '✓'; background: var(--action-tint); }
[data-email-select-target]:focus-within { outline: 2px solid var(--action); outline-offset: -2px; border-radius: var(--r-sm); }
/* Modal staff windows cover the dock; emergency notices still take priority. */
.handover-overlay:has(> .handover-panel[aria-modal="true"]) { z-index: 47; }
.scrim:has(> [role="alertdialog"]) { z-index: 70; }
.app-shell:has(> .scrim > [role="alertdialog"]) > .handover-overlay:has(> .handover-panel[aria-modal="true"]) {
  visibility: hidden;
}
.handover-panel:has([data-today-cols]),
.handover-panel:has([data-tasks-body]) {
  display: flex; flex-direction: column; gap: 8px;
  max-height: min(750px, calc(100dvh - 40px));
}
.handover-panel:has([data-today-cols]) { max-width: 1040px; }
.handover-panel:has([data-tasks-body]) { max-width: 700px; }
.handover-panel:has([data-today-cols]) > h3,
.handover-panel:has([data-today-cols]) > .ho-sub { flex-shrink: 0; }
@container shell (max-width: 719px) {
  /* One continuous scroller on a phone keeps both halves reachable instead
     of dividing a short screen into two unusably shallow scrolling slots. */
  [data-today-cols] { flex-direction: column !important; overflow-y: auto; }
  [data-today-cols] > [data-today-log],
  [data-today-cols] > [data-today-handover] { flex: none !important; overflow: visible !important; }
  [data-today-log] [data-shift-book] { overflow: visible !important; flex: none !important; }
}

/* ---------- Segmented (second-level navigation inside a pane) ---------- */
.segmented { display: flex; gap: 4px; padding: 3px; margin-bottom: 12px; border-radius: 10px; background: var(--surface-1); border: 0.5px solid var(--hairline); }
.seg-item { display: flex; align-items: center; justify-content: center; gap: 6px; flex: 1; padding: 7px 12px; border: 0; border-radius: 8px; background: transparent; color: var(--text-secondary); font: inherit; font-size: calc(13px * var(--ts)); font-weight: 550; cursor: pointer; }
.seg-item:hover { color: var(--text-primary); }
.seg-item[aria-current="true"], .seg-item[aria-selected="true"] { background: var(--surface-2); color: var(--text-primary); box-shadow: 0 1px 2px rgba(0,0,0,0.18); }
.seg-item .seg-n { font-size: calc(11px * var(--ts)); font-variant-numeric: tabular-nums; color: var(--text-muted); }

/* ---------- Dock (fixed corner stack, scoped to shell) ---------- */
/* The dock stack grows UPWARD from bottom-right, one 36px button per row plus
   a 6px gap. Its measured height is published as --dock-h on the SHELL by
   clerim.js so the popover can clear it exactly; every read carries a 44px
   fallback for the frame before the first measurement lands. */
/* gap 8, not 6: a 36px button + 8px gap is a 44px pitch, and the pitch is what
   a thumb gets. At gap 6 the 44px hit areas below overlapped and the later
   sibling won, so the measured target was 41px — see the note in shell.css. */
[data-dock-button] [data-dock-glyph] svg { width: 16px; height: 16px; }
[data-dock-button] {
  box-shadow: inset 0 1px 0 var(--glass-highlight), 0 6px 20px rgba(0,0,0,0.28);
}
/* Same size everywhere, and the label comes out sideways instead of widening
   the button ([data-reveal], below).
   ─── WHAT THIS REPLACES, AND WHY THE OLD ARGUMENT IS ANSWERED ──────────────
   Until 2026-08-13 the dock expanded to a labelled pill on hover, and stayed
   permanently labelled at [data-mode="desktop"], defended here by: "four
   unlabelled circles say it only to someone who already knows the system —
   discoverability by hover is discoverability for people who do not need it."
   That objection is right and it is met three other ways now: a phone never
   sees an icon-only nav (the drawer names every page in full), a touch user
   gets the name on a long press, and :focus-visible gives a keyboard user the
   same pill without a pointer. What is left open is a first-run state that
   shows every label for one shift — recorded in docs/design/FRAMEWORK.md
   §5.1 ("Open, on purpose"), not pretended away. */
[data-dock-button]::after {
  content: ""; position: absolute; left: 50%; top: 50%;
  width: var(--tap); height: var(--tap); transform: translate(-50%, -50%);
}
[data-dock-button]:hover, [data-dock-button]:focus-visible { background: var(--surface-2); }
/* Emergency. Colour is the whole of its distinction, so the tokens it names
   have to exist — they did not, and it read as a third grey circle. */
[data-dock-button][data-alert] {
  color: var(--status-warn);
  border-color: color-mix(in oklch, var(--status-warn) 45%, transparent);
  background: color-mix(in oklch, var(--warn-bg) 70%, var(--glass-strong));
}
[data-dock-button][data-alert]:hover, [data-dock-button][data-alert]:focus-visible {
  background: color-mix(in oklch, var(--warn-bg) 100%, var(--surface-2));
  border-color: var(--status-warn);
}
/* The Role views switcher is DEMO-ONLY (ADR-0005, founder 2026-08-10) and says
   so rather than sitting in the row as a fifth ordinary control. The dashed
   ring carries it at rest; the word rides on the revealed label, which is the
   only place there is room for it now. */
[data-dock-button][data-demo] [data-reveal]::after {
  content: "demo"; margin-left: 8px; padding: 1px 6px; border-radius: var(--r-pill);
  font-size: 0.8em; font-weight: 700; letter-spacing: 0.04em; text-transform: uppercase;
  background: var(--wa10); color: var(--text-muted);
}
/* [data-dock-count] is defined with .icon-badge further down — one count, one look,
   whichever piece of chrome is carrying it. */
@media (prefers-reduced-motion: reduce) { [data-dock-button] { transition: none; } }
[data-mode="mobile"] [data-dock] { bottom: 12px; right: 12px; }

/* ---------- DockPopover (grows out of the dock button that opened it) ---------- */
.dock-pop-scrim { position: absolute; inset: 0; z-index: 44; background: rgba(10,12,18,0.55); }
[data-theme="light"] .dock-pop-scrim { background: rgba(60,64,72,0.34); }
.dock-pop {
  /* Base posture. Non-chat popovers are re-centered by the overlay directive
     further down; chat keeps the corner anchor and clears the dock there. */
  position: absolute; right: 16px; bottom: calc(16px + var(--dock-h, 44px) + 12px); z-index: 46;
  width: min(760px, calc(100% - 32px)); max-height: min(560px, calc(100% - 120px));
  display: flex; flex-direction: column; overflow: hidden;
  border-radius: 24px; border: 0.5px solid var(--wa10); background: var(--glass-strong);
  -webkit-backdrop-filter: saturate(180%) blur(30px); backdrop-filter: saturate(180%) blur(30px);
  box-shadow: inset 0 1px 0 var(--glass-highlight), 0 20px 60px rgba(0,0,0,0.45);
  transform-origin: calc(100% - 22px) calc(100% + 44px);
  animation: dockPop 0.24s cubic-bezier(0.22,0.9,0.3,1) both;
}
@keyframes dockPop { from { opacity: 0; transform: scale(0.86) translateY(12px); } to { opacity: 1; transform: none; } }
@media (prefers-reduced-motion: reduce) { .dock-pop { animation: none; } }
.dock-pop-head { flex: none; display: flex; align-items: flex-start; gap: 12px; padding: 14px 16px 10px; border-bottom: 0.5px solid var(--wa10); }
.dock-pop-titles { flex: 1; min-width: 0; }
.dock-pop-head h3 { margin: 0; font-size: calc(16px * var(--ts)); }
.dock-pop-head p { margin: 2px 0 0; font-size: calc(12px * var(--ts)); color: var(--text-secondary); }
.dock-pop-x { flex: none; width: 28px; height: 28px; border-radius: 999px; border: 0.5px solid var(--wa10); background: transparent; color: var(--text-secondary); font-size: calc(12px * var(--ts)); cursor: pointer; }
.dock-pop-x:hover { background: var(--wa06); color: var(--text-primary); }
.dock-pop-body { flex: 1; min-height: 0; display: flex; }
/* The mobile posture lives with the other overlay anchors at the foot of
   this file, so a dock popover has ONE definition of where it sits. */

/* ---------- Bubble (a message in a thread) ---------- */
.bubble-line { display: flex; margin: 4px 0; }
.bubble-line.out { justify-content: flex-end; }
.bubble { display: flex; flex-direction: column; gap: 3px; max-width: 78%; padding: 8px 12px; border-radius: 18px; font-size: calc(13.5px * var(--ts)); line-height: 1.45; }
.bubble.in { background: var(--wa06); border: 0.5px solid var(--wa10); border-bottom-left-radius: 6px; }
.bubble.out { background: color-mix(in oklch, var(--accent) 26%, transparent); border: 0.5px solid color-mix(in oklch, var(--accent) 40%, transparent); border-bottom-right-radius: 6px; }
.bubble-who { font-size: calc(11px * var(--ts)); font-weight: 650; color: var(--text-secondary); }
.bubble-meta { display: flex; gap: 6px; align-items: center; font-size: calc(10.5px * var(--ts)); color: var(--text-muted); }
.bubble-channel { padding: 0 6px; border-radius: 999px; border: 0.5px solid var(--wa10); }

/* ---------- CommandPalette: sheet at compact, centred dialog at wide ---------- */
.palette-scrim { position: absolute; inset: 0; z-index: 60; background: rgba(10,12,18,0.6); -webkit-backdrop-filter: blur(8px); backdrop-filter: blur(8px); display: flex; align-items: stretch; justify-content: center; }
[data-theme="light"] .palette-scrim { background: rgba(40,44,52,0.35); }
.palette {
  display: flex; flex-direction: column; width: 100%; height: 100%;
  background: var(--glass-strong);
  -webkit-backdrop-filter: blur(32px) saturate(200%); backdrop-filter: blur(32px) saturate(200%);
  border: 0.5px solid var(--glass-border); padding: 12px;
}
/* Palette geometry lives with the other overlay anchors at the foot of this
   file — it is top-aligned and centred at every width now, not only wide ones. */
[data-palette-item][aria-selected="true"], [data-palette-item]:hover { background: var(--wa08); }
/* The withheld-count line. It sits beside the listbox rather than inside it —
   a listbox's children are options, and a note among them is both invalid ARIA
   and a miscount to anyone reading the list by its length. */

/* prefers-reduced-transparency: solidify overlays */
@media (prefers-reduced-transparency: reduce) {
  .sheet, .palette, .handover-panel, [data-toast] { -webkit-backdrop-filter: none; backdrop-filter: none; background: var(--surface-2); }
  .scrim, .palette-scrim, .handover-overlay { -webkit-backdrop-filter: none; backdrop-filter: none; }
}

/* ============================================================
   App additions (v1.0 screens) — still primitives, no per-screen
   styling. Everything below is restyle-safe vocabulary.
   ============================================================ */

/* ---------- Forms ---------- */
.field-label { display: block; font-size: calc(12px * var(--ts)); color: var(--text-muted); margin: 12px 0 5px; }
/* A real form still owns implicit Enter submission; this modifier carries
   the directory's one-line layout without making the surface own CSS. */
.open-form { display: flex; gap: 8px; }
.open-form .input { flex: 1; min-width: 0; }
.open-form .btn { flex: none; }
/* A credential pair (FormControls' CredentialField): the label sits directly
   under whatever introduces it, so it drops the rule above's 12px top, and the
   gap moves below the control instead. Was `#form .field-label` / `#form
   .input` in password.css, which the port retired. */
.cred-field { margin-bottom: 12px; }
.cred-field .field-label { margin-top: 0; }
/* A credential field that stands ALONE rather than in a run of them — the
   sign-in page's two authenticator-code boxes, which sit in the account
   panels and never had the form's flush rhythm. The label keeps the base
   rule's top margin and the field keeps no bottom one. */
.cred-field.spaced { margin-bottom: 0; }
.cred-field.spaced .field-label { margin-top: 12px; }
/* An alert category (FormControls' AlertCategoryField): a checkbox, its name,
   and the reason under it. Top-aligned, because the reason wraps and the box
   belongs beside the first line rather than the middle of the block. Was
   login.css's `.cat` group, which the port retired. */
.cat { display: flex; align-items: flex-start; gap: 10px; margin-top: 12px; }
.cat input { margin-top: 3px; flex: none; }
.cat .why { font-size: calc(12px * var(--ts)); color: var(--text-muted); display: block; }
.input, select.input, textarea.input {
  width: 100%; font: inherit; font-size: calc(15px * var(--ts)); color: var(--text);
  background: var(--field-bg); border: 0.5px solid var(--border);
  border-radius: var(--r-md); padding: 11px 13px; outline: none;
  box-sizing: border-box;
  /* 11+11 padding plus a 15px line came to 43px — one pixel under this design
     system's own --tap floor, on every field and every select in the product.
     Found by the rendered tap-target pass in scripts/a11y-scan.mjs. */
  min-height: var(--tap);
}
select.input option { background: var(--field-bg); color: var(--text); }
.input:focus { border-color: var(--border-strong); }
textarea.input { resize: vertical; min-height: 84px; }
.check-label { display: flex; align-items: flex-start; gap: 9px; font-size: calc(13px * var(--ts)); color: var(--text-secondary); margin: 12px 0 0; }
.check-label input { margin-top: 2px; }
[data-chat-routing] .check-label { position: relative; min-height: var(--tap); align-items: center; padding-left: 28px; }
[data-chat-routing] .check-label input { position: absolute; inset: 0; width: 100%; height: 100%; margin: 0; opacity: 0; cursor: pointer; }
[data-chat-routing] .check-label::before { content: ''; position: absolute; left: 0; width: 18px; height: 18px; border: 1px solid var(--border); border-radius: 4px; text-align: center; line-height: 18px; }
[data-chat-routing] .check-label:has(input:checked)::before { content: '✓'; background: var(--action-tint); color: var(--action-tint-text); }
[data-chat-routing] .check-label:focus-within { outline: 2px solid var(--action); outline-offset: 2px; }
[data-chat-routing] .check-label:has(input:disabled) { opacity: .55; }
.grid2 { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
@container shell (max-width: 519px) { .grid2 { grid-template-columns: 1fr; } }

/* ---------- Segmented mode control ---------- */
.modes { display: flex; gap: 6px; background: var(--wa05); border: 0.5px solid var(--border); border-radius: var(--r-pill); padding: 4px; margin-bottom: 16px; }
.modes button {
  flex: 1; font: inherit; font-size: calc(13px * var(--ts)); font-weight: 600; color: var(--text-secondary);
  background: none; border: 0; border-radius: var(--r-pill); padding: 8px 10px; min-height: 36px; cursor: pointer;
}
.modes button.active { color: var(--on-action); background: linear-gradient(180deg, var(--action-hover), var(--action)); }

/* ---------- Primary action button (full-width form submit) ---------- */
.btn.submit {
  width: 100%; margin-top: 16px; padding: 13px 16px; font-size: calc(15px * var(--ts)); border: 0;
  color: var(--on-action); background: linear-gradient(180deg, var(--action-hover), var(--action));
}
.btn.submit.compact { margin-top: 12px; }
.btn.submit:hover { color: var(--on-action); background: linear-gradient(180deg, var(--action-hover), var(--action)); filter: brightness(1.06); }
.btn.submit.danger { background: linear-gradient(180deg, var(--warn-fg), color-mix(in srgb, var(--warn-fg) 78%, #000)); color: var(--page); }
.btn:disabled { opacity: 0.5; cursor: not-allowed; }

/* ---------- Inline status message ---------- */
.msg { font-size: calc(13px * var(--ts)); color: var(--text-secondary); margin-top: 12px; min-height: 18px; }
.msg.ok { color: var(--ok-fg); }
.msg.warn { color: var(--warn-fg); }

/* ---------- Callout (tinted card: scripts, warnings, acks) ---------- */
.callout { margin-top: 12px; padding: 13px 15px; border-radius: var(--r-md); background: var(--wa05); border: 0.5px solid var(--wa10); font-size: calc(13px * var(--ts)); color: var(--text-secondary); }
.callout.warn { background: var(--warn-bg); border-color: var(--warn-border); color: var(--warn-fg); }
.callout.ok { background: var(--ok-bg); border-color: var(--ok-border); color: var(--ok-fg); }
.callout.wait { background: var(--wait-bg); border-color: var(--wait-border); color: var(--wait-fg); }
.callout p { margin: 0; line-height: 1.5; }
.kicker { font-size: calc(10.5px * var(--ts)); text-transform: uppercase; letter-spacing: 0.06em; font-weight: 700; margin-bottom: 5px; color: var(--text-muted); }
.callout.warn .kicker { color: var(--warn-fg); }

/* ---------- Copybox (tokenized links, codes) ---------- */
.copybox { margin-top: 14px; padding: 13px 15px; border-radius: var(--r-md); background: var(--wa05); border: 0.5px solid var(--border); }
.copybox .lbl { font-size: calc(11px * var(--ts)); color: var(--text-muted); margin-bottom: 6px; }
.copybox .copy-row { display: flex; gap: 8px; align-items: center; }
.copybox code { flex: 1; font-family: var(--font-mono); font-size: calc(12px * var(--ts)); color: var(--action-tint-text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; background: var(--wa08); padding: 8px 10px; border-radius: var(--r-sm); }

/* ---------- Compliance pill states (door verdicts) ---------- */
.pill.expiring { background: var(--wait-bg); color: var(--wait-fg); }
.pill.expired { background: var(--warn-bg); color: var(--warn-fg); }
.pill.missing { background: var(--wa08); color: var(--text-muted); }
.pill.pending { background: var(--violet-bg); color: var(--violet-fg); }
/* Coverage below the building's minimum (SPEC §4.7): a real shortfall, but not
   a closed door — the same caution tone as expiring, not the alarm of expired. */
.pill.insufficient { background: var(--wait-bg); color: var(--wait-fg); }
.pill.guest { background: var(--action-tint); color: var(--action-tint-text); }
.pill.lg { font-size: calc(12px * var(--ts)); padding: 4px 12px; }

/* ---------- Page header (inside a pane) ---------- */
.page-header { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; margin: 6px 0 14px; flex-wrap: wrap; }
.page-header h1 { font-size: calc(22px * var(--ts)); font-weight: 600; letter-spacing: -0.02em; margin: 0; }
.page-header .sub { font-size: calc(13px * var(--ts)); color: var(--text-secondary); margin: 2px 0 0; }
.section-title { font-size: calc(15px * var(--ts)); font-weight: 600; margin: 0 0 14px; }

/* ---------- Auth pages (no shell chrome) ---------- */
.auth-wrap {
  min-height: 100dvh; display: flex; flex-direction: column; align-items: center; justify-content: center;
  padding: 24px 18px; box-sizing: border-box;
  background: var(--page); background-image: var(--page-gradient); background-attachment: fixed;
  color: var(--text); font-family: var(--font-body); line-height: 1.5; -webkit-font-smoothing: antialiased;
}
.auth-card {
  width: 100%; max-width: 400px;
  background: var(--glass); -webkit-backdrop-filter: blur(20px) saturate(180%); backdrop-filter: blur(20px) saturate(180%);
  border: 0.5px solid var(--glass-border); border-radius: var(--r-lg); padding: 24px 22px;
  box-shadow: var(--elev-auth);
}
.auth-card h1 { font-size: calc(20px * var(--ts)); font-weight: 600; letter-spacing: -0.02em; margin: 0 0 4px; }
.auth-card .sub { font-size: calc(13px * var(--ts)); color: var(--text-secondary); margin: 0 0 8px; }
.auth-brand { display: flex; align-items: center; gap: 8px; margin-bottom: 18px; font-size: calc(14px * var(--ts)); font-weight: 700; }
/* The workspace a /w/<slug>/login page was opened for (ADR-0006). Sized above
   the subtitle because it is the answer to "am I at the right door" — the one
   thing somebody checks before typing a password on a shared desk tablet. */
/* A quiet divider inside the auth card — separates the device controls
   (ADR-0007) from the account actions above them. */
.auth-card .rule { border: 0; border-top: 0.5px solid var(--wa10); margin: 18px 0 14px; }
.auth-card .workspace-name { margin: 0 0 4px; font-size: calc(19px * var(--ts)); font-weight: 650; color: var(--text-primary); line-height: 1.25; }
.auth-brand .mark { width: 24px; height: 24px; border-radius: 7px; background: var(--brand); color: var(--on-brand); display: flex; align-items: center; justify-content: center; font-size: calc(13px * var(--ts)); font-weight: 800; }
.auth-wrap .foot { margin-top: 16px; font-size: calc(12px * var(--ts)); color: var(--text-muted); text-align: center; }
.auth-wrap .foot a, .link { color: var(--action-tint-text); text-decoration: none; }
.link:hover, .auth-wrap .foot a:hover { text-decoration: underline; }
button.link { font: inherit; font-size: inherit; background: none; border: 0; padding: 0; cursor: pointer; }

/* Offline banner: the in-flow band in shell.css owns it (kit doctrine —
   a state change is a shell condition, not a floating toast). */
/* RN owns role-view layout; web keeps the hover affordance. */
[data-role-view]:hover { background: var(--wa10); }

/* ---------- report tags (flat labels, never fields) ----------
   Chips read as labels, not as settings — which is the same thing the shape of
   the data is defending (src/domain/tags.ts). Nothing here is editable in
   place: a tag is added or removed, never given a value. */
.rc-tagbox { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; }
.rc-tag-chips { display: contents; }
.rc-tag {
  display: inline-flex; align-items: center; gap: 4px;
  font-size: calc(12px * var(--ts)); padding: 3px 4px 3px 10px; border-radius: var(--r-pill);
  background: var(--wa06); border: 0.5px solid var(--wa10); color: var(--text-secondary);
  white-space: nowrap; max-width: 100%; overflow: hidden;
}
.rc-tag-x {
  font: inherit; line-height: 1; background: none; border: 0; cursor: pointer;
  color: var(--text-muted); padding: 0 4px; border-radius: var(--r-pill);
  /* A 44px target would blow the chip apart, so it gets the comfortable half:
     the chip is small, the × is reachable, and Backspace removes the last one
     without aiming at all. */
  min-height: 20px; min-width: 20px;
}
.rc-tag-x:hover { background: var(--warn-bg); color: var(--warn-fg); }
.rc-tagbox .rc-tags { flex: 1 1 160px; width: auto; min-width: 0; }
.rc-tag-hint { color: var(--warn-fg); }
.rc-tag-hint:empty { display: none; }

/* ---------- a pill that is a control, not a label ----------
   Filters, one-tap tag suggestions, the mode chips on a batch form. Same
   vocabulary as the read-only .pill so a filter and the state it filters on
   look like the same object — it just gets a tap target and a hover. Lived in
   concierge.html's <style> block until the parcel redesign needed it on two
   screens, which is the moment a page style becomes a primitive. */
button.pill {
  font: inherit; font-size: calc(10.5px * var(--ts)); font-weight: 600;
  border: 0; cursor: pointer; min-height: 28px; padding: 2px 12px;
}
button.pill:hover { background: var(--wa12); color: var(--text); }
button.pill.ok:hover { background: var(--ok-bg); color: var(--ok-fg); }
button.pill.wait:hover { background: var(--wait-bg); color: var(--wait-fg); }
button.pill.warn:hover { background: var(--warn-bg); color: var(--warn-fg); }
button.pill.action:hover { background: var(--action-tint); color: var(--action-tint-text); }

/* ---------- panel bar: a switcher and the panel's own actions in one line ----------
   The pattern the parcel panel introduced (2026-08-12): what you are looking
   at on the left, what you can add on the right, one bar, no card around it.
   The actions push right on their own rather than against a spacer element. */
.panel-bar { display: flex; align-items: center; gap: 10px; margin-bottom: 12px; flex-wrap: wrap; }
.panel-bar .segmented { margin: 0; flex: 1 1 220px; max-width: 380px; }
.panel-bar .panel-bar-acts { display: flex; align-items: center; gap: 8px; margin-left: auto; flex-wrap: wrap; }
.panel-bar .btn { flex: none; white-space: nowrap; }

/* ---------- filter row: a search box and the counts you can narrow to ---------- */
.filter-row { display: flex; align-items: center; gap: 8px; margin-bottom: 12px; flex-wrap: wrap; }
.filter-row .input { margin: 0; flex: 1 1 220px; font-size: calc(13px * var(--ts)); }

/* A card that is currently taking input, distinguished from the ones merely
   being read. Same construction as .setup-card — the accent mixed into the
   border rather than a second border color invented for one screen. */
.card.card-live { border-color: var(--action-border); }

/* ---------- parcel batch intake (SPEC §8.1) ----------
   One line per parcel, because the desk receives them by the trolley-load and
   a form that files one at a time makes a concierge choose between logging the
   stack and serving the person in front of them. The grid is the whole idea:
   Tab crosses a line, Enter starts the next.

   At compact the six columns become two and every cell names itself — the
   column header the phone cannot afford is moved onto the cell. The labels are
   presentational only; each control keeps its own aria-label at every width. */
.parcel-batch-head, .parcel-line {
  display: grid;
  grid-template-columns: 128px minmax(0, 1.05fr) minmax(0, 1fr) 88px 104px 26px;
  gap: 10px;
}
.parcel-batch-head { align-items: start; padding: 0 2px 6px; font-size: calc(12px * var(--ts)); color: var(--text-muted); }
.parcel-line { align-items: center; padding: 8px 2px; border-top: 0.5px solid var(--wa06); }
.pb-cell { min-width: 0; }
.pb-cell::before {
  content: attr(data-label);
  display: none; font-size: calc(11px * var(--ts)); color: var(--text-muted); margin-bottom: 4px;
}
.pb-cell .input { margin: 0; width: 100%; }
.pb-cell.pb-what .input { font-size: calc(13px * var(--ts)); }
.pb-cell .check-label { margin: 0; justify-content: center; }
.pb-cell .check-label span { font-size: calc(12px * var(--ts)); }
/* "Away" is a yes/no; "until when" only exists once the answer is yes, so the
   date appears under the box rather than sitting there asking to be filled in
   for every parcel that is not on hold. */
/* The unit and, once it resolves to somebody, who the parcel is for. Stacked
   because the second question only exists after the first is answered. */
.pb-unit { display: flex; flex-direction: column; gap: 4px; }
.pb-unit .input[data-f="recipient"] { font-size: calc(11px * var(--ts)); padding: 4px 6px; min-height: 28px; }
.pb-hold { display: flex; flex-direction: column; gap: 4px; align-items: center; }
.pb-hold .input { font-size: calc(11px * var(--ts)); padding: 4px 6px; min-height: 28px; text-align: center; }
.pb-drop { justify-self: center; }
.batch-foot { display: flex; align-items: center; gap: 8px; margin-top: 12px; flex-wrap: wrap; }
.batch-foot .btn { flex: none; white-space: nowrap; }

@container shell (max-width: 719px) {
  .parcel-batch-head { display: none; }
  .parcel-line { grid-template-columns: 1fr 1fr; gap: 8px; padding: 12px 2px; align-items: end; }
  .pb-cell::before { display: block; }
  .pb-cell.pb-tags, .pb-cell.pb-what { grid-column: 1 / -1; }
  .pb-cell .check-label { justify-content: flex-start; }
  .pb-drop { justify-self: end; align-self: center; }
}

/* ---------- emergency procedures (SPEC §8.1) ----------
   Read under stress: big tap targets, numbered steps, the number to dial
   first pulled out of the prose and made tappable. */
[data-procedure-summary]:hover { background: var(--wa06); border-radius: var(--r-sm); }
[data-procedure-full-link]:hover { text-decoration: underline; }

/* ---------- Chat popover: contacts beside the conversation (dock chat) ---------- */
.chat-pop .dock-pop-body { align-items: stretch; }

/* ---------- monochrome icon sizing (the SVG glyph set in clerim.js) ---------- */
.icon-btn, [data-icon-btn] { position: relative; }
.icon-btn svg, [data-icon-btn] svg, [data-shell-search] [data-search-glyph] svg { width: 16px; height: 16px; display: block; }
[data-nav-item] .glyph svg { width: 18px; height: 18px; display: block; margin: 0 auto; }
.dock-glyph svg { width: 18px; height: 18px; display: block; }

/* ---------- the reveal: one recipe, three hosts (2026-08-13) ----------
   Every button in the chrome is a single glyph at reading size, and the word
   it used to carry emerges from the button's INTERIOR-facing edge: rail labels
   slide right, header labels drop down, dock labels slide left. It is the SAME
   element renderNav and dockButton already emitted — it stops taking layout
   and gets positioned instead — so nothing left the accessibility tree.

   The complaint this answers: the chrome was three different things at once —
   bare icons in the header, icon-over-label in the rail, full-width labelled
   pills in the dock — so nothing read as one system. */
[data-reveal] {
  position: absolute; z-index: 60; pointer-events: none; white-space: nowrap;
  font-family: var(--font-body); font-size: calc(12px * var(--ts)); font-weight: 600;
  letter-spacing: -0.01em; line-height: 1.15;
  color: var(--text); padding: .5em .85em; border-radius: var(--r-pill);
  background: var(--glass-strong); border: 0.5px solid var(--glass-border);
  -webkit-backdrop-filter: blur(20px) saturate(180%); backdrop-filter: blur(20px) saturate(180%);
  box-shadow: inset 0 1px 0 var(--glass-highlight), 0 8px 24px rgba(0,0,0,0.34);
  opacity: 0;
  transition: opacity .13s ease, transform .28s cubic-bezier(.32,.72,0,1);
  transition-delay: 0s;
}
/* NO max-width: a nowrap pill has to size to its content. "Something's not
   right" overruns any cap once OpenDyslexic is the reading face. */
.has-reveal { position: relative; -webkit-user-select: none; user-select: none; touch-action: manipulation; }
[data-has-reveal] { position: relative; -webkit-user-select: none; user-select: none; touch-action: manipulation; }
.has-reveal:hover > [data-reveal],
.has-reveal:focus-visible > [data-reveal] { opacity: 1; transition-delay: .1s; }
[data-has-reveal]:hover > [data-reveal],
[data-has-reveal]:focus-visible > [data-reveal] { opacity: 1; transition-delay: .1s; }

/* Offsets are in em so the clearance grows with the label's own type size —
   the pill can never sit on the glyph it belongs to. It still STARTS tucked
   under the button; the gap is what it settles into, and transform-origin is
   the button-facing edge so it grows OUT OF the button rather than fading in
   beside it. */
.nav-rail [data-reveal] { left: 100%; top: 50%; transform-origin: left center; transform: translate(-1.4em,-50%) scale(.92); }
.nav-rail [data-has-reveal]:hover > [data-reveal],
.nav-rail [data-has-reveal]:focus-visible > [data-reveal] { transform: translate(.75em,-50%) scale(1); }

.shell-header [data-reveal] { top: 100%; right: 0; transform-origin: top right; transform: translateY(-1.1em) scale(.92); }
.shell-header .has-reveal:hover > [data-reveal],
.shell-header .has-reveal:focus-visible > [data-reveal] { transform: translateY(.6em) scale(1); }
.shell-header [data-has-reveal]:hover > [data-reveal],
.shell-header [data-has-reveal]:focus-visible > [data-reveal] { transform: translateY(.6em) scale(1); }

[data-dock] [data-reveal] { right: 100%; top: 50%; transform-origin: right center; transform: translate(1.4em,-50%) scale(.92); }
[data-dock] [data-has-reveal]:hover > [data-reveal],
[data-dock] [data-has-reveal]:focus-visible > [data-reveal] { transform: translate(-.75em,-50%) scale(1); }

@media (prefers-reduced-motion: reduce) { [data-reveal] { transition: none; } }

/* Touch has no hover, so the trigger is a long press (380ms — the platform
   threshold; a tap still taps). The shell carries data-press=<id> while the
   finger is down and the button carries data-lp=<id>; clerim.js sets both. */
.app-shell[data-press="pages"]     .shell-header [data-lp="pages"] > [data-reveal],
.app-shell[data-press="notices"]   .shell-header [data-lp="notices"] > [data-reveal],
.app-shell[data-press="arrivals"]  .shell-header [data-lp="arrivals"] > [data-reveal],
.app-shell[data-press="today"]     .shell-header [data-lp="today"] > [data-reveal],
.app-shell[data-press="bell"]      .shell-header [data-lp="bell"] > [data-reveal],
.app-shell[data-press="settings"]  .shell-header [data-lp="settings"] > [data-reveal] {
  opacity: 1; transform: translateY(.6em) scale(1);
}
.app-shell[data-press="chat"]      [data-dock] [data-lp="chat"] > [data-reveal],
.app-shell[data-press="report"]    [data-dock] [data-lp="report"] > [data-reveal],
.app-shell[data-press="emergency"] [data-dock] [data-lp="emergency"] > [data-reveal],
.app-shell[data-press="roleviews"] [data-dock] [data-lp="roleviews"] > [data-reveal] {
  opacity: 1; transform: translate(-.75em,-50%) scale(1);
}

/* ---------- the count lens ----------
   What used to sit here was a solid --status-warn disc with #1a1200 numerals:
   red on a glyph that is not an alarm, and an opaque hole cut in the icon
   underneath. The disc goes entirely. What is left is a frosted lens running
   OPPOSITE the ground (--lens-1/--lens-2, tokens.css) with the numeral in
   --text, at ONE size for the header and the dock — they were 15px and 18px,
   which is two answers to one question. */
.icon-badge, [data-icon-badge], [data-dock-button] [data-dock-count] {
  position: absolute; text-align: center; pointer-events: none;
  top: -.66em; right: -.66em;
  min-width: 2.5em; height: 2.5em; padding: 0 .42em;
  border-radius: var(--r-pill); border: 0; box-shadow: none;
  background: radial-gradient(closest-side circle at 50% 48%,
    var(--lens-1) 38%, var(--lens-2) 66%, transparent 100%);
  isolation: isolate; z-index: 0;         /* so the halo below can sit at -1 */
  color: var(--text);
  font-size: calc(10px * var(--ts)); font-weight: 700; line-height: 2.5em;
  letter-spacing: 0; font-variant-numeric: tabular-nums;
}
/* The outer falloff. NO backdrop-filter: a filtered region is clipped to its
   own box — it paints a hard square whatever the radius says — and a filtered
   layer sharing the box with the numeral samples over it. Both were tried;
   layered translucency is what works. */
.icon-badge::before, [data-icon-badge]::before, [data-dock-button] [data-dock-count]::before,
.badge-dot::before, [data-badge-dot]::before {
  content: ""; position: absolute; inset: -.2em; border-radius: 999px; z-index: -1;
  background: radial-gradient(closest-side circle at 50% 45%,
    var(--lens-1) 30%, var(--lens-2) 58%, transparent 100%);
  pointer-events: none;
}
/* Where the number carries no meaning, a dot: same circle, same place. */
.badge-dot {
  position: absolute; font-size: calc(10px * var(--ts)); top: -.66em; right: -.66em;
  width: 2.5em; height: 2.5em; padding: 0; min-width: 0; border-radius: 999px;
  background: radial-gradient(closest-side circle at 50% 50%,
    var(--lens-1) 38%, var(--lens-2) 66%, transparent 100%);
  box-shadow: none; isolation: isolate; z-index: 0; pointer-events: none;
}
.badge-dot::after {   /* a solid disc, not a gradient stop, so its edge is real */
  content: ""; position: absolute; top: 50%; left: 50%;
  width: .8em; height: .8em; margin: -.4em 0 0 -.4em;
  border-radius: 999px; background: var(--dot-core);
}
[data-badge-dot] {
  position: absolute; font-size: calc(10px * var(--ts)); top: -.66em; right: -.66em;
  width: 2.5em; height: 2.5em; padding: 0; min-width: 0; border-radius: 999px;
  background: radial-gradient(closest-side circle at 50% 50%,
    var(--lens-1) 38%, var(--lens-2) 66%, transparent 100%);
  box-shadow: none; isolation: isolate; z-index: 0; pointer-events: none;
}
[data-badge-dot]::after {
  content: ""; position: absolute; top: 50%; left: 50%;
  width: .8em; height: .8em; margin: -.4em 0 0 -.4em;
  border-radius: 999px; background: var(--dot-core);
}

/* ---------- Settings (the cog that used to leave the screen) ----------
   The account link was an <a> to /login.html?account=1: the only piece of
   chrome that answered a click by unloading the surface somebody was working
   on. It is a popover now, and the three things it holds are the ones a person
   needs to change WHERE THEY ARE — how big the type is, which face it is set
   in, and only then, who they are signed in as.

   Anchored under the cog rather than centred: it is a top-bar overlay by the
   directive at the foot of this file, and the bar it came out of is 44px tall.
   Everything inside is em-based, so the panel fits at every font and scale
   combination it can be asked to render itself in. */
.settings-scrim { position: absolute; inset: 0; z-index: 49; }
.settings-pop {
  position: absolute; top: calc(44px + 6px); right: 10px; z-index: 50;
  width: max-content; min-width: 22em; max-width: min(26em, calc(100% - 20px));
  display: flex; flex-direction: column; max-height: calc(100% - 60px); overflow-y: auto;
  padding: 1.1em; border-radius: var(--r-lg);
  background: var(--glass-strong); border: 0.5px solid var(--glass-border);
  -webkit-backdrop-filter: blur(32px) saturate(200%); backdrop-filter: blur(32px) saturate(200%);
  box-shadow: inset 0 1px 0 var(--glass-highlight), 0 20px 60px rgba(0,0,0,0.45);
  font-size: calc(13px * var(--ts));
  transform-origin: top right;
  animation: settingsPop .2s cubic-bezier(.32,.72,0,1) both;
}
@keyframes settingsPop { from { opacity: 0; transform: translateY(-6px) scale(.96); } to { opacity: 1; transform: none; } }
/* A left-opening child cannot escape a scrolling ancestor. Suspend the main
   scroller only while either controlled secondary panel is present. */
.settings-pop:has([data-workspace-panel]), .settings-pop:has([data-settings-secondary]) {
  max-height: none; overflow: visible;
  /* These create the containing block that would make a fixed secondary
     relative to Settings instead of the shell. The secondary keeps glass. */
  animation: none; transform: none;
  -webkit-backdrop-filter: none; backdrop-filter: none;
}
@media (prefers-reduced-motion: reduce) { .settings-pop { animation: none; } }
.settings-pop .field-label { margin: 0 0 5px; }
.settings-pop .input { font-size: calc(13px * var(--ts)); padding: 9px 11px; }
[data-settings-choice]:hover [data-settings-choice-label] { color: var(--text-primary); }
[data-settings-choice][aria-current="true"] { box-shadow: 0 1px 2px rgba(0,0,0,0.18); }
[data-settings-row]:hover { background: var(--wa08); }
[data-workspace-switcher], [data-effects-switcher] { position: relative; }
[data-workspace-panel], [data-settings-secondary] {
  /* The containing switcher begins inside the main popover's 1.1em padding.
     Fixed positioning gives both role rows the same shell-top anchor and
     keeps a 700px panel reachable instead of clipping it below its trigger. */
  position: fixed; top: 52px;
  right: calc(min(26em, calc(100cqw - 20px)) + 20px); z-index: 1;
  width: min(34em, calc(100cqw - 40px)); max-height: min(700px, calc(100cqh - 64px));
  overflow-y: auto; padding: 1em; border-radius: var(--r-lg);
  background: var(--glass-strong); border: 0.5px solid var(--glass-border);
  -webkit-backdrop-filter: blur(32px) saturate(200%); backdrop-filter: blur(32px) saturate(200%);
  box-shadow: inset 0 1px 0 var(--glass-highlight), 0 20px 60px rgba(0,0,0,0.45);
}
[data-workspace-role]:hover, [data-workspace-trigger]:hover { background: var(--wa08); }
/* Two side-by-side settings panels need up to 1,056px at larger text. Key the contained
   posture to the shell's actual width and leave room for the 1.3× text
   preference, rather than relying on the coarse phone mode label. */
@container shell (max-width: 1055px) {
[data-workspace-panel], [data-settings-secondary] {
  position: fixed; top: 52px; left: 12px; right: 12px; width: auto;
  max-height: calc(100cqh - 64px);
}
}
@media (prefers-reduced-transparency: reduce) {
  .settings-pop, [data-workspace-panel], [data-settings-secondary], [data-reveal] {
    -webkit-backdrop-filter: none; backdrop-filter: none; background: var(--surface-2);
  }
}

/* OpenDyslexic's letters lean on their own weight; a hair of tracking keeps
   them from touching at small sizes. The face and the scale that goes with it
   are tokens (tokens.css, READING PREFERENCES) — this is the one part of the
   preference that is appearance rather than a value. */
.app-shell[data-reading-font="dyslexic"] { letter-spacing: 0.01em; }

/* ---------- where an overlay sits (revised 2026-08-09) ----------
   An overlay is anchored by WHERE IT CAME FROM, and every measurement is a
   percentage of the shell — never a fixed pixel guess, because the shell is
   whatever size the window is and half a screen is a normal way to work.

     • from the bottom-corner DOCK  → the corner it grew out of
     • from the TOP BAR             → top-aligned, horizontally centred
     • from anywhere in a page      → centred in the shell

   ─── THE BUG THIS REPLACES ────────────────────────────────────────────────
   The previous directive centred every popover with
       .dock-pop { left: 50%; top: 50%; transform: translate(-50%,-50%); }
   which never took effect. .dock-pop runs `animation: dockPop … both`, and
   that animation's `to` keyframe sets `transform: none`. Animations outrank
   normal declarations in the cascade, so with fill-mode `both` the identity
   transform won permanently: the panel's top-LEFT corner sat at the centre of
   the shell and grew right and down out of the window. Measured before the
   fix: 760px wide starting at x=480 in a 960px shell — 280px off the right
   edge, and 110px off the bottom at every width.

   The lesson generalises: if an element is animated with a keyframe that
   touches `transform`, its POSITION must not depend on `transform`. Every
   anchor below uses inset properties, so the animation cannot move anything.
   ────────────────────────────────────────────────────────────────────────── */

/* Page-level overlays: centred in the shell. */
.scrim { align-items: center; padding: 20px; }
.sheet { max-width: 520px; border-radius: var(--r-xl); box-shadow: inset 0 1px 0 var(--glass-highlight), 0 24px 80px rgba(0,0,0,0.45); }

/* Dock overlays: the corner they grew out of, clearing the button stack.
   --dock-h is MEASURED and published on the shell by clerim.js — the stack is
   two buttons or three depending on rank, so a fixed guess opened the panel
   straight through the icons. Chat had this posture already; it is now what
   every dock popover does, which is what the founder asked for. */
.dock-pop {
  left: auto; top: auto; right: 16px;
  bottom: calc(16px + var(--dock-h, 44px) + 12px);
  max-height: calc(100% - var(--dock-h, 44px) - 96px);
}
/* On a phone a dock popover spans the width less a gutter — there is no room
   for it to be anything else, and `width: auto` with both insets set is what
   makes it track the shell rather than a guessed pixel width. */
[data-mode="mobile"] .dock-pop {
  left: 12px; right: 12px; width: auto;
  bottom: calc(12px + var(--dock-h, 44px) + 10px);
  max-height: calc(100% - var(--dock-h, 44px) - 84px);
}
/* …except chat, which was explicitly left alone. Its phone posture is
   shrink-to-fit off the right edge (left:auto + width:auto), NOT full-bleed —
   measured at 334px wide starting at x=89 in a 430px shell, and it still is.
   Folding it into the rule above would have widened it to 406px, which is a
   change to the one panel that was supposed to see none. */
[data-mode="mobile"] .dock-pop.chat-pop {
  left: auto; right: 8px; width: auto;
}

/* Top-bar overlays: top-aligned, horizontally centred, at EVERY width — the
   palette used to go full-bleed below 1120px, which is a different shape on a
   half-width window than on a wide one for no reason a user could predict. */
.palette-scrim { align-items: flex-start; padding: 60px 20px; }
.palette {
  height: auto; max-height: calc(100% - 120px); max-width: 560px;
  border-radius: var(--r-lg); box-shadow: 0 24px 80px rgba(0,0,0,0.45);
}
[data-mode="mobile"] .palette-scrim { padding: 16px 12px; }
[data-mode="mobile"] .palette { max-height: calc(100% - 32px); }

/* ---------- the report capture (SPEC §8.4) ----------
   The report form has TWO hosts — the /report.html pane and the dock's Report
   popover — and exactly one definition (Clerim.reportCapture). Its appearance
   therefore has to live here, not in a page's <style> block, or the quick
   report would be a different-looking form than the one it claims to be. */
.report-capture .section-title .pill { margin-left: 8px; }
.report-capture .rc-opt { font-weight: 400; color: var(--text-muted); }
/* The visit choice freezes once media is written under it. The hint says so in
   words; this is so the control looks the way the hint reads. */
.report-capture .input:disabled { opacity: 0.55; cursor: not-allowed; }
/* ---------- Hint: the small print under a control ----------
   Was scoped per-component twice before it earned a definition of its own;
   without one it inherits body size and shouts. */
.hint { font-size: calc(12px * var(--ts)); color: var(--text-muted); line-height: 1.5; }
.hint:empty { display: none; }

.report-capture .hint { margin-top: 6px; }
.report-capture .rc-phases { margin: 8px 0 4px; }
/* An upload or a model call that failed can never read as success. */
.report-capture .rc-banner {
  border-radius: var(--r-md); padding: 12px 14px; margin-bottom: 16px;
  font-size: calc(13.5px * var(--ts)); line-height: 1.45;
  background: var(--warn-bg); border: 0.5px solid var(--warn-fg); color: var(--warn-fg);
}
.report-capture .rc-banner[hidden] { display: none; }
.report-capture .ok-note { color: var(--ok-fg); }
.report-capture .thumbs { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 14px; }
.report-capture .thumb { width: 104px; border-radius: var(--r-sm); overflow: hidden; border: 0.5px solid var(--border); background: var(--wa06); }
.report-capture .thumb img,
.report-capture .thumb video { width: 104px; height: 78px; object-fit: cover; display: block; background: var(--wa10); }
.report-capture .thumb .cap { font-size: calc(10.5px * var(--ts)); padding: 5px 7px 3px; color: var(--text-muted); }
.report-capture .thumb .cap b { color: var(--text-secondary); text-transform: capitalize; }
.report-capture .thumb.up { opacity: 0.7; }
.report-capture .thumb.err { border-color: var(--warn-fg); background: var(--warn-bg); }
.report-capture .thumb .state { font-size: calc(10.5px * var(--ts)); padding: 0 7px 6px; }
.report-capture .thumb .state.uploading { color: var(--wait-fg); }
.report-capture .thumb .state.error { color: var(--warn-fg); font-weight: 600; }
.report-capture .retry { font: inherit; font-size: calc(11px * var(--ts)); font-weight: 600; color: var(--text-muted); background: none; border: 0; cursor: pointer; padding: 0 7px 7px; text-decoration: underline; }
.report-capture .thumb.err .retry { color: var(--warn-fg); }
.report-capture .ph-placeholder { width: 104px; height: 78px; display: flex; align-items: center; justify-content: center; font-size: calc(11px * var(--ts)); color: var(--text-muted); }
.report-capture .voice-row { display: flex; gap: 10px; flex-wrap: wrap; align-items: center; margin-top: 12px; }
.report-capture .dot { width: 9px; height: 9px; border-radius: 50%; background: var(--warn-fg); display: inline-block; animation: recPulse 1s infinite; }
@keyframes recPulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.25; } }
.report-capture .count { font-family: var(--font-mono); font-size: calc(13px * var(--ts)); color: var(--warn-fg); }
.report-capture audio { width: 100%; margin-top: 12px; }
.report-capture .transcript { margin-top: 12px; border: 0.5px solid var(--border); border-radius: var(--r-md); background: var(--wa06); padding: 0 14px; }
.report-capture .transcript[hidden] { display: none; }
.report-capture .transcript summary { cursor: pointer; font-size: calc(13px * var(--ts)); font-weight: 600; color: var(--text-secondary); padding: 11px 0; list-style: none; }
.report-capture .transcript summary::-webkit-details-marker { display: none; }
.report-capture .transcript p { font-size: calc(13.5px * var(--ts)); color: var(--text-secondary); white-space: pre-wrap; margin: 0 0 14px; }
.report-capture .edited { font-size: calc(11px * var(--ts)); color: var(--action-tint-text); margin-left: 6px; }
.report-capture .rc-again { font: inherit; font-size: calc(13px * var(--ts)); font-weight: 600; color: var(--action-tint-text); background: none; border: 0; padding: 0; cursor: pointer; text-decoration: underline; }
/* Mounted in the dock popover, the capture IS the scrolling body. */
.dock-pop-body > .report-capture { flex: 1; min-width: 0; overflow-y: auto; padding: 12px 14px 18px; }
.dock-pop-body > .report-capture .card { margin-bottom: 12px; }
.dock-pop-body > .report-capture .btn.submit { margin-top: 4px; }
/* A form reads better narrow than the 760px chat/procedures width. Position
   still comes from the dock anchor block above — this sets size only. */
.report-pop { width: min(560px, calc(100% - 32px)); }
/* Template row: the saved wording, and saving the wording you just typed. */
.report-capture .rc-save-row { margin-top: 14px; padding-top: 12px; border-top: 0.5px solid var(--wa10); }
.report-capture .rc-name-row { display: flex; gap: 8px; flex-wrap: wrap; align-items: center; }
.report-capture .rc-name-row .input { flex: 1; min-width: 180px; margin: 0; }
.report-capture .rc-save-hint:empty { display: none; }

/* ---------- the template customizer (Office / vendor) ----------
   Where a company keeps the wording it reports over and over. One definition,
   two hosts — see Clerim.templateEditor. */
.tpl-editor .hint { margin-top: 8px; }
.tpl-editor .tpl-scope { font-size: calc(12px * var(--ts)); color: var(--text-muted); margin: 0 0 12px; line-height: 1.5; }
.tpl-editor .tpl-list { margin-bottom: 12px; }
.tpl-editor .tpl-list .list-label { font-size: calc(10.5px * var(--ts)); font-weight: 600; letter-spacing: 0.06em; text-transform: uppercase; color: var(--text-muted); margin: 12px 0 6px; }
.tpl-editor .tpl-list .list-label:first-child { margin-top: 0; }
.tpl-editor .tpl-actions { display: flex; gap: 8px; flex-wrap: wrap; }
.tpl-editor .tpl-form { margin-top: 14px; padding-top: 12px; border-top: 0.5px solid var(--wa10); }
.tpl-editor .tpl-form-actions { display: flex; gap: 8px; flex-wrap: wrap; margin-top: 12px; }
.tpl-editor .row-actions .row-sub { font-size: calc(10.5px * var(--ts)); color: var(--text-muted); }
.tpl-editor .tpl-msg:empty { display: none; }
