/* ============================================================================
   AMS-Triage · 运维分诊助手 — app composition layer
   Built on the Acloudear UX/UI Design Standard v1.2 · 2026-10-15 (tokens.css, copied
   unchanged and loaded first). This file is composition only.

   Rules held here:
   1. Colour, type, spacing, radius, elevation, motion and control sizes come
      from standard tokens. No literal colour anywhere.
   2. Values the standard does not model are declared ONCE, below, as app
      layout tokens (the screen frame: rail, panel, drawer, modal, column
      minimums). They are the PRD's product-scope dimensions, held on the
      standard's 4px grid. See 01-UI-SPEC §2.3.
   3. Border widths use only 1px / 2px / 3px — the widths the standard itself
      specifies (1px card and divider lines, 2px focus ring, 3px accent bar).
      Every other dimension is a token or a calc() of tokens.
   4. Light is canonical. Dark comes from tokens.css with no component fork.
   ============================================================================ */

/* --- The screen frame (the standard has no tokens for these) --------------- */
:root {
  --app-rail: 76px;            /* PRD §9.9 — rail with text labels            */
  --app-drawer: 768px;         /* PRD §9.2 S3 — object & history drawer       */
  --app-panel: 440px;          /* PRD §9.2 S4 — source panel                  */
  --app-modal: 760px;          /* PRD §9.2 S2a — assignment pop-up            */
  --app-col-left-min: 300px;   /* PRD §9.3 — column minimums                  */
  --app-col-mid-min: 380px;
  --app-col-right-min: 340px;
  --app-scale-note: 1.2;       /* see 01-UI-SPEC §2.2 — documented, not applied */
}

/* --- Text on a filled button -----------------------------------------------
   Standard v1.2 answers this app's token request: `--color-on-primary` and
   `--color-on-danger` are the text colours ON a fill — white in light, the
   theme's dark ink in dark, because v1.2's dark fills are light blues and
   reds. Nothing is declared locally any more; the destructive button is a
   solid danger fill in both themes, as 02-COMPONENTS §1 specifies.
   Verified against the delivered palette with `tokens/contrast_check.py`
   (15 pairs × both themes, all pass): on-primary on the action fill
   7.13 light / 7.14 dark · on-danger on the danger fill 5.77 / 8.31.
   ------------------------------------------------------------------------- */

/* --- Base ---------------------------------------------------------------- */
* { box-sizing: border-box; }

svg { width: var(--size-icon-md); height: var(--size-icon-md); flex: none; }

html, body { height: 100%; }

body {
  margin: 0;
  font-family: var(--font-family-base);
  font-size: var(--fs-body);
  line-height: var(--lh-body);
  color: var(--color-text);
  background: var(--color-bg);
}

body.app-vh { overflow: hidden; }           /* workspace screens: columns scroll, page does not */

button, input, select, textarea { font: inherit; color: inherit; }

h1, h2, h3, p, ul, ol, dl, dd, figure { margin: 0; }
ul, ol { padding: 0; list-style: none; }

:focus-visible { outline: 2px solid var(--color-focus); outline-offset: 2px; }

.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: 0;
  overflow: hidden; clip-path: inset(50%); white-space: nowrap; border: 0;
}

.skip-link {
  position: absolute; left: var(--space-8); top: calc(var(--space-48) * -1);
  z-index: var(--z-tooltip); background: var(--color-surface);
  border: 1px solid var(--color-border-strong); border-radius: var(--radius-md);
  padding: var(--space-8) var(--space-12); color: var(--color-primary);
  font-weight: 600; text-decoration: none;
}
.skip-link:focus { top: var(--space-8); }

.mono { font-family: var(--font-family-mono); font-size: var(--fs-mono); line-height: var(--lh-mono); }
.num { font-variant-numeric: tabular-nums; }
.muted { color: var(--color-text-secondary); }
.cap { font-size: var(--fs-caption); line-height: var(--lh-caption); }
.cap.muted, .muted.cap { color: var(--color-text-secondary); }
.strong { font-weight: 600; }
.tone-ok { color: var(--color-success-text); font-weight: 600; }
.tone-wa { color: var(--color-warning-text); font-weight: 600; }
.tone-rd { color: var(--color-danger-text); font-weight: 600; }
.tone-pr { color: var(--color-primary); font-weight: 600; }
.stack-4 > * + * { margin-top: var(--space-4); }
.stack-8 > * + * { margin-top: var(--space-8); }
.stack-12 > * + * { margin-top: var(--space-12); }
.stack-16 > * + * { margin-top: var(--space-16); }

/* --- App shell ------------------------------------------------------------ */
.app { display: grid; grid-template-columns: var(--app-rail) 1fr; height: 100%; }

.rail {
  background: var(--color-surface);
  border-right: 1px solid var(--color-border);
  display: flex; flex-direction: column; align-items: center;
  gap: var(--space-8); padding-top: var(--space-16);
}
.rail-mark {
  width: var(--size-control-md); height: var(--size-control-md);
  border-radius: var(--radius-md); background: var(--color-brand-subtle);
  color: var(--color-brand); font-size: var(--fs-caption);
  font-weight: 700; display: grid; place-items: center; margin-bottom: var(--space-8);
}
.rail-i {
  position: relative; width: calc(var(--app-rail) - var(--space-8));
  padding: var(--space-8) 0; border: 0; background: none; cursor: pointer;
  border-radius: var(--radius-md); color: var(--color-text-secondary);
  font-size: var(--fs-caption); font-weight: 600;
  display: flex; flex-direction: column; align-items: center; gap: var(--space-4);
}
.rail-i svg { width: var(--size-icon-lg); height: var(--size-icon-lg); }
.rail-i:hover { background: var(--color-surface-subtle); }
.rail-i[aria-current="page"] { background: var(--color-primary-subtle); color: var(--color-primary); }
.rail-i[aria-current="page"]::before {
  content: ""; position: absolute; left: calc(var(--space-4) * -1); top: 0; bottom: 0;
  width: 3px; background: var(--color-primary); border-radius: 0 var(--radius-sm) var(--radius-sm) 0;
}

.main { display: flex; flex-direction: column; min-width: 0; min-height: 0; }

.hdr {
  display: flex; align-items: center; gap: var(--space-16);
  padding: var(--space-16) var(--space-24) var(--space-8);
}
.hdr-t { flex: 1; min-width: 0; }
.hdr-t h1 { font-size: var(--fs-display); line-height: var(--lh-display); font-weight: var(--fw-display); }
.hdr-t .sub { font-size: var(--fs-caption); line-height: var(--lh-caption); color: var(--color-text-secondary); }
.hdr-a { display: flex; align-items: center; gap: var(--space-8); }

.seg { display: flex; border: 1px solid var(--color-border); background: var(--color-surface);
  border-radius: var(--radius-md); padding: var(--space-4); }
.seg button { border: 0; background: none; color: var(--color-text-secondary); font-weight: 600;
  font-size: var(--fs-button); padding: var(--space-4) var(--space-12);
  border-radius: var(--radius-sm); cursor: pointer; height: 32px; }
.seg button[aria-pressed="true"] { background: var(--color-primary-subtle); color: var(--color-primary); }

/* --- The client-context bar (present on every screen, always whole) -------- */
.ctxbar {
  display: flex; align-items: center; gap: var(--space-16); flex-wrap: wrap;
  margin: 0 var(--space-24) var(--space-12);
  padding: var(--space-8) var(--space-16);
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-left: 3px solid var(--color-primary);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-1);
  position: relative; z-index: var(--z-sticky);
}
.ctxbar .it { display: flex; flex-direction: column; line-height: var(--lh-caption); }
.ctxbar .it small { font-size: var(--fs-caption); line-height: var(--lh-label); font-weight: 600;
  color: var(--color-text-secondary); }
.ctxbar .it b { font-weight: 600; }
.ctxbar .sp { flex: 1; }

/* --- View frame ----------------------------------------------------------- */
.view { flex: 1; min-height: 0; display: flex; flex-direction: column;
  position: relative; overflow: hidden; }
.page { padding: 0 var(--space-24) var(--space-24); overflow-y: auto; flex: 1; }

.cols {
  flex: 1; min-height: 0;
  display: grid;
  grid-template-columns:
    minmax(var(--app-col-left-min), 0.9fr)
    minmax(var(--app-col-mid-min), 1.25fr)
    minmax(var(--app-col-right-min), 1fr);
  grid-template-rows: auto minmax(0, 1fr);
  gap: var(--space-12) var(--space-16);
  padding: 0 var(--space-24) var(--space-24);
}
.cols > .l { grid-column: 1; grid-row: 1 / 3; }
.cols > .wf { grid-column: 2 / 4; grid-row: 1; }
.cols > .m { grid-column: 2; grid-row: 2; }
.cols > .r { grid-column: 3; grid-row: 2; }
.col { min-height: 0; display: flex; flex-direction: column; }
.col-t { display: flex; align-items: baseline; gap: var(--space-8); padding: 0 var(--space-4) var(--space-8); }
.col-t h2 { font-size: var(--fs-h3); line-height: var(--lh-h3); font-weight: var(--fw-h3); }
.sc { flex: 1; min-height: 0; overflow-y: auto; display: flex; flex-direction: column;
  gap: var(--space-12); padding: 0 var(--space-4) var(--space-8); }

/* --- Card ----------------------------------------------------------------- */
.card { background: var(--color-surface); border: 1px solid var(--color-border);
  border-radius: var(--radius-md); }
.card-h { display: flex; align-items: center; gap: var(--space-8); flex-wrap: wrap;
  padding: var(--space-12) var(--space-16); border-bottom: 1px solid var(--color-border); }
.card-h h3 { font-size: var(--fs-h3); line-height: var(--lh-h3); font-weight: var(--fw-h3);
  flex: 1 1 auto; min-width: 0; white-space: nowrap; }
.card-b { padding: var(--space-16); }
.card-n { padding: var(--space-8) var(--space-16) var(--space-12);
  font-size: var(--fs-caption); line-height: var(--lh-caption); color: var(--color-text-secondary); }
.card--accent { border-left: 3px solid var(--color-primary); }
.card--accent.wa { border-left-color: var(--color-warning-text); }
.card--accent.rd { border-left-color: var(--color-danger-text); }

/* --- Sticky page head (galleries) ---------------------------------------- */
.gal-h { position: sticky; top: 0; background: var(--color-bg); z-index: var(--z-sticky);
  padding: var(--space-8) 0 var(--space-8); }
.gal-h h2 { font-size: var(--fs-h2); line-height: var(--lh-h2); font-weight: var(--fw-h2); }

/* --- Chips & badges ------------------------------------------------------- */
.chip {
  display: inline-flex; align-items: center; gap: var(--space-4);
  height: var(--space-24); padding: 0 var(--space-8);
  border-radius: var(--radius-pill); background: var(--color-surface-subtle);
  color: var(--color-text-secondary); font-size: var(--fs-caption);
  line-height: var(--lh-caption); font-weight: 600; white-space: nowrap;
}
.chip--pr { background: var(--color-primary-subtle); color: var(--color-primary); }
.chip--ok { background: var(--color-success-subtle); color: var(--color-success-text); }
.chip--wa { background: var(--color-warning-subtle); color: var(--color-warning-text); }
.chip--rd { background: var(--color-danger-subtle); color: var(--color-danger-text); }
.chip--line { background: var(--color-surface); border: 1px solid var(--color-border-strong); color: var(--color-text-secondary); }

.badge {
  display: inline-flex; align-items: center; gap: var(--space-8);
  padding: var(--space-4) var(--space-12); border-radius: var(--radius-pill);
  font-size: var(--fs-body); font-weight: 600;
}
.badge small { font-size: var(--fs-caption); font-weight: 600; opacity: 0.9; }
.badge--wa { background: var(--color-warning-subtle); color: var(--color-warning-text); }
.badge--ok { background: var(--color-success-subtle); color: var(--color-success-text); }
.badge--pr { background: var(--color-primary-subtle); color: var(--color-primary); }
.badge--rd { background: var(--color-danger-subtle); color: var(--color-danger-text); }
.badge--nu { background: var(--color-surface-subtle); color: var(--color-text-secondary); }

/* Object-link chip (standard §13) */
.olink { display: inline-flex; align-items: center; gap: var(--space-4);
  background: var(--color-primary-subtle); color: var(--color-primary);
  border-radius: var(--radius-sm); padding: 0 var(--space-4);
  font-family: var(--font-family-mono); font-size: var(--fs-mono);
  text-decoration: none; }
.olink:hover { text-decoration: underline; }

/* Text link */
.tlink { background: none; border: 0; padding: 0; cursor: pointer;
  color: var(--color-primary); font-size: var(--fs-caption); font-weight: 600; }
.tlink:hover { text-decoration: underline; }

/* --- Key/value ------------------------------------------------------------ */
.kv { display: grid; grid-template-columns: calc(var(--space-48) * 2) 1fr;
  gap: var(--space-8) var(--space-12); }
.kv dt { color: var(--color-text-secondary); font-size: var(--fs-caption); line-height: var(--lh-caption); }
.kv dd { font-weight: 600; font-size: var(--fs-body); line-height: var(--lh-body); word-break: break-word; }

/* --- Buttons -------------------------------------------------------------- */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: var(--space-8);
  min-height: var(--size-control-md); padding: 0 var(--space-16);
  border: 1px solid var(--color-border-strong); background: var(--color-surface);
  color: var(--color-primary); border-radius: var(--radius-md);
  font-size: var(--fs-button); line-height: var(--lh-button); font-weight: var(--fw-button);
  cursor: pointer; white-space: nowrap;
}
.btn:hover { background: var(--color-surface-subtle); }
.btn:active { background: var(--color-primary-subtle); }
.btn--primary { background: var(--color-action-fill); border-color: var(--color-action-fill); color: var(--color-on-primary); }
.btn--primary:hover { background: var(--color-action-fill-hover); border-color: var(--color-action-fill-hover); }
.btn--primary:active { background: var(--color-action-fill-active); border-color: var(--color-action-fill-active); }
.btn--ghost { border-color: transparent; background: none; }
.btn--ghost:hover { background: var(--color-surface-subtle); }
.btn--danger { background: var(--color-danger-fill); border-color: var(--color-danger-fill); color: var(--color-on-danger); }
.btn--danger:hover { background: var(--color-danger-fill-hover); border-color: var(--color-danger-fill-hover); }
.btn--sm { min-height: var(--space-32); padding: 0 var(--space-12); }
.btn[disabled], .btn[aria-disabled="true"] {
  background: var(--color-disabled-bg); border-color: var(--color-border);
  color: var(--color-disabled-text); cursor: not-allowed; }
.btn[aria-busy="true"] { cursor: progress; }
.btns { display: flex; flex-wrap: wrap; gap: var(--space-8); align-items: center; }
.btns--col { flex-direction: column; align-items: stretch; }

.iconbtn { width: var(--size-control-md); height: var(--size-control-md); padding: 0;
  border: 1px solid var(--color-border); background: var(--color-surface);
  border-radius: var(--radius-md); color: var(--color-text-secondary); cursor: pointer;
  display: inline-grid; place-items: center; }
.iconbtn:hover { background: var(--color-surface-subtle); }
.iconbtn svg { width: var(--size-icon-md); height: var(--size-icon-md); }

/* --- Form controls -------------------------------------------------------- */
label { display: block; font-size: var(--fs-label); line-height: var(--lh-label);
  font-weight: var(--fw-label); color: var(--color-text-secondary);
  margin: var(--space-12) 0 var(--space-4); }
input[type="text"], input[type="date"], select, textarea {
  width: 100%; min-height: var(--size-control-md); padding: var(--space-8) var(--space-12);
  border: 1px solid var(--color-border-strong); border-radius: var(--radius-md);
  background: var(--color-surface); font-size: var(--fs-body); }
textarea { resize: vertical; }
.helper { font-size: var(--fs-caption); line-height: var(--lh-caption); color: var(--color-text-secondary);
  margin-top: var(--space-4); }
.counter { font-size: var(--fs-caption); line-height: var(--lh-caption); color: var(--color-text-secondary);
  font-variant-numeric: tabular-nums; }
.counter.over { color: var(--color-danger-text); font-weight: 600; }

/* --- Thread viewer -------------------------------------------------------- */
.thr { display: flex; flex-direction: column; gap: var(--space-12); }
.msg { position: relative; padding-left: var(--space-12); border-left: 3px solid transparent; }
.msg--joined { border-left-color: var(--color-primary); }
.msg-h { display: flex; align-items: center; gap: var(--space-4); flex-wrap: wrap;
  margin-bottom: var(--space-4); font-size: var(--fs-caption); line-height: var(--lh-caption);
  color: var(--color-text-secondary); }
.msg-t { white-space: pre-wrap; background: var(--color-surface-subtle);
  border-radius: var(--radius-md); padding: var(--space-8) var(--space-12); }
.join-note { font-size: var(--fs-caption); line-height: var(--lh-caption); color: var(--color-text-secondary);
  display: flex; align-items: center; gap: var(--space-4); }

/* --- Asks ----------------------------------------------------------------- */
.ask { display: flex; gap: var(--space-8); padding: var(--space-8) 0; border-bottom: 1px solid var(--color-border); }
.ask:last-child { border-bottom: 0; padding-bottom: 0; }
.ask-n { flex: none; width: var(--space-24); height: var(--space-24); border-radius: var(--radius-pill);
  background: var(--color-primary-subtle); color: var(--color-primary);
  display: grid; place-items: center; font-size: var(--fs-caption); font-weight: 600; }

/* --- Facts ---------------------------------------------------------------- */
.fact { display: inline-flex; align-items: center; gap: var(--space-4);
  background: var(--color-surface-subtle); border: 1px solid var(--color-border);
  border-radius: var(--radius-sm); padding: var(--space-4) var(--space-8);
  margin: 0 var(--space-4) var(--space-4) 0; font-size: var(--fs-caption); }
.fact i { font-style: normal; color: var(--color-text-secondary); }
.fact b { font-weight: 600; }
.fact i, .fact b { white-space: nowrap; }
.fact--missing { border-color: var(--color-warning-text); flex-wrap: wrap; max-width: 100%; }
.fact--missing b { color: var(--color-warning-text); }
.fact--locked { border-style: dashed; }
.fact--missing .why-miss { display: block; flex-basis: 100%; color: var(--color-warning-text);
  white-space: normal; }

/* --- Hero card ------------------------------------------------------------ */
.hero { border-left: 3px solid var(--color-primary); }
.hero--wa { border-left-color: var(--color-warning-text); }
.hero--rd { border-left-color: var(--color-danger-text); }
.hero h2 { font-size: var(--fs-h2); line-height: var(--lh-h2); font-weight: var(--fw-h2);
  margin: var(--space-8) 0 var(--space-4); }
.conf { display: flex; align-items: center; gap: var(--space-4); margin-top: var(--space-12);
  font-size: var(--fs-caption); color: var(--color-text-secondary); }
.conf i { width: var(--space-16); height: var(--space-4); border-radius: var(--radius-sm); background: var(--color-success); }
.conf i.off { background: var(--color-border); }

/* --- Why rows ------------------------------------------------------------- */
.why { display: flex; flex-direction: column; gap: var(--space-4); }
.why > div { background: var(--color-surface-subtle); border-radius: var(--radius-sm);
  padding: var(--space-8) var(--space-12); font-size: var(--fs-caption); line-height: var(--lh-caption); }

/* --- Recall rows ---------------------------------------------------------- */
.rec { padding: var(--space-12); border-radius: var(--radius-sm);
  background: var(--color-surface-subtle); }
.rec--top { background: var(--color-primary-subtle); }
.rec-h { display: flex; align-items: center; gap: var(--space-8); flex-wrap: wrap; margin-bottom: var(--space-4); }
.rec + .rec { margin-top: var(--space-8); }
.rec-applic { margin-top: var(--space-4); font-size: var(--fs-caption); line-height: var(--lh-caption); }

/* --- Banners -------------------------------------------------------------- */
.ban { display: flex; gap: var(--space-12); align-items: flex-start;
  padding: var(--space-12) var(--space-16); border-radius: var(--radius-md);
  border: 1px solid var(--color-border); background: var(--color-surface-subtle);
  font-size: var(--fs-body); line-height: var(--lh-body); }
.ban b { display: block; }
.ban svg { flex: none; width: var(--size-icon-md); height: var(--size-icon-md); margin-top: var(--space-4); }
.ban--pr { background: var(--color-primary-subtle); border-color: var(--color-primary); }
.ban--pr svg { color: var(--color-primary); }
.ban--ok { background: var(--color-success-subtle); border-color: var(--color-success-text); }
.ban--ok svg { color: var(--color-success-text); }
.ban--wa { background: var(--color-warning-subtle); border-color: var(--color-warning-text); }
.ban--wa svg { color: var(--color-warning-text); }
.ban--rd { background: var(--color-danger-subtle); border-color: var(--color-danger-text); }
.ban--rd svg { color: var(--color-danger-text); }

/* --- Hypothesis ----------------------------------------------------------- */
.hyp { border: 1px dashed var(--color-warning-text); border-radius: var(--radius-md);
  background: var(--color-warning-subtle); padding: var(--space-12); }
.hyp b.t { display: block; color: var(--color-warning-text); font-size: var(--fs-caption);
  margin-bottom: var(--space-4); }

/* --- Contract position strip ---------------------------------------------- */
.strip { display: flex; flex-direction: column; gap: var(--space-8); }
.strip .pos { display: flex; align-items: center; gap: var(--space-8); flex-wrap: wrap; }
.strip .boundary { font-size: var(--fs-caption); line-height: var(--lh-caption);
  color: var(--color-text-secondary); }

/* --- Workflow bar --------------------------------------------------------- */
.wf { display: flex; align-items: center; gap: var(--space-16);
  padding: var(--space-12) var(--space-16); }
.wfs { flex: 1; display: flex; }
.wfs > div { flex: 1; text-align: center; position: relative;
  font-size: var(--fs-caption); line-height: var(--lh-caption); color: var(--color-text-secondary); }
.wfs > div::before {
  content: ""; display: block; width: var(--space-24); height: var(--space-24);
  border-radius: var(--radius-pill); background: var(--color-surface);
  border: 2px solid var(--color-border); margin: 0 auto var(--space-4);
  position: relative; z-index: 2;
}
.wfs > div::after {
  content: ""; position: absolute; top: calc(var(--space-12) - 1px); left: 50%;
  width: 100%; height: 0; border-top: 2px solid var(--color-border);
}
.wfs > div:last-child::after { display: none; }
.wfs .done { color: var(--color-text); }
.wfs .done::before { background: var(--color-success); border-color: var(--color-success); }
.wfs .done::after { border-top-color: var(--color-success); }
.wfs .cur { color: var(--color-primary); font-weight: 600; }
.wfs .cur::before { border-color: var(--color-primary); }
.wfs .stop { color: var(--color-danger-text); font-weight: 600; }
.wfs .stop::before { border-color: var(--color-danger-text); }
.wfs .wfs-skip { color: var(--color-text-secondary); }
.wfs .wfs-skip::before { border-style: dashed; }
.wfs .crit { color: var(--color-text); font-weight: 600; }
.wfs .crit::before { background: var(--color-danger-fill); border-color: var(--color-danger-fill); }
.wfs small { display: block; font-size: var(--fs-caption); color: var(--color-text-secondary); font-weight: 400; }
.wfm { display: flex; flex-direction: column; align-items: flex-end; gap: var(--space-4); flex: none; }

/* --- Data table ----------------------------------------------------------- */
table.data { width: 100%; border-collapse: collapse; }
table.data th { text-align: left; font-size: var(--fs-label); line-height: var(--lh-label);
  font-weight: var(--fw-label); color: var(--color-text-secondary);
  background: var(--color-surface-subtle); padding: var(--space-8) var(--space-8);
  border-bottom: 1px solid var(--color-border); }
table.data td { padding: var(--space-8); border-bottom: 1px solid var(--color-border);
  height: var(--size-row); vertical-align: middle; }
table.data tr:last-child td { border-bottom: 0; }
table.data td.n, table.data th.n { text-align: right; font-variant-numeric: tabular-nums; }

/* --- Skeleton, progress, empty, error ------------------------------------- */
.skel { height: var(--space-16); border-radius: var(--radius-sm); background: var(--color-surface-subtle);
  margin: var(--space-8) 0; }
.skel--t { height: var(--space-24); }
.skel--b { height: var(--space-48); }
@media (prefers-reduced-motion: no-preference) {
  .skel { background-image: linear-gradient(90deg, var(--color-surface-subtle), var(--color-border), var(--color-surface-subtle));
    background-size: 200% 100%; animation: sk 1.2s linear infinite; }
  @keyframes sk { to { background-position: -200% 0; } }
}
.wip { display: flex; align-items: center; gap: var(--space-8); height: var(--space-32);
  padding: 0 var(--space-12); border-bottom: 1px solid var(--color-border);
  font-size: var(--fs-caption); color: var(--color-text-secondary); }
.spin { width: var(--space-12); height: var(--space-12); border-radius: var(--radius-pill);
  border: 2px solid var(--color-border); border-top-color: var(--color-primary); flex: none; }
@media (prefers-reduced-motion: no-preference) { .spin { animation: sp 0.8s linear infinite; } }
@keyframes sp { to { transform: rotate(360deg); } }
.prog li { display: flex; align-items: center; gap: var(--space-12); padding: var(--space-8) 0;
  color: var(--color-text-secondary); }
.prog li i { width: var(--space-16); height: var(--space-16); border-radius: var(--radius-pill);
  border: 2px solid var(--color-border); flex: none; }
.prog li.done { color: var(--color-text); }
.prog li.done i { background: var(--color-success); border-color: var(--color-success); }
.prog li.cur i { border-color: var(--color-primary); }
.empty { text-align: center; padding: var(--space-24) var(--space-16); }
.empty svg { width: var(--size-icon-lg); height: var(--size-icon-lg); color: var(--color-text-secondary); }
.empty h3 { font-size: var(--fs-h3); line-height: var(--lh-h3); font-weight: var(--fw-h3); margin-top: var(--space-8); }
.empty p { font-size: var(--fs-caption); line-height: var(--lh-caption); color: var(--color-text-secondary); margin-top: var(--space-4); }
.empty .btns { justify-content: center; margin-top: var(--space-16); }

/* --- Overlays: drawer, modal ---------------------------------------------- */
/* An overlay is always mounted INSIDE .view, which starts below the
   client-context bar. The bar is therefore never dimmed, clipped, covered or
   scrolled out (PRD gate 14); the rail and the page header stay whole too.
   The sheet dims the page behind it and traps focus. */
.ov { position: absolute; inset: 0; background: var(--color-overlay);
  display: flex; z-index: var(--z-overlay); }
.ov--modal { align-items: center; justify-content: center; padding: var(--space-24); }
.ov--drawer { justify-content: flex-end; align-items: stretch; }
.sheet { background: var(--color-surface); border: 1px solid var(--color-border);
  border-radius: var(--radius-lg); box-shadow: var(--shadow-3); display: flex; flex-direction: column;
  max-height: 100%; }
.modal { width: min(var(--app-modal), 100%); }
.drawer { width: min(var(--app-drawer), 100%); border-radius: 0; border-right: 0; border-top: 0; border-bottom: 0; }
.drawer--narrow { width: min(var(--app-panel), 100%); }
.sh-h { display: flex; align-items: center; gap: var(--space-12);
  padding: var(--space-16) var(--space-24); border-bottom: 1px solid var(--color-border); }
.sh-h h2 { font-size: var(--fs-h2); line-height: var(--lh-h2); font-weight: var(--fw-h2); flex: 1; }
.sh-scope { display: flex; align-items: center; gap: var(--space-8); flex-wrap: wrap;
  padding: var(--space-8) var(--space-24); border-bottom: 1px solid var(--color-border);
  font-size: var(--fs-caption); line-height: var(--lh-caption); color: var(--color-text-secondary); }
.sh-b { padding: var(--space-24); overflow-y: auto; flex: 1; }
.sh-f { display: flex; align-items: center; gap: var(--space-8);
  padding: var(--space-16) var(--space-24); border-top: 1px solid var(--color-border); }
.sh-f .sp { flex: 1; }
.note { font-size: var(--fs-caption); line-height: var(--lh-caption); color: var(--color-text-secondary); }

/* --- Overlay behind a sheet, rendered as a static page in this mockup ----- */
.app--dim { filter: none; }
.dim { position: absolute; inset: 0; background: var(--color-overlay); z-index: var(--z-overlay); }

/* --- Assignment candidate rows -------------------------------------------- */
.cand { display: grid; grid-template-columns: var(--space-24) 1.3fr 1.1fr 1fr 0.6fr var(--space-48);
  gap: var(--space-8); align-items: center; background: var(--color-surface-subtle);
  border: 2px solid transparent; border-radius: var(--radius-md);
  padding: var(--space-8) var(--space-12); cursor: pointer; }
.cand + .cand { margin-top: var(--space-8); }
.cand--sel { border-color: var(--color-primary); background: var(--color-primary-subtle); }
.cand--fail { opacity: 0.75; }
.cand .no { width: var(--space-24); height: var(--space-24); border-radius: var(--radius-pill);
  background: var(--color-border); display: grid; place-items: center;
  font-size: var(--fs-caption); font-weight: 700; }
.cand--sel .no { background: var(--color-primary); color: var(--color-primary-subtle); }
.cand .score { text-align: right; font-size: var(--fs-h2); font-weight: 700; color: var(--color-text-secondary);
  font-variant-numeric: tabular-nums; }
.cand--sel .score { color: var(--color-primary); }
.fx { font-size: var(--fs-caption); line-height: var(--lh-caption); color: var(--color-text-secondary);
  margin: 0 0 var(--space-8) var(--space-32); }

/* --- Reason chips --------------------------------------------------------- */
.opt { display: inline-flex; align-items: center; min-height: var(--space-32);
  border: 1px solid var(--color-border-strong); background: var(--color-surface);
  border-radius: var(--radius-pill); padding: 0 var(--space-12);
  font-size: var(--fs-caption); font-weight: 600; cursor: pointer;
  margin: 0 var(--space-4) var(--space-4) 0; }
.opt:hover { border-color: var(--color-primary); color: var(--color-primary); background: var(--color-primary-subtle); }
.opt--on { border-color: var(--color-primary); color: var(--color-primary); background: var(--color-primary-subtle); }

/* --- Candidate picker (shortlist) ----------------------------------------- */
.pick { display: grid; grid-template-columns: 1fr auto; gap: var(--space-8); align-items: center;
  border: 2px solid var(--color-border); border-radius: var(--radius-md); padding: var(--space-12);
  margin-bottom: var(--space-8); cursor: pointer; }
.pick:hover { border-color: var(--color-primary); background: var(--color-primary-subtle); }

/* --- Conversation --------------------------------------------------------- */
.chat .log { display: flex; flex-direction: column; gap: var(--space-12);
  padding: var(--space-16); max-height: calc(var(--space-48) * 4); overflow-y: auto; }
.bub { max-width: 85%; padding: var(--space-8) var(--space-12); border-radius: var(--radius-md);
  font-size: var(--fs-body); line-height: var(--lh-body); }
.bub--desk { align-self: flex-end; background: var(--color-primary-subtle);
  border-bottom-right-radius: var(--radius-sm); }
.bub--consultant { align-self: flex-start; background: var(--color-surface);
  border: 1px solid var(--color-border); border-bottom-left-radius: var(--radius-sm); }
.sysnote { align-self: center; text-align: center; font-size: var(--fs-caption);
  line-height: var(--lh-caption); color: var(--color-text-secondary); }
.cin { display: flex; gap: var(--space-8); padding: var(--space-12) var(--space-16);
  border-top: 1px solid var(--color-border); }
.cin input { flex: 1; }

/* --- State gallery -------------------------------------------------------- */
.grid { display: grid; gap: var(--space-12); }
.grid--5 { grid-template-columns: repeat(5, 1fr); }
.grid--3 { grid-template-columns: repeat(3, 1fr); }
.grid--2 { grid-template-columns: repeat(2, 1fr); }
.statecard { padding: var(--space-12); display: flex; flex-direction: column; gap: var(--space-4); }
.statecard h3 { font-size: var(--fs-body); line-height: var(--lh-body); font-weight: 600; }
.statecard p { font-size: var(--fs-caption); line-height: var(--lh-caption); color: var(--color-text-secondary); }
.statecard .sig { margin-top: auto; padding-top: var(--space-4); }

/* --- S1 group heading  (sprint-05 delta, one entry, reasoned) --------------
   `.pick-grp` — a labelled sub-group inside the S1 rehearsed-threads section.
   NEW because no delivered class expresses one: `.col-t` is a page-section head
   carrying an h2, `.card-h` belongs to a card, `.gal-h` is the S7 gallery's
   sticky head. Tokens only — no new token, no restyled sibling, no rename.
   Emitted by `s1-console-home.html` and by the app's S1 projection.
   ------------------------------------------------------------------------- */
.pick-grp { display: flex; align-items: baseline; gap: var(--space-8);
  margin: var(--space-16) 0 var(--space-8);
  font-size: var(--fs-label); line-height: var(--lh-label);
  font-weight: var(--fw-label); color: var(--color-text-secondary); }
.pick-grp:first-child { margin-top: 0; }

/* --- Toast ---------------------------------------------------------------- */
.toast { position: fixed; right: var(--space-24); bottom: var(--space-24);
  width: min(360px, 100%); background: var(--color-surface); border: 1px solid var(--color-border);
  box-shadow: var(--shadow-2); border-radius: var(--radius-md);
  padding: var(--space-12) var(--space-16); display: flex; gap: var(--space-8); align-items: flex-start;
  z-index: var(--z-toast); }

/* --- Utility -------------------------------------------------------------- */
.two { display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-4) var(--space-16); }
.row { display: flex; align-items: center; gap: var(--space-8); flex-wrap: wrap; }
.row--top { align-items: flex-start; }
.sp { flex: 1; }
.divider { border: 0; border-top: 1px solid var(--color-border); margin: var(--space-16) 0; }
.hl { background: var(--color-primary-subtle); border-left: 3px solid var(--color-primary);
  border-radius: var(--radius-sm); padding: var(--space-8) var(--space-12); }
.tl { border: 1px solid var(--color-border); border-radius: var(--radius-md);
  padding: var(--space-8) var(--space-12); }
.tl + .tl { margin-top: var(--space-8); }
.tl--now { border-color: var(--color-primary); }
.steps { display: flex; flex-direction: column; gap: var(--space-8); }
.steps li { display: flex; gap: var(--space-8); align-items: flex-start; }
.steps .n { flex: none; width: var(--space-24); height: var(--space-24); border-radius: var(--radius-pill);
  background: var(--color-primary-subtle); color: var(--color-primary);
  display: grid; place-items: center; font-size: var(--fs-caption); font-weight: 700; }

/* ===== DELTA — the app's additions to the delivered composition layer ===== */
/* ----------------------------------------------------------------------------------------------
   THE DELTA. Everything above this line is `UXUI-Design/mockups/app.css`, **copied unchanged**.
   Everything below is the app's, and there are exactly **seven entries**. `AC-S4-19` leg ①: the app
   may ADD to the delivered layer; it may not replace it or rename it — and *a delta doing the
   design's job is visible by its size*. This one is 80 bytes of marker and the rules
   below; the delivered layer above is 34,304 bytes of design.
   ---------------------------------------------------------------------------------------------- */

/* --- Entry 1 of 5 · the language switch ------------------------------------------------------
   WHY. The design's mockups carry both languages in one document and switch them with
   `html[data-lang]`, and the three rules that do it live in each **mockup's own `<head>`** — not in
   the composition layer (`grep -c data-lang UXUI-Design/mockups/app.css` reads 0; the rules are at
   the tail of every mockup's inline style block). The app renders the same two spans and sets
   `data-lang` **on the server** from the requested language instead of from the mockup's hash
   script, so the layer needs the three rules the mockups were carrying themselves.
   ---------------------------------------------------------------------------------------------- */
html[data-lang="en"] .zh { display: none; }
html[data-lang="zh"] .en { display: none; }
html:not([data-lang]) .en { display: none; }

/* --- Entry 2 of 5 · an overlay at rest is hidden ---------------------------------------------
   WHY. The design's `.ov` sets `display: flex`, and a class's `display` beats the user agent's
   `[hidden] { display: none }` — so the app, which renders the drawer and the source panel **into
   every screen** and shows them on demand, needs the attribute honoured. The mockups never needed the
   rule: their overlays are static frames, always open. One selector; nothing about the design's
   overlay changes.
   ---------------------------------------------------------------------------------------------- */
.ov[hidden] { display: none; }

/* --- Entry 3 of 5 · a `.pick` is a button, and a button has a user-agent background ------------
   WHY, and it is a defect in the delivered layer rather than a taste. `.pick` sets its border,
   padding and cursor but never its `background`, so the browser's own `buttonface` — a light grey — shows
   through **in both themes**: measured, axe reports twelve contrast failures in dark on the delivered
   layer's own screen: dark-theme text on that light grey, a contrast of 1.02:1, on the three rehearsed-thread
   picks. The fix is the surface the card beside them already uses, and nothing else changes.
   ---------------------------------------------------------------------------------------------- */
button.pick { background: var(--color-surface); }

/* --- Entry 4 of 5 · a refused candidate is dimmed below the contrast floor --------------------
   WHY, and it is the second defect found in the delivered layer, in the same family as the first.
   `.cand--fail { opacity: 0.75 }` dims the whole row — **including the text that says why the
   candidate was refused**, which computed at 3.36:1 against its own chip. Measured: axe reports it on
   six of the S2a captures, both themes. The signal the dimming carried is already carried by the red
   chip's word, so the override restores the floor and loses nothing; it is the **one declaration in
   this delta that overrides the delivered layer rather than adding to it**, and it is here rather
   than in the layer because the layer is the design's.
   ---------------------------------------------------------------------------------------------- */
.cand--fail { opacity: 1; }

/* --- Entry 5 of 5 · the progress narration ---------------------------------------------------
   WHY. `PRD §11.1`'s progress narration (`AC-S4-15`): a panel that appears when a stage passes
   1.5 s and stays until the stage answers. **The design has no such panel** — it is M3's addition to
   the product, so it is an addition to the layer. It is hidden at rest (`[hidden]`) and only the
   driver shows it, so a screen at rest is the design's screen.
   ---------------------------------------------------------------------------------------------- */
.narration { position: sticky; bottom: var(--space-16); z-index: var(--z-sticky);
             margin: var(--space-16) 0 0; background: var(--color-surface);
             border: 1px solid var(--color-border); border-radius: var(--radius-md);
             box-shadow: var(--shadow-2); padding: var(--space-16); }
.narration[hidden] { display: none; }
.narration-head { display: flex; align-items: center; gap: var(--space-8); margin: 0; }
.narration-dot { width: var(--space-8); height: var(--space-8); border-radius: var(--radius-pill);
                 background: var(--color-primary); flex: none; }
.narration-current { color: var(--color-text-secondary); font-size: var(--fs-caption); }
.narration-steps { list-style: none; display: flex; flex-wrap: wrap; gap: var(--space-8);
                   margin: var(--space-12) 0 0; padding: 0; }
.narration-step { font-size: var(--fs-caption); color: var(--color-text-disabled);
                  border: 1px solid var(--color-border); border-radius: var(--radius-pill);
                  padding: var(--space-4) var(--space-8); }
.narration-step.is-done { color: var(--color-text-secondary); }
.narration-step.is-active { color: var(--color-primary); border-color: var(--color-primary);
                            background: var(--color-primary-subtle); font-weight: var(--fw-label); }
.narration-note { margin: var(--space-12) 0 0; font-size: var(--fs-caption);
                  color: var(--color-text-secondary); }

/* --- Entry 6 of 7 · the narrow-width header (F-1, sprint-07) -----------------------------------
   WHY. `TECH 08 §6` and `UXUI 05` TC-17/A-07 require no horizontal scroll of main content at 375 px,
   and S1 measured **466 px** there: the header row (`.hdr`) is a single-line flex composition and its
   last item, the language switch (`.seg`, x = 375 → 466), overflowed the viewport by 91 px. The UI
   spec's *"no breakpoint"* is about the desktop column at 1280 / 1366 / 1440 — it defines no 375 px
   composition — so this is the standard's responsive gate implemented at build level, not a design
   change. The rule only lets the header wrap below 480 px; the 768 and 1440 boxes are unchanged
   (measured `.seg` left 639 / 1311, top 30 / 21). Markup unchanged.
   ---------------------------------------------------------------------------------------------- */
@media (max-width: 480px) { .hdr { flex-wrap: wrap; } }

/* --- Entry 7 of 7 · S2's workflow bar is its own full-width row (sprint-08) --------------------
   WHY. `S2-WORKFLOW-BAR-CHANGE` (A2): the bar is a case-level instrument, not a column artefact.
   In columns 2–3 it was 933 px at 1440 while the left column ran beside it, and the left column
   started a row higher than the other two. It now sits in a `.wfrow` above `.cols`, spanning the
   content region — 1316 / 1242 / 1156 px at 1440 / 1366 / 1280 — and aligned with the client-context
   bar; the grid keeps one row and all three columns start on it. These five selectors are the
   design's named delta (`S2-WORKFLOW-BAR-CHANGE` §4, 217 bytes of rules); no delivered class is
   restyled, and the bar's anatomy is unchanged.
   ---------------------------------------------------------------------------------------------- */
.wfrow { padding: 0 var(--space-24); margin-bottom: var(--space-12); }
.cols--wf { grid-template-rows: minmax(0, 1fr); }
.cols--wf > .l { grid-row: 1; }
.cols--wf > .m { grid-row: 1; }
.cols--wf > .r { grid-row: 1; }

/* ===== END DELTA ===== */

/* --- The batch history table (the intake surface, sprint-13) ---------------- */
/* The intake history is the one table the console renders; it is composed from the
   design's own type and spacing tokens, with no new token and no literal size. */
.tbl { width: 100%; border-collapse: collapse; font-size: var(--fs-body); }
.tbl th, .tbl td {
  text-align: left;
  padding: var(--space-8) var(--space-12);
  border-bottom: 1px solid var(--color-border);
}
.tbl th {
  color: var(--color-text-secondary);
  font-size: var(--fs-caption);
  font-weight: var(--fw-button);
}
