/* ============================================================================
   FinCheqIQ — Component Library  ·  Phase 1 Foundation  ·  LOCKED
   Every class here is demonstrated on component-library.html. Later phases
   compose these; they do not restyle them.
   ========================================================================== */

/* ══ 1. BUTTONS ═══════════════════════════════════════════════════════════ */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: var(--sp-2);
  position: relative;
  height: 36px; padding: 0 var(--sp-4);
  border: 1px solid transparent; border-radius: var(--r-md);
  font-family: var(--font-ui); font-size: var(--fs-sm); font-weight: 500;
  letter-spacing: var(--tr-normal); white-space: nowrap;
  transition: background var(--motion-micro), border-color var(--motion-micro),
              color var(--motion-micro), box-shadow var(--motion-micro), transform var(--dur-press) var(--ease-out);
}
.btn svg { width: 16px; height: 16px; flex: none; }
.btn:active:not(:disabled) { transform: translateY(1px); }
.btn:disabled, .btn[aria-disabled="true"] { cursor: not-allowed; transform: none; }

.btn-primary { background: var(--brand); color: var(--brand-on); border-color: var(--brand); box-shadow: var(--e-1); }
.btn-primary:hover:not(:disabled) { background: var(--brand-hover); border-color: var(--brand-hover); }
.btn-primary:active:not(:disabled) { background: var(--brand-active); border-color: var(--brand-active); box-shadow: none; }
.btn-primary:disabled { background: var(--surface-3); color: var(--ink-disabled); border-color: var(--line); box-shadow: none; }

.btn-secondary { background: var(--surface); color: var(--ink); border-color: var(--line-strong); box-shadow: var(--e-1); }
.btn-secondary:hover:not(:disabled) { background: var(--surface-2); border-color: var(--ink-disabled); }
.btn-secondary:active:not(:disabled) { background: var(--surface-3); box-shadow: none; }
.btn-secondary:disabled { background: var(--surface-2); color: var(--ink-disabled); border-color: var(--line); box-shadow: none; }

.btn-ghost { background: transparent; color: var(--ink-2); }
.btn-ghost:hover:not(:disabled) { background: var(--surface-3); color: var(--ink); }
.btn-ghost:active:not(:disabled) { background: var(--canvas-sunken); }
.btn-ghost:disabled { color: var(--ink-disabled); }

.btn-danger { background: var(--st-invalid); color: #fff; border-color: var(--st-invalid); box-shadow: var(--e-1); }
.btn-danger:hover:not(:disabled) { background: var(--st-invalid-ink); border-color: var(--st-invalid-ink); }
.btn-danger:active:not(:disabled) { box-shadow: none; }
.btn-danger:disabled { background: var(--surface-3); color: var(--ink-disabled); border-color: var(--line); box-shadow: none; }

/* a <button> is inline-block by default and the global rule makes svg a block
   child, so without an explicit centring context the icon lands top-left — and
   without a size it falls back to the 300x150 svg default. .btn svg covers the
   labelled buttons; icon-only buttons carry no .btn class, so they need both. */
.btn-icon { display: inline-grid; place-items: center; width: 34px; height: 34px;
  padding: 0; border-radius: var(--r-md); color: var(--ink-2); }
.btn-icon svg { width: 16px; height: 16px; flex: none; }
.btn-icon:hover:not(:disabled) { background: var(--surface-3); color: var(--ink); }
.btn-icon:disabled { color: var(--ink-disabled); }
.btn-icon.on-chrome { color: var(--chrome-ink-2); }
.btn-icon.on-chrome:hover { background: var(--chrome-3); color: var(--chrome-ink); }

.btn-sm { height: 28px; padding: 0 var(--sp-3); font-size: var(--fs-xs); }
.btn-lg { height: 42px; padding: 0 var(--sp-5); font-size: var(--fs-md); }
.btn-block { width: 100%; }

/* loading — label hides, spinner takes its place, width does not jump */
.btn.is-loading { pointer-events: none; color: transparent !important; }
.btn.is-loading > * { visibility: hidden; }
.btn.is-loading::after {
  content: ''; position: absolute; width: 15px; height: 15px; border-radius: var(--r-full);
  border: 2px solid currentColor; border-top-color: transparent;
  animation: fq-spin 620ms linear infinite;
}
.btn-primary.is-loading::after, .btn-danger.is-loading::after { border-color: rgba(255,255,255,.45); border-top-color: #fff; }
.btn-secondary.is-loading::after, .btn-ghost.is-loading::after { border-color: var(--line-strong); border-top-color: var(--brand); }
@keyframes fq-spin { to { transform: rotate(360deg); } }

/* ══ 2. FORM FIELDS + VALIDATION PRIMITIVES ═══════════════════════════════ */
.field { display: flex; flex-direction: column; gap: var(--sp-2); }
.field-label {
  display: flex; align-items: baseline; gap: var(--sp-2);
  font-size: var(--fs-sm); font-weight: 500; color: var(--ink-2);
}
/* Required-field convention — ONE convention, used in every phase:
   a brand-coloured asterisk after the label, plus aria-required on the input. */
.req::after { content: '*'; color: var(--brand); margin-inline-start: 2px; font-weight: 600; }
.field-optional { font-size: var(--fs-xs); color: var(--ink-3); font-weight: 400; }

.control-wrap { position: relative; display: flex; align-items: center; }
.control-wrap .control-icon {
  position: absolute; inset-inline-start: var(--sp-3); width: 16px; height: 16px; color: var(--ink-3);
  pointer-events: none; transition: color var(--motion-micro);
}
.control-wrap .control-action {
  position: absolute; inset-inline-end: var(--sp-2); display: inline-flex; align-items: center; gap: var(--sp-1);
  height: 26px; padding: 0 var(--sp-2); border-radius: var(--r-sm);
  font-size: var(--fs-xs); font-weight: 500; color: var(--ink-3);
  transition: background var(--motion-micro), color var(--motion-micro);
}
.control-wrap .control-action:hover { background: var(--surface-3); color: var(--ink); }
.control-wrap:has(.control-icon) .input { padding-inline-start: 34px; }
.control-wrap:has(.control-action) .input { padding-inline-end: 68px; }

.input, .select, .textarea {
  width: 100%; height: 38px; padding: 0 var(--sp-3);
  background: var(--surface); color: var(--ink);
  border: 1px solid var(--line-strong); border-radius: var(--r-md);
  font-size: var(--fs-md); box-shadow: var(--e-inset);
  transition: border-color var(--motion-micro), box-shadow var(--motion-micro), background var(--motion-micro);
}
.textarea { height: auto; min-height: 88px; padding: var(--sp-3); resize: vertical; line-height: var(--lh-md); }
.input::placeholder, .textarea::placeholder { color: var(--ink-4); }
.input:hover:not(:disabled):not([readonly]), .select:hover:not(:disabled), .textarea:hover:not(:disabled) { border-color: var(--ink-disabled); }
.input:focus, .select:focus, .textarea:focus {
  outline: none; border-color: var(--brand);
  box-shadow: 0 0 0 3px var(--brand-tint-2);
}
.control-wrap:focus-within .control-icon { color: var(--brand); }

.select {
  appearance: none; padding-inline-end: 34px; cursor: pointer;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='%236a7683' stroke-width='1.6' stroke-linecap='round'%3E%3Cpath d='M4 6.5 8 10.5 12 6.5'/%3E%3C/svg%3E");
  background-repeat: no-repeat; background-position: right var(--sp-3) center; background-size: 15px;
}
.input[type="date"], .input[type="time"] { cursor: pointer; }
.input[type="date"]::-webkit-calendar-picker-indicator { opacity: .55; cursor: pointer; }

/* filled — a value is present but the field is not focused */
.input.is-filled, .textarea.is-filled { background: var(--surface); border-color: var(--line-strong); }

/* error */
.field.has-error .input, .field.has-error .select, .field.has-error .textarea,
.input.has-error, .select.has-error, .textarea.has-error {
  border-color: var(--st-invalid); background: var(--st-invalid-bg);
}
.field.has-error .input:focus, .input.has-error:focus,
.field.has-error .select:focus, .field.has-error .textarea:focus {
  box-shadow: 0 0 0 3px rgba(193, 55, 46, .18);
}
/* valid affirmation — used sparingly (password match, verified code) */
.field.is-valid .input, .input.is-valid { border-color: var(--st-valid); }
.field.is-valid .control-check { opacity: 1; transform: none; }
.control-check {
  position: absolute; inset-inline-end: var(--sp-3); width: 16px; height: 16px; color: var(--st-valid);
  opacity: 0; transform: scale(.7); pointer-events: none;
  transition: opacity var(--motion-micro), transform var(--motion-micro);
}

/* disabled vs read-only — deliberately different.
   disabled = unavailable (greyed, dashed-free, no interaction)
   read-only = real data you may select but not change (keeps ink colour)   */
.input:disabled, .select:disabled, .textarea:disabled {
  background: var(--surface-2); color: var(--ink-disabled); border-color: var(--line);
  box-shadow: none; cursor: not-allowed;
}
.input[readonly], .textarea[readonly] {
  background: var(--surface-2); color: var(--ink); border-color: var(--line);
  border-style: dashed; box-shadow: none; cursor: default;
}
.input[readonly]:focus { border-color: var(--line-strong); box-shadow: none; }

/* helper / error / success messaging under a field */
.field-hint { display: flex; gap: var(--sp-2); font-size: var(--fs-xs); color: var(--ink-3); line-height: var(--lh-xs); }
.field-msg {
  display: flex; align-items: flex-start; gap: var(--sp-2);
  font-size: var(--fs-xs); line-height: var(--lh-xs); font-weight: 500;
}
.field-msg svg { width: 14px; height: 14px; flex: none; margin-top: 1px; }
.field-msg.is-error { color: var(--st-invalid-ink); }
.field-msg.is-ok { color: var(--st-valid-ink); }
/* settle-in, not a pop */
.field-msg[data-fq-enter] { animation: fq-settle var(--dur-standard) var(--ease-out) both; }
@keyframes fq-settle {
  from { opacity: 0; transform: translateY(-4px); }
  to   { opacity: 1; transform: none; }
}

.char-count { margin-inline-start: auto; font-family: var(--font-mono); font-size: var(--fs-2xs); color: var(--ink-3); font-variant-numeric: tabular-nums; }
.char-count.is-near { color: var(--st-review-ink); }
.char-count.is-over { color: var(--st-invalid-ink); font-weight: 600; }

/* form-level error summary */
.form-summary {
  display: flex; gap: var(--sp-3); padding: var(--sp-4);
  background: var(--st-invalid-bg); border: 1px solid var(--line);
  border-radius: var(--r-md);
  animation: fq-settle var(--dur-standard) var(--ease-out) both;
}
.form-summary svg.summary-mark { width: 18px; height: 18px; color: var(--st-invalid); flex: none; margin-top: 1px; }
.form-summary h4 { font-size: var(--fs-sm); color: var(--st-invalid-ink); }
.form-summary ul { margin: var(--sp-2) 0 0; padding-inline-start: var(--sp-4); font-size: var(--fs-sm); color: var(--st-invalid-ink); }
.form-summary li + li { margin-top: 2px; }
.form-summary a { text-decoration: underline; text-underline-offset: 2px; }

/* checkbox / radio / switch */
.check { display: inline-flex; align-items: flex-start; gap: var(--sp-2); font-size: var(--fs-sm); cursor: pointer; }
.check input { appearance: none; width: 16px; height: 16px; margin: 2px 0 0; flex: none;
  border: 1px solid var(--line-strong); border-radius: var(--r-sm); background: var(--surface);
  box-shadow: var(--e-inset); cursor: pointer; transition: all var(--motion-micro); }
.check input[type="radio"] { border-radius: var(--r-full); }
.check input:hover { border-color: var(--ink-4); }
.check input:checked { background: var(--brand); border-color: var(--brand); box-shadow: none; }
.check input[type="checkbox"]:checked {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='%23fff' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M3.5 8.4 6.4 11.2 12.5 4.9'/%3E%3C/svg%3E");
  background-size: 13px; background-position: center; background-repeat: no-repeat;
}
.check input[type="radio"]:checked { box-shadow: inset 0 0 0 3px var(--surface); }
.check input:disabled { background: var(--surface-3); border-color: var(--line); cursor: not-allowed; }
.check input:disabled + span { color: var(--ink-disabled); }
/* A stack sets vertical rhythm; an inline-flex check inside one flows onto its
   neighbour's line instead of taking a row of its own. Direct children of a
   stack are rows — the margin-top the stack applies then actually separates. */
[class*="stack-"] > .check { display: flex; }

.switch { position: relative; display: inline-flex; align-items: center; gap: var(--sp-3); cursor: pointer; font-size: var(--fs-sm); }
.switch input { appearance: none; width: 34px; height: 20px; margin: 0; flex: none;
  background: var(--line-strong); border-radius: var(--r-full); cursor: pointer;
  transition: background var(--motion-micro); }
.switch input::after { content: ''; position: absolute; inset-inline-start: 2px; top: 2px; width: 16px; height: 16px;
  background: #fff; border-radius: var(--r-full); box-shadow: var(--e-1);
  transition: transform var(--motion-micro); }
.switch input:checked { background: var(--brand); }
.switch input:checked::after { transform: translateX(14px); }

/* file-drop zone (cheque upload — used from Phase 4 on) */
.dropzone {
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: var(--sp-2);
  min-height: 152px; padding: var(--sp-6);
  background: var(--surface-2); border: 1.5px dashed var(--line-strong); border-radius: var(--r-lg);
  text-align: center; cursor: pointer;
  transition: border-color var(--motion-standard), background var(--motion-standard);
}
.dropzone:hover { border-color: var(--brand); background: var(--brand-tint); }
.dropzone.is-over { border-color: var(--brand); background: var(--brand-tint); border-style: solid; }
.dropzone.has-error { border-color: var(--st-invalid); background: var(--st-invalid-bg); }
.dropzone-mark { width: 34px; height: 34px; display: grid; place-items: center; color: var(--brand);
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-md); box-shadow: var(--e-1); }
.dropzone-mark svg { width: 18px; height: 18px; }

/* ══ 3. STATUS BADGES — the signature system ══════════════════════════════
   Colour + distinct glyph shape + left state-cap. Never colour alone.      */
.badge {
  display: inline-flex; align-items: center; gap: var(--sp-2);
  height: 22px; padding: 0 var(--sp-2);
  /* Style A — tinted fill only. No border: a fill, a border and coloured text
     are three signals doing one job. Matches Linear's issue-status chips and
     GitHub's state labels: flat tint, coloured text, nothing round it. The 4px
     radius is deliberate — a full pill reads consumer, this reads institutional. */
  border-radius: var(--r-sm); flex: none;   /* a chip is never squeezed by its container */
  font-family: var(--font-head); font-size: var(--fs-2xs); font-weight: 600;
  letter-spacing: var(--tr-wide); text-transform: uppercase; white-space: nowrap;
  transition: background var(--motion-micro), color var(--motion-micro);
}
.badge::before { content: ''; width: 8px; height: 8px; flex: none; }
.badge-lg { height: 28px; padding: 0 var(--sp-3); font-size: var(--fs-xs); }
.badge-lg::before { width: 9px; height: 9px; }

/* valid — solid disc */
.badge--valid { background: var(--st-valid-bg); color: var(--st-valid-ink); }
.badge--valid::before { background: var(--st-valid); border-radius: var(--r-full); }
/* review — triangle */
.badge--review { background: var(--st-review-bg); color: var(--st-review-ink); }
.badge--review::before { width: 0; height: 0; background: none; border-left: 4.5px solid transparent; border-right: 4.5px solid transparent; border-bottom: 8px solid var(--st-review); }
/* invalid — square */
.badge--invalid { background: var(--st-invalid-bg); color: var(--st-invalid-ink); }
.badge--invalid::before { background: var(--st-invalid); border-radius: 1px; }
/* processing — spinning ring */
.badge--processing { background: var(--st-processing-bg); color: var(--st-processing-ink); }
.badge--processing::before {
  border: 2px solid var(--st-processing); border-top-color: transparent; border-radius: var(--r-full);
  animation: fq-spin 900ms linear infinite;
}
/* pending — hollow disc */
.badge--pending { background: var(--st-pending-bg); color: var(--st-pending-ink); }
.badge--pending::before { border: 2px solid var(--st-pending); border-radius: var(--r-full); }
/* hold — diamond */
.badge--hold { background: var(--st-hold-bg); color: var(--st-hold-ink); }
.badge--hold::before { background: var(--st-hold); transform: rotate(45deg); width: 7px; height: 7px; border-radius: 1px; }
/* unusable — hatched bar */
.badge--unusable { background: var(--st-unusable-bg); color: var(--st-unusable-ink); }
/* a flat bar, not a hatch: zero gradients on chips, while still reading as a
   distinct shape in monochrome — "could not run" must not collapse into the
   square that means "ran and failed" */
.badge--unusable::before {
  width: 10px; height: 3px; border-radius: 1px; background: var(--st-unusable);
}

/* There is no solid variant. One construction for every status chip in the
   product — a headline state earns emphasis from .badge-lg (28px, larger type),
   not from a second visual language. */

/* status-change pulse — ONE pulse, no bounce. Fired by fqPulse(). */
.badge.fq-pulse { animation: fq-status-pulse var(--dur-status) var(--ease-out) 1; }
@keyframes fq-status-pulse {
  0%   { box-shadow: 0 0 0 0 currentColor; }
  55%  { box-shadow: 0 0 0 5px transparent; }
  100% { box-shadow: 0 0 0 0 transparent; }
}

/* neutral tags & phase tags */
.tag {
  display: inline-flex; align-items: center; gap: var(--sp-1); height: 20px; padding: 0 var(--sp-2);
  background: var(--canvas-sunken); color: var(--ink-3); border-radius: var(--r-sm);
  font-size: var(--fs-2xs); letter-spacing: .02em;
}
.tag-brand { background: var(--brand-tint); color: var(--brand); border-color: var(--brand-tint-2); }
.kbd {
  display: inline-flex; align-items: center; height: 19px; padding: 0 5px;
  background: var(--surface-2); border: 1px solid var(--line-strong); border-bottom-width: 2px;
  border-radius: var(--r-sm); font-family: var(--font-mono); font-size: var(--fs-2xs); color: var(--ink-3);
}

/* ══ 4. CONFIDENCE / RISK SCORE INDICATORS ════════════════════════════════
   Never colour alone: the numeral is always present, plus a shaped track.  */
.meter { display: flex; align-items: center; gap: var(--sp-3); min-width: 150px; }
.meter-track { position: relative; flex: 1; height: 6px; background: var(--canvas-sunken); border-radius: var(--r-xs); overflow: hidden; }
.meter-fill { height: 100%; border-radius: var(--r-xs); transition: width var(--motion-standard); }
.meter-value { font-family: var(--font-mono); font-size: var(--fs-sm); font-weight: 600; font-variant-numeric: tabular-nums; min-width: 44px; text-align: end; }
.meter--valid   .meter-fill { background: var(--st-valid); }      .meter--valid   .meter-value { color: var(--st-valid-ink); }
.meter--review  .meter-fill { background: var(--st-review); }     .meter--review  .meter-value { color: var(--st-review-ink); }
.meter--invalid .meter-fill { background: var(--st-invalid); }    .meter--invalid .meter-value { color: var(--st-invalid-ink); }
.meter--pending .meter-fill { background: var(--st-pending); }    .meter--pending .meter-value { color: var(--st-pending-ink); }
/* threshold notch — where the bank's configured cut-off sits */
.meter-threshold { position: absolute; top: -2px; bottom: -2px; width: 2px; background: var(--ink); opacity: .5; }

.radial { display: inline-grid; place-items: center; position: relative; width: 56px; height: 56px; }
.radial svg { transform: rotate(-90deg); width: 56px; height: 56px; }
.radial circle { fill: none; stroke-width: 5; }
.radial .radial-track { stroke: var(--canvas-sunken); }
.radial .radial-fill { stroke-linecap: round; transition: stroke-dashoffset var(--motion-standard); }
.radial-label { position: absolute; font-family: var(--font-mono); font-size: var(--fs-sm); font-weight: 600; font-variant-numeric: tabular-nums; }
.radial--valid   .radial-fill { stroke: var(--st-valid); }   .radial--valid   .radial-label { color: var(--st-valid-ink); }
.radial--review  .radial-fill { stroke: var(--st-review); }  .radial--review  .radial-label { color: var(--st-review-ink); }
.radial--invalid .radial-fill { stroke: var(--st-invalid); } .radial--invalid .radial-label { color: var(--st-invalid-ink); }

/* ══ 5. CARDS / PANELS ════════════════════════════════════════════════════ */
/* a card owns its ink as well as its surface — dropped into a dark-chrome page
   (the launcher) it must not inherit light text onto its white face */
/* One at-rest treatment: hairline neutral border, no shadow. This is the Stripe
   Dashboard / Linear surface — a card that sits flat on the page is not floating,
   so it gets no drop shadow. Shadow is reserved for things that genuinely lift:
   popovers (--e-2), modals and drawers (--e-3), toasts (--e-4), and hover. */
.card { color: var(--ink); background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-lg); }
.card-head {
  display: flex; align-items: center; justify-content: space-between; gap: var(--sp-4);
  padding: var(--sp-4) var(--sp-5); border-bottom: 1px solid var(--line);
}
.card-head h3 { font-size: var(--fs-lg); }
.card-body { padding: var(--sp-5); }
.card-body.tight { padding: var(--sp-4); }
.card-foot { padding: var(--sp-4) var(--sp-5); border-top: 1px solid var(--line); background: var(--surface-2);
  border-radius: 0 0 var(--r-lg) var(--r-lg); }

.kpi { padding: var(--sp-5); }
.kpi-label { font-size: var(--fs-xs); color: var(--ink-3); letter-spacing: .01em; }
.kpi-value { font-family: var(--font-mono); font-size: var(--fs-num-lg); line-height: 1.1; font-weight: 600;
  font-variant-numeric: tabular-nums; margin-top: var(--sp-2); letter-spacing: -0.02em; }
.kpi-unit { font-size: var(--fs-md); color: var(--ink-3); margin-inline-start: 2px; font-weight: 500; }
.kpi-foot { display: flex; align-items: center; gap: var(--sp-2); margin-top: var(--sp-3); font-size: var(--fs-xs); color: var(--ink-3); }

/* comparison card — master data vs extracted data (Phases 5/6/7) */
.compare { display: grid; grid-template-columns: 132px 1fr 1fr; }
.compare-head { display: contents; }
.compare-head > * {
  padding: var(--sp-2) var(--sp-4); background: var(--surface-2); border-bottom: 1px solid var(--line);
  font-family: var(--font-head); font-size: var(--fs-2xs); font-weight: 600;
  letter-spacing: var(--tr-wide); text-transform: uppercase; color: var(--ink-3);
}
.compare-row { display: contents; }
.compare-row > * { padding: var(--sp-3) var(--sp-4); border-bottom: 1px solid var(--line); font-size: var(--fs-sm); }
.compare-row > :first-child { color: var(--ink-3); font-size: var(--fs-xs); }
.compare-row.is-mismatch > * { background: var(--st-review-bg); }
.compare-row.is-mismatch > :last-child { color: var(--st-review-ink); font-weight: 600; }
.compare-row:last-child > * { border-bottom: 0; }
@media (max-width: 767px) {
  .compare { grid-template-columns: 1fr; }
  .compare-head { display: none; }
  .compare-row > * { border-bottom: 0; padding: var(--sp-1) var(--sp-4); }
  .compare-row > :first-child { padding-top: var(--sp-3); }
  .compare-row > :last-child { padding-bottom: var(--sp-3); border-bottom: 1px solid var(--line); }
  .compare-row > :nth-child(2)::before { content: 'Master: '; color: var(--ink-3); }
  .compare-row > :nth-child(3)::before { content: 'Extracted: '; color: var(--ink-3); }
}

/* ══ 6. DATA TABLE ════════════════════════════════════════════════════════ */
.table-shell { background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-lg); box-shadow: var(--e-1); overflow: hidden; }
.table-scroll { overflow-x: auto; overflow-y: auto; max-height: 460px; }
.dt { font-size: var(--fs-sm); }
.dt thead th {
  position: sticky; top: 0; z-index: 2;
  background: var(--surface-2); border-bottom: 1px solid var(--line-strong);
  padding: var(--sp-3) var(--sp-4); text-align: start; white-space: nowrap;
  font-family: var(--font-head); font-size: var(--fs-2xs); font-weight: 600;
  letter-spacing: var(--tr-wide); text-transform: uppercase; color: var(--ink-3);
}
.dt th.is-sortable { cursor: pointer; user-select: none; transition: color var(--motion-micro), background var(--motion-micro); }
.dt th.is-sortable:hover { color: var(--ink); background: var(--surface-3); }
.dt th .sort-mark { display: inline-block; margin-inline-start: 5px; opacity: .35; transition: opacity var(--motion-micro), transform var(--motion-micro); }
.dt th.is-sorted { color: var(--ink); }
.dt th.is-sorted .sort-mark { opacity: 1; color: var(--brand); }
.dt th.is-sorted[data-dir="desc"] .sort-mark { transform: rotate(180deg); }
/* Density is the point of an operations table. The header already refuses to
   wrap; the body must too, or a ten-column queue squeezed into 1,116px wraps
   "CHQ-2026-0041827" onto two lines and a row becomes 106px — six rows to a
   screen for someone doing this two hundred times a day. Cells that genuinely
   hold two lines (a customer name over its CIF) opt in with .cell-wrap; wide
   tables scroll sideways in .table-scroll rather than growing downwards. */
.dt tbody td {
  padding: var(--sp-2) var(--sp-4); border-bottom: 1px solid var(--line);
  color: var(--ink-2); vertical-align: middle; white-space: nowrap;
}
.dt tbody td.cell-wrap, .dt tbody td .cell-wrap { white-space: normal; }
.dt tbody tr { transition: background var(--motion-micro); }
.dt tbody tr:hover td { background: var(--surface-2); }
.dt tbody tr.is-selected td { background: var(--brand-tint); }
.dt tbody tr.is-selected:hover td { background: var(--brand-tint-2); }
.dt tbody tr:last-child td { border-bottom: 0; }
.dt .col-check { width: 40px; padding-inline-end: 0; }
.dt .col-num { text-align: end; font-family: var(--font-mono); font-variant-numeric: tabular-nums; color: var(--ink); }
.dt .col-actions { width: 44px; text-align: end; }
.dt .cell-primary { color: var(--ink); font-weight: 500; }
.row-link { color: var(--brand); font-family: var(--font-mono); font-size: var(--fs-sm); text-decoration: underline;
  text-underline-offset: 2px; text-decoration-color: var(--brand-tint-2); }
.row-link:hover { text-decoration-color: var(--brand); }

.table-foot {
  display: flex; align-items: center; justify-content: space-between; gap: var(--sp-4);
  padding: var(--sp-3) var(--sp-4); border-top: 1px solid var(--line); background: var(--surface-2);
  font-size: var(--fs-xs); color: var(--ink-3); flex-wrap: wrap;
}
.pager { display: flex; align-items: center; gap: 2px; }
.pager button {
  min-width: 28px; height: 28px; padding: 0 var(--sp-2); border-radius: var(--r-sm);
  font-family: var(--font-mono); font-size: var(--fs-xs); color: var(--ink-2);
  transition: background var(--motion-micro), color var(--motion-micro);
}
.pager button:hover:not(:disabled) { background: var(--surface-3); color: var(--ink); }
.pager button[aria-current="page"] { background: var(--brand); color: var(--brand-on); font-weight: 600; }
.pager button:disabled { color: var(--ink-disabled); cursor: not-allowed; }

/* skeleton + empty */
.skeleton { background: linear-gradient(90deg, var(--canvas-sunken) 25%, var(--surface-3) 50%, var(--canvas-sunken) 75%);
  background-size: 220% 100%; border-radius: var(--r-sm); animation: fq-shimmer 1.4s ease-in-out infinite; }
@keyframes fq-shimmer { from { background-position: 130% 0; } to { background-position: -30% 0; } }
.sk-line { height: 11px; }
.sk-w-full { width: 100%; } .sk-w-3\/4 { width: 75%; } .sk-w-1\/2 { width: 50%; } .sk-w-1\/3 { width: 33%; } .sk-w-1\/4 { width: 25%; }

.empty { display: flex; flex-direction: column; align-items: center; gap: var(--sp-3); padding: var(--sp-9) var(--sp-6); text-align: center; }
.empty-mark { width: 44px; height: 44px; display: grid; place-items: center; color: var(--ink-4);
  background: var(--surface-2); border: 1px solid var(--line); border-radius: var(--r-lg); }
.empty-mark svg { width: 22px; height: 22px; }
.empty h4 { font-size: var(--fs-lg); }
.empty p { max-width: 44ch; font-size: var(--fs-sm); color: var(--ink-3); }

/* ══ 7. MODAL & DRAWER ════════════════════════════════════════════════════ */
.overlay {
  position: fixed; inset: 0; z-index: var(--z-overlay);
  background: rgba(14, 22, 30, .48); backdrop-filter: blur(1.5px);
  opacity: 0; pointer-events: none; transition: opacity var(--motion-standard);
}
.overlay.is-open { opacity: 1; pointer-events: auto; }

.modal {
  position: fixed; z-index: var(--z-modal); top: 50%; inset-inline-start: 50%;
  width: min(520px, calc(100vw - 32px)); max-height: calc(100vh - 64px);
  display: flex; flex-direction: column;
  background: var(--surface); border-radius: var(--r-xl); box-shadow: var(--e-3);
  transform: translate(-50%, -46%) scale(.97); opacity: 0; pointer-events: none;
  transition: opacity var(--dur-exit) var(--ease-inout), transform var(--dur-exit) var(--ease-inout);
}
.modal.is-open { opacity: 1; pointer-events: auto; transform: translate(-50%, -50%) scale(1);
  transition: opacity var(--motion-emphasis), transform var(--motion-emphasis); }
.modal-head { display: flex; align-items: flex-start; justify-content: space-between; gap: var(--sp-4);
  padding: var(--sp-5) var(--sp-5) var(--sp-4); }
.modal-head h3 { font-size: var(--fs-xl); }
.modal-body { padding: 0 var(--sp-5) var(--sp-5); overflow-y: auto; }
.modal-foot { display: flex; justify-content: flex-end; gap: var(--sp-3); padding: var(--sp-4) var(--sp-5);
  border-top: 1px solid var(--line); background: var(--surface-2); border-radius: 0 0 var(--r-xl) var(--r-xl); }

.drawer {
  position: fixed; z-index: var(--z-drawer); top: 0; inset-inline-end: 0; bottom: 0;
  width: min(460px, 100vw); display: flex; flex-direction: column;
  background: var(--surface); box-shadow: var(--e-3); border-inline-start: 1px solid var(--line);
  transform: translateX(100%); transition: transform var(--dur-exit) var(--ease-inout);
}
.drawer.is-open { transform: none; transition: transform var(--motion-emphasis); }
.drawer-head { display: flex; align-items: flex-start; justify-content: space-between; gap: var(--sp-4);
  padding: var(--sp-5); border-bottom: 1px solid var(--line); }
.drawer-body { flex: 1; overflow-y: auto; padding: var(--sp-5); }
.drawer-foot { display: flex; justify-content: flex-end; gap: var(--sp-3); padding: var(--sp-4) var(--sp-5);
  border-top: 1px solid var(--line); background: var(--surface-2); }
@media (max-width: 599px) {
  .drawer { width: 100vw; top: auto; height: 88vh; border-inline-start: 0; border-top: 1px solid var(--line);
    border-radius: var(--r-xl) var(--r-xl) 0 0; transform: translateY(100%); }
}

/* ══ 8. TOAST ═════════════════════════════════════════════════════════════ */
.toast-stack {
  position: fixed; z-index: var(--z-toast); inset-inline-end: var(--sp-5); bottom: var(--sp-5);
  display: flex; flex-direction: column-reverse; gap: var(--sp-3);
  width: min(384px, calc(100vw - 32px)); pointer-events: none;
}
.toast {
  display: flex; align-items: flex-start; gap: var(--sp-3);
  padding: var(--sp-4); background: var(--surface);
  border: 1px solid var(--line); border-inline-start: 3px solid var(--st-pending);
  border-radius: var(--r-xl); box-shadow: var(--e-4); pointer-events: auto;
  animation: fq-toast-in var(--motion-emphasis) both;
}
.toast.is-leaving { animation: fq-toast-out var(--dur-exit) var(--ease-inout) both; }
@keyframes fq-toast-in  { from { opacity: 0; transform: translateX(18px) scale(.98); } to { opacity: 1; transform: none; } }
@keyframes fq-toast-out { to { opacity: 0; transform: translateX(18px) scale(.98); } }
.toast-mark { width: 18px; height: 18px; flex: none; margin-top: 1px; }
.toast-body { flex: 1; min-width: 0; }
.toast-title { font-family: var(--font-head); font-size: var(--fs-sm); font-weight: 600; }
.toast-text { font-size: var(--fs-xs); color: var(--ink-3); margin-top: 2px; }
.toast-close { width: 22px; height: 22px; display: grid; place-items: center; border-radius: var(--r-sm); color: var(--ink-3); }
.toast-close:hover { background: var(--surface-3); color: var(--ink); }
.toast--success { border-inline-start-color: var(--st-valid); }    .toast--success .toast-mark { color: var(--st-valid); }
.toast--error   { border-inline-start-color: var(--st-invalid); }   .toast--error   .toast-mark { color: var(--st-invalid); }
.toast--warning { border-inline-start-color: var(--st-review); }    .toast--warning .toast-mark { color: var(--st-review); }
.toast--info    { border-inline-start-color: var(--st-processing); }.toast--info    .toast-mark { color: var(--st-processing); }
.toast-progress { position: absolute; inset-inline-start: 3px; inset-inline-end: 0; bottom: 0; height: 2px; background: currentColor; opacity: .3;
  transform-origin: left; animation: fq-toast-timer linear forwards; border-radius: 0 0 0 var(--r-xl); }
@keyframes fq-toast-timer { from { transform: scaleX(1); } to { transform: scaleX(0); } }
@media (max-width: 599px) { .toast-stack { inset-inline-end: var(--sp-3); inset-inline-start: var(--sp-3); bottom: var(--sp-3); width: auto; } }

/* ══ 9. TABS / BREADCRUMBS / TOOLTIP / MENU ═══════════════════════════════ */
.tabs { display: flex; gap: var(--sp-1); border-bottom: 1px solid var(--line); position: relative; overflow-x: auto; }
.tab {
  position: relative; height: 38px; padding: 0 var(--sp-4);
  font-size: var(--fs-sm); font-weight: 500; color: var(--ink-3); white-space: nowrap;
  transition: color var(--motion-micro);
}
.tab:hover { color: var(--ink); }
.tab[aria-selected="true"] { color: var(--brand); }
.tab::after {
  content: ''; position: absolute; inset-inline-start: var(--sp-2); inset-inline-end: var(--sp-2); bottom: -1px; height: 2px;
  background: var(--brand); border-radius: var(--r-xs) var(--r-xs) 0 0;
  transform: scaleX(0); transform-origin: center; transition: transform var(--motion-standard);
}
.tab[aria-selected="true"]::after { transform: scaleX(1); }
.tab-count { display: inline-flex; align-items: center; height: 17px; padding: 0 5px; margin-inline-start: var(--sp-2);
  background: var(--surface-3); border-radius: var(--r-sm); font-family: var(--font-mono); font-size: var(--fs-2xs); color: var(--ink-3); }
.tab[aria-selected="true"] .tab-count { background: var(--brand-tint); color: var(--brand); }
.tabpanel { animation: fq-fade-up var(--motion-standard) both; }
@keyframes fq-fade-up { from { opacity: 0; transform: translateY(4px); } to { opacity: 1; transform: none; } }

.crumbs { display: flex; align-items: center; gap: var(--sp-2); font-size: var(--fs-xs); color: var(--ink-3); flex-wrap: wrap; }
.crumbs a { transition: color var(--motion-micro); }
.crumbs a:hover { color: var(--brand); text-decoration: underline; text-underline-offset: 2px; }
.crumbs .sep { color: var(--ink-3); }
.crumbs [aria-current="page"] { color: var(--ink); font-weight: 500; }

.tip { position: relative; display: inline-flex; }
.tip-bubble {
  position: absolute; bottom: calc(100% + 8px); inset-inline-start: 50%; z-index: var(--z-tooltip);
  transform: translateX(-50%) translateY(3px); width: max-content;
  max-width: min(240px, calc(100vw - 32px));
  white-space: normal;
  padding: var(--sp-2) var(--sp-3); background: var(--chrome); color: var(--chrome-ink);
  border-radius: var(--r-md); box-shadow: var(--e-2);
  font-size: var(--fs-xs); line-height: 1.4; font-weight: 400; text-align: start; text-transform: none; letter-spacing: 0;
  opacity: 0; pointer-events: none; transition: opacity var(--motion-micro), transform var(--motion-micro);
}
.tip-bubble::after { content: ''; position: absolute; top: 100%; inset-inline-start: 50%; margin-inline-start: -4px;
  border: 4px solid transparent; border-top-color: var(--chrome); }
.tip:hover .tip-bubble, .tip:focus-within .tip-bubble { opacity: 1; transform: translateX(-50%); }
.tip-bubble.tip-right { inset-inline-start: auto; inset-inline-end: 0; transform: translateY(3px); }
.tip:hover .tip-bubble.tip-right, .tip:focus-within .tip-bubble.tip-right { transform: none; }
.tip-bubble.tip-right::after { inset-inline-start: auto; inset-inline-end: 12px; }

.avatar {
  display: inline-grid; place-items: center; width: 30px; height: 30px; flex: none;
  background: var(--brand); color: var(--brand-on); border-radius: var(--r-full);
  font-family: var(--font-head); font-size: var(--fs-xs); font-weight: 600; letter-spacing: .02em;
}
.avatar-lg { width: 38px; height: 38px; font-size: var(--fs-sm); }
.avatar-chrome { background: var(--chrome-3); color: var(--chrome-ink); border: 1px solid var(--line-inverse); }

.menu {
  position: absolute; z-index: var(--z-tooltip); top: calc(100% + 6px); inset-inline-end: 0; min-width: 232px;
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-lg); box-shadow: var(--e-2);
  padding: var(--sp-2); opacity: 0; transform: translateY(-4px) scale(.98); pointer-events: none;
  transition: opacity var(--motion-micro), transform var(--motion-micro);
}
.menu.is-open { opacity: 1; transform: none; pointer-events: auto; }
.menu-head { padding: var(--sp-3); border-bottom: 1px solid var(--line); margin: calc(var(--sp-2) * -1) calc(var(--sp-2) * -1) var(--sp-2); }
.menu-item {
  display: flex; align-items: center; gap: var(--sp-3); width: 100%; padding: var(--sp-2) var(--sp-3);
  border-radius: var(--r-md); font-size: var(--fs-sm); color: var(--ink-2); text-align: start;
  transition: background var(--motion-micro), color var(--motion-micro);
}
.menu-item svg { width: 16px; height: 16px; flex: none; color: var(--ink-4); }
.menu-item:hover { background: var(--surface-2); color: var(--ink); }
/* an informational row inside a menu — session times, counts. It is not an
   action, so it is not a button: no hover, no focus stop, nothing to click. */
.menu-note {
  display: flex; align-items: center; gap: var(--sp-3); width: 100%;
  padding: var(--sp-2) var(--sp-3); font-size: var(--fs-xs); color: var(--ink-3);
}
.menu-note svg { width: 16px; height: 16px; flex: none; color: var(--ink-3); }
.menu-item:hover svg { color: var(--ink-2); }
.menu-item.is-danger { color: var(--st-invalid-ink); }
.menu-item.is-danger svg { color: var(--st-invalid); }
.menu-item.is-danger:hover { background: var(--st-invalid-bg); }
.menu-sep { height: 1px; background: var(--line); margin: var(--sp-2) calc(var(--sp-2) * -1); }

/* notification bell + unread badge */
.bell { position: relative; }
.bell-count {
  position: absolute; top: 1px; inset-inline-end: 1px; min-width: 15px; height: 15px; padding: 0 3px;
  display: grid; place-items: center; background: var(--st-invalid); color: #fff;
  border: 1.5px solid var(--chrome); border-radius: var(--r-full);
  font-family: var(--font-mono); font-size: var(--fs-3xs); font-weight: 600; line-height: 1;
}
.bell-count.on-surface { border-color: var(--surface); }
.bell.has-unread svg { color: var(--ink); }

/* segmented control */
.segmented { display: inline-flex; padding: 2px; background: var(--surface-3); border: 1px solid var(--line); border-radius: var(--r-md); }
.segmented button {
  height: 28px; padding: 0 var(--sp-3); border-radius: var(--r-sm);
  font-size: var(--fs-xs); font-weight: 500; color: var(--ink-3);
  transition: background var(--motion-micro), color var(--motion-micro), box-shadow var(--motion-micro);
}
.segmented button[aria-pressed="true"] { background: var(--surface); color: var(--ink); box-shadow: var(--e-1); }

/* ══ 10. PERSISTENT BANNER — Phase 2 ══════════════════════════════════════
   Non-blocking, stays until the condition clears. Distinct from a toast:
   a toast reports something that already finished; a banner reports a
   condition that is still true.                                            */
.banner-slot {
  position: sticky; top: var(--topbar-h); z-index: calc(var(--z-sticky) - 1);
  display: grid; grid-template-rows: 0fr; transition: grid-template-rows var(--motion-standard);
}
.banner-slot.is-open { grid-template-rows: 1fr; }
.banner-slot > .banner-clip { overflow: hidden; min-height: 0; }
.banner {
  display: flex; align-items: center; gap: var(--sp-3);
  padding: var(--sp-3) var(--sp-5);
  border-bottom: 1px solid var(--line);
  border-inline-start: 3px solid var(--st-pending);
  background: var(--st-pending-bg); color: var(--st-pending-ink);
  font-size: var(--fs-sm);
  transform: translateY(-100%); opacity: 0;
  transition: transform var(--motion-standard), opacity var(--motion-standard);
}
.banner-slot.is-open .banner { transform: none; opacity: 1; }
.banner-mark { width: 18px; height: 18px; flex: none; }
.banner-text { flex: 1; min-width: 0; }
.banner-text strong { font-weight: 600; }
.banner-text .banner-sub { color: inherit; opacity: .82; }
.banner .btn { flex: none; }
.banner--offline { background: var(--st-review-bg); border-inline-start-color: var(--st-review); color: var(--st-review-ink); }
.banner--online  { background: var(--st-valid-bg);  border-inline-start-color: var(--st-valid);  color: var(--st-valid-ink); }
.banner--info    { background: var(--st-processing-bg); border-inline-start-color: var(--st-processing); color: var(--st-processing-ink); }
.banner--warning { background: var(--st-review-bg); border-inline-start-color: var(--st-review); color: var(--st-review-ink); }
@media (max-width: 767px) {
  .banner { padding: var(--sp-3) var(--sp-4); align-items: flex-start; flex-wrap: wrap; }
  .banner .btn { margin-inline-start: 30px; }
}

/* connectivity heartbeat — small scale here, full scale in Phase 8 */
.heartbeat { display: inline-flex; align-items: center; gap: 5px; }
.heartbeat i {
  width: 3px; border-radius: var(--r-full); background: currentColor;
  animation: fq-heartbeat 1.6s var(--ease-inout) infinite;
}
.heartbeat i:nth-child(1) { height: 7px;  animation-delay: 0ms; }
.heartbeat i:nth-child(2) { height: 12px; animation-delay: 160ms; }
.heartbeat i:nth-child(3) { height: 9px;  animation-delay: 320ms; }
@keyframes fq-heartbeat { 0%, 100% { opacity: .32; } 50% { opacity: 1; } }
.heartbeat.is-flat i { animation: none; opacity: .34; height: 3px; }

/* ══ 11. WIDGET-LEVEL FAILURE — Phase 2 ══════════════════════════════════
   One panel fails inside an otherwise-working screen. Contained: never
   escalate a widget failure into a full-page state.                        */
.widget-error {
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: var(--sp-3); padding: var(--sp-7) var(--sp-5); text-align: center;
  background: var(--surface-2); border: 1px dashed var(--st-invalid-line); border-radius: var(--r-md);
}
.widget-error .widget-mark {
  width: 34px; height: 34px; display: grid; place-items: center; color: var(--st-invalid);
  background: var(--st-invalid-bg); border-radius: var(--r-md);
}
.widget-error .widget-mark svg { width: 18px; height: 18px; }
.widget-error h5 { font-family: var(--font-head); font-size: var(--fs-sm); font-weight: 600; margin: 0; }
.widget-error p { font-size: var(--fs-xs); color: var(--ink-3); max-width: 38ch; }
.widget-error .widget-ref { font-family: var(--font-mono); font-size: var(--fs-2xs); color: var(--ink-3); }

/* ══ 12. DISCLOSURE — Phase 2 ════════════════════════════════════════════ */
.disclosure { border: 1px solid var(--line); border-radius: var(--r-md); background: var(--surface-2); overflow: hidden; }
.disclosure > summary {
  display: flex; align-items: center; gap: var(--sp-2);
  padding: var(--sp-3) var(--sp-4); cursor: pointer; list-style: none;
  font-size: var(--fs-sm); font-weight: 500; color: var(--ink-2);
  transition: background var(--motion-micro), color var(--motion-micro);
}
.disclosure > summary::-webkit-details-marker { display: none; }
.disclosure > summary::before {
  content: ''; width: 0; height: 0; flex: none;
  border-top: 4px solid transparent; border-bottom: 4px solid transparent; border-left: 6px solid var(--ink-4);
  transition: transform var(--motion-micro);
}
.disclosure[open] > summary::before { transform: rotate(90deg); }
.disclosure > summary:hover { background: var(--surface-3); color: var(--ink); }
.disclosure-body { padding: 0 var(--sp-4) var(--sp-4); animation: fq-fade-up var(--motion-standard) both; }
.disclosure-body pre {
  margin: 0; padding: var(--sp-3); background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--r-sm); font-family: var(--font-mono); font-size: var(--fs-2xs);
  color: var(--ink-2); white-space: pre-wrap; word-break: break-word; overflow-x: auto; max-height: 190px;
}

/* ══ 13. INLINE ACTION ERROR (timeout / failed submit) — Phase 2 ═════════
   Sits beside the action that failed. Never a full-page state, never a
   toast — the user must see it next to the button they pressed.            */
.action-error {
  display: flex; align-items: flex-start; gap: var(--sp-3);
  padding: var(--sp-3) var(--sp-4);
  background: var(--st-review-bg); border: 1px solid var(--st-review-line);
  border-inline-start: 1px solid var(--line); border-radius: var(--r-md);
  font-size: var(--fs-sm); color: var(--st-review-ink);
  animation: fq-settle var(--motion-standard) both;
}
.action-error svg { width: 16px; height: 16px; flex: none; margin-top: 2px; }
.action-error .action-error-body { flex: 1; min-width: 0; }
.action-error h5 { font-family: var(--font-head); font-size: var(--fs-sm); font-weight: 600; margin: 0; }
.action-error p { font-size: var(--fs-xs); margin-top: 2px; opacity: .9; }
.action-error.is-failed { background: var(--st-invalid-bg); border-color: var(--st-invalid-line);
 color: var(--st-invalid-ink); }

/* ══ 14. KPI GROUPS, HERO KPIs & TREND INDICATORS — Phase 3 ══════════════
   Sixteen metrics is not sixteen identical tiles. The grouping IS the
   information hierarchy: two headline health signals, then four labelled
   families of supporting numbers.                                         */
.kpi-group + .kpi-group { margin-top: var(--sp-6); }
.kpi-group-head {
  display: flex; align-items: baseline; gap: var(--sp-3);
  margin-bottom: var(--sp-3); padding-bottom: var(--sp-2);
  border-bottom: 1px solid var(--line);
}
.kpi-group-head h3 {
  font-family: var(--font-head); font-size: var(--fs-2xs); font-weight: 600;
  letter-spacing: var(--tr-wide); text-transform: uppercase; color: var(--ink-3);
}
.kpi-group-head .kpi-group-note { font-size: var(--fs-xs); color: var(--ink-3); margin-inline-start: auto; }
.kpi-grid { display: grid; gap: var(--sp-4); grid-template-columns: repeat(auto-fit, minmax(184px, 1fr)); }

.card-hover { transition: border-color var(--motion-micro), box-shadow var(--motion-micro), transform var(--motion-micro); }
.card-hover:hover { border-color: var(--line-strong); box-shadow: var(--e-2); transform: translateY(-1px); }
.card-hover:active { transform: none; box-shadow: var(--e-1); }
a.card-hover, button.card-hover { display: block; width: 100%; text-align: start; }

/* the two headline signals get real weight */
.kpi-hero { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: var(--sp-5); align-items: center; padding: var(--sp-6); }
.kpi-hero .kpi-label { font-size: var(--fs-sm); color: var(--ink-2); font-weight: 500; }
.kpi-hero .kpi-value { font-size: var(--fs-num-xl); margin-top: var(--sp-1); }
.kpi-hero .kpi-unit { font-size: var(--fs-xl); }
.kpi-hero .kpi-foot { margin-top: var(--sp-3); }
@media (max-width: 599px) {
  .kpi-hero { grid-template-columns: minmax(0, 1fr); }
  .kpi-hero .kpi-value { font-size: var(--fs-num-xl-c); }
}

/* trend: glyph + sign + value, never colour alone. Tone is MEANING, not
   direction — a rise in rejections is bad, a rise in STP is good.        */
.trend {
  display: inline-flex; align-items: center; gap: 4px;
  font-family: var(--font-mono); font-size: var(--fs-2xs); font-weight: 600;
  font-variant-numeric: tabular-nums; white-space: nowrap;
}
.trend::before { font-size: var(--fs-4xs); line-height: 1; }
/* tone (meaning) and direction (glyph) are separate axes — a rise in
   rejections is bad, a rise in STP is good, a rise in volume is neither */
.trend.is-good    { color: var(--st-valid-ink); }
.trend.is-bad     { color: var(--st-invalid-ink); }
.trend.is-neutral { color: var(--ink-3); }
.trend--up::before   { content: '▲'; }
.trend--down::before { content: '▼'; }
.trend--flat::before { content: '—'; font-size: var(--fs-2xs); }
.trend-since { color: var(--ink-3); font-weight: 400; font-family: var(--font-ui); }

/* ══ 15. CHARTS — Phase 3 ════════════════════════════════════════════════
   Inline SVG driven entirely by the existing status palette. No library
   look-and-feel, no colour outside the seven families plus brand.        */
.chart { display: block; width: 100%; height: auto; overflow: visible; }
.chart .c-grid   { stroke: var(--line); stroke-width: 1; }
.chart .c-axis   { stroke: var(--line-strong); stroke-width: 1; }
.chart .c-label  { fill: var(--ink-3); font-family: var(--font-mono); font-size: var(--fs-micro); }
.chart .c-label--y { text-anchor: end; }
.chart .c-guide  { stroke: var(--ink-3); stroke-width: 1; stroke-dasharray: 3 3; opacity: .55; }
.chart .c-guide-label { fill: var(--ink-3); font-family: var(--font-mono); font-size: var(--fs-3xs); }

/* areas encode with a fill, never a bare outline */
.c-fill--valid      { fill: var(--st-valid);      opacity: .82; }
.c-fill--review     { fill: var(--st-review);     opacity: .82; }
.c-fill--invalid    { fill: var(--st-invalid);    opacity: .82; }
.c-fill--processing { fill: var(--st-processing); opacity: .82; }
.c-fill--pending    { fill: var(--st-pending);    opacity: .82; }
.c-fill--hold       { fill: var(--st-hold);       opacity: .82; }
.c-fill--unusable   { fill: var(--st-unusable);   opacity: .82; }
.c-fill--brand      { fill: var(--brand);         opacity: .12; }

.c-stroke--brand      { fill: none; stroke: var(--brand);         stroke-width: 2; stroke-linejoin: round; stroke-linecap: round; }
.c-stroke--ink        { fill: none; stroke: var(--ink);           stroke-width: 1.5; stroke-linejoin: round; stroke-linecap: round; stroke-dasharray: 4 3; }
.c-stroke--valid      { fill: none; stroke: var(--st-valid);      stroke-width: 2; stroke-linejoin: round; stroke-linecap: round; }
.c-dot--brand         { fill: var(--surface); stroke: var(--brand); stroke-width: 2; }

/* draw-on animation, one pass, honours reduced motion via the global rule */
.c-anim-draw { stroke-dasharray: var(--len, 1200); stroke-dashoffset: var(--len, 1200);
  animation: fq-draw 900ms var(--ease-out) forwards; }
@keyframes fq-draw { to { stroke-dashoffset: 0; } }
.c-anim-rise { transform-box: fill-box; transform-origin: bottom; animation: fq-rise var(--motion-standard) var(--ease-out) both; }
@keyframes fq-rise { from { transform: scaleY(.04); opacity: 0; } to { transform: none; opacity: 1; } }

/* sparkline inside a KPI card */
.spark { display: block; width: 108px; height: 34px; overflow: visible; }
@media (max-width: 599px) { .spark { width: 100%; } }

/* donut */
.donut { display: block; width: 148px; height: 148px; }
.donut circle { fill: none; stroke-width: 17; }
.donut .d-track { stroke: var(--canvas-sunken); }
.donut .d-seg { transition: stroke-dashoffset var(--motion-standard), stroke-width var(--motion-micro); }
.donut .d-seg:hover { stroke-width: 20; }
.d-seg--valid      { stroke: var(--st-valid); }
.d-seg--review     { stroke: var(--st-review); }
.d-seg--invalid    { stroke: var(--st-invalid); }
.d-seg--processing { stroke: var(--st-processing); }
.d-seg--pending    { stroke: var(--st-pending); }
.d-seg--hold       { stroke: var(--st-hold); }
.donut-centre { display: grid; place-items: center; text-align: center; }
.donut-centre .donut-value { font-family: var(--font-mono); font-size: var(--fs-num-sm); font-weight: 600; font-variant-numeric: tabular-nums; letter-spacing: -0.02em; }
.donut-centre .donut-label { font-size: var(--fs-2xs); color: var(--ink-3); }
.donut-wrap { position: relative; display: inline-grid; place-items: center; }
.donut-wrap > .donut-centre { position: absolute; inset: 0; }

/* horizontal breakdown bars */
.hbar { display: grid; gap: var(--sp-3); }
.hbar-row { display: grid; grid-template-columns: minmax(0, 1fr) 56px; gap: var(--sp-3); align-items: center; }
.hbar-head { display: flex; align-items: baseline; justify-content: space-between; gap: var(--sp-2); margin-bottom: 5px; }
.hbar-name { font-size: var(--fs-sm); color: var(--ink-2); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.hbar-track { height: 8px; background: var(--canvas-sunken); border-radius: var(--r-xs); overflow: hidden; }
.hbar-fill { height: 100%; border-radius: var(--r-xs); transform-origin: left;
  animation: fq-grow var(--motion-standard) var(--ease-out) both; }
@keyframes fq-grow { from { transform: scaleX(0); } to { transform: none; } }
.hbar-fill--review     { background: var(--st-review); }
.hbar-fill--invalid    { background: var(--st-invalid); }
.hbar-fill--unusable   { background: var(--st-unusable); }
.hbar-fill--hold       { background: var(--st-hold); }
.hbar-fill--pending    { background: var(--st-pending); }
.hbar-fill--processing { background: var(--st-processing); }
.hbar-count { font-family: var(--font-mono); font-size: var(--fs-sm); font-variant-numeric: tabular-nums;
  text-align: end; color: var(--ink); font-weight: 500; }
.hbar-pct { font-family: var(--font-mono); font-size: var(--fs-2xs); color: var(--ink-3); font-variant-numeric: tabular-nums; }

/* shared chart legend */
.legend { display: flex; flex-wrap: wrap; gap: var(--sp-2) var(--sp-4); }
.legend-item { display: inline-flex; align-items: center; gap: var(--sp-2); font-size: var(--fs-xs); color: var(--ink-3); }
.legend-key { width: 9px; height: 9px; border-radius: 2px; flex: none; }
.legend-key--line { height: 2px; width: 14px; border-radius: 1px; }

/* ══ 16. FILTER BAR — Phase 3 ════════════════════════════════════════════ */
.filterbar {
  display: flex; align-items: center; gap: var(--sp-2); flex-wrap: wrap;
  padding: var(--sp-3) var(--sp-4);
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--r-lg); box-shadow: var(--e-1);
}
.chip {
  display: inline-flex; align-items: center; gap: var(--sp-2);
  height: 28px; padding: 0 var(--sp-3);
  background: var(--surface-2); color: var(--ink-2);
  border: 1px solid var(--line); border-radius: var(--r-sm);
  font-size: var(--fs-xs); white-space: nowrap;
  transition: background var(--motion-micro), border-color var(--motion-micro), color var(--motion-micro);
}
.chip:hover { background: var(--surface-3); border-color: var(--line-strong); color: var(--ink); }
.chip .chip-key { color: var(--ink-3); }
.chip.is-active { background: var(--brand-tint); border-color: var(--brand-tint-2); color: var(--brand); }
.chip.is-active .chip-key { color: var(--brand); opacity: .7; }
.chip-clear { width: 15px; height: 15px; display: grid; place-items: center; border-radius: var(--r-full);
  background: var(--brand); color: var(--brand-on); font-size: var(--fs-4xs); line-height: 1; flex: none; }
.filterbar .filter-count { font-size: var(--fs-xs); color: var(--ink-3); margin-inline-start: auto; white-space: nowrap; }

/* prototype-only control — deliberately marked so it never reads as product chrome */
.proto {
  display: inline-flex; align-items: center; gap: var(--sp-2);
  padding: 3px 3px 3px var(--sp-2);
  border: 1px dashed var(--line-strong); border-radius: var(--r-md); background: var(--surface-2);
}
.proto-tag {
  font-family: var(--font-mono); font-size: var(--fs-3xs); letter-spacing: .06em; text-transform: uppercase;
  color: var(--ink-3); white-space: nowrap;
}
/* the label and the select are each unshrinkable at their min-content size, so
   on a phone the pair is wider than the page — let the pair wrap instead */
.proto { flex-wrap: wrap; }
.proto .select { height: 28px; font-size: var(--fs-xs); width: auto; box-shadow: none;
  min-width: 0; max-width: 100%; }

.cmp-foot {
  margin: var(--sp-3) 0 0; padding-top: var(--sp-3);
  border-top: 1px solid var(--line);
  font-size: var(--fs-xs); color: var(--ink-3); line-height: 1.5;
}
.cmp-foot .cmp-source { margin-inline-end: 3px; }

/* ── acting-role control (topbar) ──────────────────────────────────────────
   Keeps the dashed prototype marking of .proto even though it sits in product
   chrome: a real deployment never lets a user grant themselves a role, and the
   control should never be mistaken for one that would ship. */
.role-switch { flex: none; }
.role-btn {
  display: inline-flex; align-items: center; gap: var(--sp-2);
  height: 30px; max-width: 260px; padding: 0 var(--sp-2);
  border: 1px dashed var(--line-strong); border-radius: var(--r-md);
  background: var(--surface-2); color: var(--ink-2); font-size: var(--fs-xs);
  transition: background var(--motion-micro), border-color var(--motion-micro);
}
.role-btn:hover { background: var(--surface-3); border-color: var(--ink-4); }
.role-btn[aria-expanded="true"] { background: var(--surface-3); border-color: var(--brand); }
.role-btn-tag { flex: none; }
.role-btn-name {
  font-weight: 500; color: var(--ink);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.role-btn-chev { width: 14px; height: 14px; flex: none; color: var(--ink-3); }
/* the glyph only earns its space once the label is gone */
.role-btn-icon { width: 15px; height: 15px; flex: none; color: var(--ink-3); display: none; }
.role-menu { min-width: 296px; }
.role-opt { align-items: flex-start; gap: var(--sp-2); }
.role-opt-mark {
  flex: none; width: 14px; margin-top: 1px;
  color: var(--brand); font-size: var(--fs-sm); line-height: 1;
}
.role-opt-text { display: flex; flex-direction: column; gap: 1px; min-width: 0; }
.role-opt-name { color: inherit; }
.role-opt.is-current .role-opt-name { font-weight: 600; color: var(--ink); }

/* the tag is the first thing to go when the topbar tightens, then the label —
   the control itself stays reachable at every width */
@media (max-width: 1279px) { .role-btn-tag { display: none; } }
@media (max-width: 767px)  {
  .role-btn-name { display: none; }
  .role-btn-icon { display: block; }
  .role-btn { max-width: none; padding: 0 5px; gap: 2px; }
  /* anchored to the button it would hang off the left edge and be clipped —
     on a phone it spans the viewport under the topbar instead */
  .role-menu {
    position: fixed; top: calc(var(--topbar-h) + 6px);
    inset-inline-start: var(--sp-4); inset-inline-end: var(--sp-4);
    width: auto; min-width: 0; max-width: none;
  }
}

/* staggered panel entrance */
.stagger > * { animation: fq-fade-up var(--motion-standard) var(--ease-out) both;
  animation-delay: calc(var(--i, 0) * var(--stagger-step)); }

/* ══ 17. MOBILE TABLE TRANSFORM — Phase 3 ════════════════════════════════
   The canonical card-per-row transform promised by the Phase 1 responsive
   contract. Add `.dt--cards` to any table and give each <td> a data-label. */
@media (max-width: 767px) {
  .table-scroll:has(.dt--cards) { max-height: none; overflow-x: visible; }
  .dt--cards thead { display: none; }
  .dt--cards, .dt--cards tbody, .dt--cards tr, .dt--cards td { display: block; width: 100%; }
  .dt--cards tbody { padding: var(--sp-3); }
  .dt--cards tr {
    background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-md);
    padding: var(--sp-3); box-shadow: var(--e-1);
  }
  .dt--cards tr + tr { margin-top: var(--sp-3); }
  .dt--cards tbody tr:hover td { background: transparent; }
  .dt--cards tbody tr.is-selected { border-color: var(--brand-tint-2); background: var(--brand-tint); }
  .dt--cards td {
    border: 0; padding: 5px 0; text-align: start;
    display: flex; align-items: center; justify-content: space-between; gap: var(--sp-4);
  }
  .dt--cards td::before {
    content: attr(data-label); flex: none;
    font-family: var(--font-head); font-size: var(--fs-2xs); font-weight: 600;
    letter-spacing: var(--tr-wide); text-transform: uppercase; color: var(--ink-3);
  }
  .dt--cards td:empty, .dt--cards td.col-check { display: none; }
  .dt--cards td.col-num { text-align: end; }
  .dt--cards td.col-actions { width: auto; padding-top: var(--sp-3); margin-top: var(--sp-2); border-top: 1px solid var(--line); }
  .dt--cards td.col-actions::before { content: attr(data-label); }
  .dt--cards .meter { min-width: 0; max-width: 150px; }
}

/* ══ 18. PANEL GRID — Phase 3 ════════════════════════════════════════════ */
.panel-grid { display: grid; gap: var(--sp-4); grid-template-columns: repeat(3, minmax(0, 1fr)); align-items: start; }
.panel-grid > .span-2 { grid-column: span 2; }
@media (max-width: 1279px) {
  .panel-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 767px) {
  .panel-grid { grid-template-columns: minmax(0, 1fr); }
  .panel-grid > .span-2 { grid-column: span 1; }
}

/* ══ 19. CHEQUE IMAGE VIEWER — Phase 4 ═══════════════════════════════════
   The one genuinely new component since Phase 1. Built entirely from the
   existing elevation, radius and motion tokens so it reads as native.
   Transform-only: zoom, pan and rotate never touch layout.                */
.viewer {
  position: relative; overflow: hidden;
  background: var(--canvas-sunken);
  border: 1px solid var(--line); border-radius: var(--r-lg); box-shadow: var(--e-1);
}
.viewer-stage {
  position: relative; height: 420px; overflow: hidden;
  display: grid; place-items: center;
  cursor: grab; touch-action: none; user-select: none;
  background-image:
    linear-gradient(45deg, var(--surface-3) 25%, transparent 25%, transparent 75%, var(--surface-3) 75%),
    linear-gradient(45deg, var(--surface-3) 25%, transparent 25%, transparent 75%, var(--surface-3) 75%);
  background-size: 16px 16px; background-position: 0 0, 8px 8px;
}
.viewer-stage.is-panning { cursor: grabbing; }
.viewer-canvas {
  width: 86%; max-width: 760px;
  transform-origin: center center;
  transition: transform var(--motion-standard);
  will-change: transform;
  filter: drop-shadow(0 6px 18px rgba(17, 26, 36, .18));
}
.viewer-canvas.is-dragging { transition: none; }
.viewer-canvas svg { display: block; width: 100%; height: auto; }

.viewer-bar {
  position: absolute; inset-inline-start: var(--sp-3); inset-inline-end: var(--sp-3); top: var(--sp-3);
  display: flex; align-items: flex-start; justify-content: space-between; gap: var(--sp-3);
  pointer-events: none;
}
.viewer-bar > * { pointer-events: auto; }

.viewer-tools {
  position: absolute; left: 50%; bottom: var(--sp-3); transform: translateX(-50%);
  display: flex; align-items: center; gap: 2px; padding: 3px;
  background: color-mix(in srgb, var(--surface) 92%, transparent);
  backdrop-filter: blur(10px) saturate(1.2);
  border: 1px solid var(--line); border-radius: var(--r-md); box-shadow: var(--e-2);
}
.viewer-tools button {
  width: 30px; height: 28px; display: grid; place-items: center;
  border-radius: var(--r-sm); color: var(--ink-2);
  transition: background var(--motion-micro), color var(--motion-micro);
}
.viewer-tools button:hover:not(:disabled) { background: var(--surface-3); color: var(--ink); }
.viewer-tools button:disabled { color: var(--ink-disabled); cursor: not-allowed; }
.viewer-tools svg { width: 15px; height: 15px; }
.viewer-tools .viewer-zoom {
  min-width: 46px; padding: 0 var(--sp-2);
  font-family: var(--font-mono); font-size: var(--fs-2xs); font-variant-numeric: tabular-nums;
  color: var(--ink-3);
}
.viewer-tools .tool-sep { width: 1px; height: 18px; background: var(--line); margin: 0 3px; flex: none; }

.viewer-hint {
  position: absolute; inset-inline-end: var(--sp-3); bottom: var(--sp-3);
  font-family: var(--font-mono); font-size: var(--fs-2xs); color: var(--ink-3);
  background: color-mix(in srgb, var(--surface) 84%, transparent);
  padding: 3px var(--sp-2); border-radius: var(--r-sm);
}
@media (max-width: 1023px) { .viewer-stage { height: 340px; } .viewer-hint { display: none; } }
@media (max-width: 599px)  { .viewer-stage { height: 250px; } .viewer-canvas { width: 94%; } }

/* thumbnail strip (Extraction Results) */
.thumb-strip { display: flex; gap: var(--sp-3); overflow-x: auto; padding-bottom: var(--sp-1); }
.thumb {
  position: relative; flex: none; width: 208px; padding: var(--sp-2);
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-md);
  box-shadow: var(--e-1); cursor: zoom-in;
  transition: border-color var(--motion-micro), box-shadow var(--motion-micro), transform var(--motion-micro);
}
.thumb:hover { border-color: var(--brand-tint-2); box-shadow: var(--e-2); transform: translateY(-1px); }
.thumb svg { display: block; width: 100%; height: auto; border-radius: var(--r-xs); }
.thumb-cap { display: flex; align-items: center; justify-content: space-between; gap: var(--sp-2);
  margin-top: var(--sp-2); font-size: var(--fs-2xs); color: var(--ink-3); }

/* ══ 20. VERTICAL STATE TIMELINE — Phase 4 ═══════════════════════════════ */
.timeline { position: relative; padding-inline-start: 28px; }
.timeline::before {
  content: ''; position: absolute; inset-inline-start: 7px; top: 8px; bottom: 8px;
  width: 2px; background: var(--line); border-radius: var(--r-xs);
}
.tl-item { position: relative; padding-bottom: var(--sp-5); }
.tl-item:last-child { padding-bottom: 0; }
.tl-node {
  position: absolute; inset-inline-start: -28px; top: 3px;
  width: 16px; height: 16px; border-radius: var(--r-full);
  background: var(--surface); border: 2px solid var(--line-strong);
  display: grid; place-items: center;
}
.tl-node svg { width: 8px; height: 8px; color: var(--surface); }
.tl-item--valid      .tl-node { background: var(--st-valid);      border-color: var(--st-valid); }
.tl-item--review     .tl-node { background: var(--st-review);     border-color: var(--st-review); }
.tl-item--invalid    .tl-node { background: var(--st-invalid);    border-color: var(--st-invalid); }
.tl-item--processing .tl-node { background: var(--st-processing); border-color: var(--st-processing); }
.tl-item--pending    .tl-node { background: var(--surface);       border-color: var(--st-pending-line); }
.tl-item--hold       .tl-node { background: var(--st-hold);       border-color: var(--st-hold); }
.tl-item.is-current .tl-node { box-shadow: 0 0 0 4px var(--brand-tint-2); }
.tl-item.is-future  { opacity: .55; }
.tl-item.is-future .tl-node { border-style: dashed; }
.tl-head { display: flex; align-items: baseline; justify-content: space-between; gap: var(--sp-3); flex-wrap: wrap; }
.tl-name { font-size: var(--fs-sm); font-weight: 500; color: var(--ink); }
.tl-time { font-family: var(--font-mono); font-size: var(--fs-2xs); color: var(--ink-3); white-space: nowrap; }
.tl-meta { font-size: var(--fs-xs); color: var(--ink-3); margin-top: 2px; }
.tl-dur { font-family: var(--font-mono); font-size: var(--fs-2xs); color: var(--ink-3); }

/* ══ 21. UPLOAD SLOTS & PROGRESS — Phase 4 ═══════════════════════════════ */
.slot-grid { display: grid; gap: var(--sp-4); grid-template-columns: repeat(2, minmax(0, 1fr)); }
@media (max-width: 767px) { .slot-grid { grid-template-columns: minmax(0, 1fr); } }
.slot-label { display: flex; align-items: baseline; justify-content: space-between; gap: var(--sp-2); margin-bottom: var(--sp-2); }
.slot-label .slot-name { font-size: var(--fs-sm); font-weight: 500; color: var(--ink-2); }

.slot-filled {
  padding: var(--sp-3); background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--r-lg); box-shadow: var(--e-1);
  animation: fq-fade-up var(--motion-standard) both;
}
.slot-filled .slot-thumb {
  border-radius: var(--r-md); overflow: hidden; border: 1px solid var(--line);
  background: var(--canvas-sunken);
}
.slot-filled .slot-thumb svg { display: block; width: 100%; height: auto; }
.slot-file { display: flex; align-items: center; gap: var(--sp-2); margin-top: var(--sp-3); }
.slot-file .slot-fname { font-family: var(--font-mono); font-size: var(--fs-2xs); color: var(--ink-2);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.slot-file .slot-size { font-family: var(--font-mono); font-size: var(--fs-2xs); color: var(--ink-3); flex: none; }

.progress { height: 4px; background: var(--canvas-sunken); border-radius: var(--r-xs); overflow: hidden; }
.progress-fill { height: 100%; background: var(--brand); border-radius: var(--r-xs);
  transition: width var(--motion-standard) linear; }
.progress-fill.is-done { background: var(--st-valid); }
.progress-fill.is-failed { background: var(--st-invalid); }
.progress-label { display: flex; align-items: center; justify-content: space-between; gap: var(--sp-2);
  margin-bottom: 5px; font-size: var(--fs-2xs); color: var(--ink-3); }
.progress-label .num { color: var(--ink-2); }

/* ══ 22. INLINE-EDITABLE FIELD ROW — Phase 4 ═════════════════════════════ */
.efields { display: grid; gap: var(--sp-2); }
.ef-row {
  display: grid; gap: var(--sp-3); align-items: center;
  grid-template-columns: 168px minmax(0, 1fr) 170px 138px 74px;
  padding: var(--sp-3) var(--sp-4);
  background: var(--surface); border: 1px solid var(--line);
  border-inline-start: 3px solid transparent; border-radius: var(--r-md);
  transition: border-color var(--motion-micro), background var(--motion-micro), box-shadow var(--motion-micro);
}
.ef-row:hover { border-color: var(--line-strong); }
.ef-row.is-low     { border-inline-start-color: var(--st-review);  background: color-mix(in srgb, var(--st-review-bg) 45%, var(--surface)); }
.ef-row.is-missing { border-inline-start-color: var(--st-unusable); background: color-mix(in srgb, var(--st-unusable-bg) 55%, var(--surface)); }
.ef-row.is-editing { border-color: var(--brand); background: var(--surface); box-shadow: 0 0 0 3px var(--brand-tint-2); }
.ef-row.is-saved   { border-inline-start-color: var(--st-valid); }

.ef-name { display: flex; flex-direction: column; gap: 2px; }
.ef-name .ef-title { font-size: var(--fs-sm); font-weight: 500; color: var(--ink); }
.ef-name .ef-src {
  align-self: flex-start; padding: 1px 5px; border: 1px solid var(--line); border-radius: var(--r-sm);
  font-family: var(--font-mono); font-size: var(--fs-3xs); letter-spacing: .06em; color: var(--ink-3);
}
.ef-value { min-width: 0; display: flex; align-items: center; gap: var(--sp-2); }
.ef-value .ef-text {
  font-family: var(--font-mono); font-size: var(--fs-sm); color: var(--ink);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.ef-value .ef-text.is-empty { color: var(--ink-3); font-style: italic; font-family: var(--font-ui); }
.ef-value .input { height: 32px; font-family: var(--font-mono); font-size: var(--fs-sm); }
.ef-edit {
  opacity: 0; width: 26px; height: 26px; flex: none; display: grid; place-items: center;
  border-radius: var(--r-sm); color: var(--ink-3);
  transition: opacity var(--motion-micro), background var(--motion-micro), color var(--motion-micro);
}
.ef-row:hover .ef-edit, .ef-edit:focus-visible { opacity: 1; }
.ef-edit:hover { background: var(--surface-3); color: var(--ink); }
.ef-edit svg { width: 14px; height: 14px; }
.ef-actions { display: flex; gap: var(--sp-2); justify-content: flex-end; }
.ef-audit {
  display: inline-flex; align-items: center; gap: 4px; margin-top: 4px;
  font-size: var(--fs-2xs); color: var(--st-valid-ink);
  animation: fq-settle var(--motion-standard) both;
}
.ef-audit svg { width: 11px; height: 11px; }
.ef-shimmer { height: 13px; width: 62%; }

@media (max-width: 1023px) {
  .ef-row { grid-template-columns: 150px minmax(0, 1fr) 140px 120px; }
  .ef-row > .ef-actions { grid-column: 1 / -1; justify-content: flex-start; }
}
@media (max-width: 767px) {
  .ef-row { grid-template-columns: minmax(0, 1fr); gap: var(--sp-2); padding: var(--sp-3); }
  .ef-row > * { min-width: 0; }
  .ef-row .ef-edit { opacity: 1; }
  .ef-row .ef-actions { justify-content: flex-end; }
}

/* ══ 23. COLLAPSIBLE CARD SECTION — Phase 4 ══════════════════════════════ */
details.card-collapse { padding: 0; }
details.card-collapse > summary {
  display: flex; align-items: center; justify-content: space-between; gap: var(--sp-3);
  padding: var(--sp-4) var(--sp-5); cursor: pointer; list-style: none;
  border-radius: var(--r-lg);
  transition: background var(--motion-micro);
}
details.card-collapse > summary::-webkit-details-marker { display: none; }
details.card-collapse > summary:hover { background: var(--surface-2); }
details.card-collapse[open] > summary { border-bottom: 1px solid var(--line); border-radius: var(--r-lg) var(--r-lg) 0 0; }
details.card-collapse > summary h3 { font-size: var(--fs-lg); }
details.card-collapse .summary-chev {
  width: 0; height: 0; flex: none; margin-inline-start: auto;
  border-top: 4.5px solid transparent; border-bottom: 4.5px solid transparent; border-left: 6.5px solid var(--ink-4);
  transition: transform var(--motion-micro);
}
details.card-collapse[open] .summary-chev { transform: rotate(90deg); }
details.card-collapse > .card-body { animation: fq-fade-up var(--motion-standard) both; }

/* "live" refresh affordance for the processing queue */
.live-dot { width: 7px; height: 7px; border-radius: var(--r-full); background: var(--st-valid); flex: none;
  animation: fq-live 2.4s var(--ease-inout) infinite; }
@keyframes fq-live { 0%, 100% { opacity: 1; box-shadow: 0 0 0 0 var(--st-valid-line); } 55% { opacity: .55; box-shadow: 0 0 0 4px transparent; } }

/* ══ 24. SPLIT LAYOUTS — Phase 4 ═════════════════════════════════════════ */
.split-main { display: grid; gap: var(--sp-6); grid-template-columns: minmax(0, 1.62fr) minmax(0, 1fr); align-items: start; }
.split-even { display: grid; gap: var(--sp-6); grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); align-items: start; }
.split-viewer { display: grid; gap: var(--sp-6); grid-template-columns: minmax(0, 1.12fr) minmax(0, 1fr); align-items: start; }
@media (max-width: 1279px) {
  .split-main, .split-even, .split-viewer { grid-template-columns: minmax(0, 1fr); }
}
/* column-priority collapse for wide operational tables */
@media (max-width: 1439px) { .dt .prio-4 { display: none; } }
@media (max-width: 1279px) { .dt .prio-3 { display: none; } }
@media (max-width: 1023px) { .dt .prio-2 { display: none; } }
@media (max-width: 767px)  { .dt--cards .prio-2, .dt--cards .prio-3, .dt--cards .prio-4 { display: flex; } }

/* wide modal — used to open the cheque viewer full-size from a thumbnail */
.modal.is-wide { width: min(920px, calc(100vw - 32px)); }

/* The evidence column stays put while the interpretation column scrolls — a
   reviewer must never lose sight of the cheque while reading what was read
   from it. Only above tablet-lg, where there are two real columns. */
@media (min-width: 1280px) {
  .split-viewer > .sticky-col { position: sticky; top: calc(var(--topbar-h) + var(--sp-4)); }
}

/* ══ 25. KEY-VALUE REFERENCE GRID — Phase 5 ══════════════════════════════
   Reference data, not operational density: generous spacing, scannable,
   precision over compression. Distinct in tone from the queue tables.     */
.kv-grid { display: grid; gap: var(--sp-5) var(--sp-7); grid-template-columns: repeat(auto-fit, minmax(228px, 1fr)); }
.kv-grid.is-tight { gap: var(--sp-4) var(--sp-6); }
.kv { display: flex; flex-direction: column; gap: 5px; min-width: 0; padding-inline-start: 0;
  border-inline-start: 3px solid transparent; transition: border-color var(--motion-micro), padding var(--motion-micro); }
.kv-label { display: flex; align-items: center; gap: var(--sp-2);
  font-size: var(--fs-xs); color: var(--ink-3); letter-spacing: .01em; }
.kv-value { font-size: var(--fs-md); color: var(--ink); line-height: 1.4; word-break: break-word; }
.kv-value.num, .kv-value .num { font-variant-numeric: tabular-nums; }
.kv-value.is-blank { color: var(--ink-3); font-style: italic; }
.kv-sub { font-size: var(--fs-xs); color: var(--ink-3); }
.kv.is-pending { padding-inline-start: var(--sp-3); }
.kv.is-locked .kv-label::after {
  content: ''; width: 11px; height: 11px; flex: none; opacity: .5;
  background: currentColor;
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3E%3Cpath d='M4 8.6h12v8.4H4zM6.8 8.6V6.4a3.2 3.2 0 0 1 6.4 0v2.2' fill='none' stroke='%23000' stroke-width='1.8'/%3E%3C/svg%3E") center/contain no-repeat;
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3E%3Cpath d='M4 8.6h12v8.4H4zM6.8 8.6V6.4a3.2 3.2 0 0 1 6.4 0v2.2' fill='none' stroke='%23000' stroke-width='1.8'/%3E%3C/svg%3E") center/contain no-repeat;
}

/* ══ 26. MAKER-CHECKER PENDING-APPROVAL PATTERN — Phase 5 ════════════════
   ONE treatment for every dual-controlled change in every later phase.
   A proposed change is never shown as if it were live: the record keeps
   its current value and the proposal sits beside it, clearly separate.
   Routine governance, not an error — amber, calm entrance, never red.    */
.pending-panel {
  border: 1px solid var(--st-review-line); border-radius: var(--r-lg); overflow: hidden;
  background: var(--surface); box-shadow: var(--e-1);
  animation: fq-settle var(--motion-standard) var(--ease-out) both;
}
.pending-panel-head {
  display: flex; align-items: flex-start; gap: var(--sp-3); flex-wrap: wrap;
  padding: var(--sp-4) var(--sp-5);
  background: var(--st-review-bg); border-bottom: 1px solid var(--st-review-line);
  color: var(--st-review-ink);
}
.pending-panel-head svg { width: 17px; height: 17px; flex: none; margin-top: 2px; }
.pending-panel-head h3 { font-size: var(--fs-md); color: var(--st-review-ink); }
.pending-panel-head p { font-size: var(--fs-xs); margin-top: 3px; opacity: .92; max-width: 74ch; }
.pending-panel-head .pending-actions { margin-inline-start: auto; display: flex; gap: var(--sp-2); }
.pending-panel-body { padding: var(--sp-4) var(--sp-5); }
.pending-foot {
  display: flex; align-items: center; justify-content: space-between; gap: var(--sp-3); flex-wrap: wrap;
  padding: var(--sp-3) var(--sp-5); border-top: 1px solid var(--line); background: var(--surface-2);
  font-size: var(--fs-xs); color: var(--ink-3);
}

/* the diff itself: current → proposed, never merged into one value */
.diff-row {
  display: grid; grid-template-columns: 176px minmax(0, 1fr) 26px minmax(0, 1fr);
  gap: var(--sp-3); align-items: center; padding: var(--sp-3) 0;
}
.diff-row + .diff-row { border-top: 1px solid var(--line); }
.diff-label { font-size: var(--fs-sm); color: var(--ink-3); }
.diff-from { font-family: var(--font-mono); font-size: var(--fs-sm); color: var(--ink-3); text-decoration: line-through;
  text-decoration-color: var(--st-invalid-line); overflow: hidden; text-overflow: ellipsis; }
.diff-arrow { display: grid; place-items: center; color: var(--ink-3); font-size: var(--fs-glyph); }
.diff-to { font-family: var(--font-mono); font-size: var(--fs-sm); color: var(--st-review-ink); font-weight: 600;
  overflow: hidden; text-overflow: ellipsis; }
@media (max-width: 767px) {
  .diff-row { grid-template-columns: minmax(0, 1fr); gap: 4px; padding: var(--sp-3) 0; }
  .diff-arrow { display: none; }
  .diff-from::before { content: 'Current: '; font-family: var(--font-ui); color: var(--ink-3); }
  .diff-to::before   { content: 'Proposed: '; font-family: var(--font-ui); color: var(--ink-3); font-weight: 400; }
}

.pending-chip {
  display: inline-flex; align-items: center; gap: 4px; height: 18px; padding: 0 6px;
  background: var(--st-review-bg); color: var(--st-review-ink);
  border: 1px solid var(--st-review-line); border-radius: var(--r-sm);
  font-family: var(--font-head); font-size: var(--fs-3xs); font-weight: 600;
  letter-spacing: var(--tr-wide); text-transform: uppercase; white-space: nowrap;
}

/* read-only marker — least privilege stated, not implied */
.viewonly {
  display: inline-flex; align-items: center; gap: var(--sp-2); height: 26px; padding: 0 var(--sp-3);
  background: var(--canvas-sunken); border-radius: var(--r-sm);
  font-size: var(--fs-xs); color: var(--ink-3); white-space: nowrap;
}
.viewonly svg { width: 13px; height: 13px; opacity: .7; }

/* ══ 27. MASKED / HOLD-TO-REVEAL — Phase 5 ═══════════════════════════════
   Reference signatures are the comparison baseline for every cheque. Access
   is deliberate and logged, so the reveal must FEEL deliberate: a held
   press, not a hover.                                                     */
.masked { position: relative; border: 1px solid var(--line); border-radius: var(--r-md);
  overflow: hidden; background: var(--surface-2); }
.masked-media { display: block; width: 100%; filter: blur(10px) saturate(.35) contrast(.85); transform: scale(1.06);
  transition: filter var(--dur-reveal) var(--ease-out), transform var(--dur-reveal) var(--ease-out); }
.masked-media svg { display: block; width: 100%; height: auto; }
.masked.is-revealed .masked-media { filter: none; transform: none; }
.masked-scrim {
  position: absolute; inset: 0; display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: var(--sp-2); padding: var(--sp-3); text-align: center;
  background: color-mix(in srgb, var(--surface) 58%, transparent);
  backdrop-filter: blur(1px);
  transition: opacity var(--motion-standard);
}
.masked.is-revealed .masked-scrim { opacity: 0; pointer-events: none; }
.masked-scrim .masked-note { font-size: var(--fs-2xs); color: var(--ink-3); max-width: 30ch; }
/* the accountability line under a visible specimen — quiet, but present, so the
   reviewer knows the view is on the record */
.masked-foot {
  display: flex; align-items: center; gap: var(--sp-2);
  padding: var(--sp-2) var(--sp-3); margin: 0;
  border-top: 1px solid var(--line); background: var(--surface-2);
  font-size: var(--fs-2xs); color: var(--ink-3);
}
.masked-foot svg { width: 13px; height: 13px; flex: none; color: var(--ink-4); }

.hold-reveal {
  position: relative; overflow: hidden;
  display: inline-flex; align-items: center; justify-content: center; gap: var(--sp-2);
  height: 32px; padding: 0 var(--sp-4);
  background: var(--surface); color: var(--ink); border: 1px solid var(--line-strong);
  border-radius: var(--r-md); box-shadow: var(--e-1);
  font-size: var(--fs-xs); font-weight: 500; white-space: nowrap;
  transition: border-color var(--motion-micro);
}
.hold-reveal:hover { border-color: var(--brand); }
.hold-reveal svg { width: 14px; height: 14px; }
.hold-reveal > span { position: relative; z-index: 1; display: inline-flex; align-items: center; gap: var(--sp-2); }
.hold-fill {
  position: absolute; inset-inline-start: 0; top: 0; bottom: 0; width: 0;
  background: var(--brand-tint-2); z-index: 0;
}
.hold-reveal.is-holding .hold-fill { width: 100%; transition: width var(--dur-hold) linear; }
.hold-reveal.is-revealing { border-color: var(--brand); }

.reveal-log {
  display: inline-flex; align-items: center; gap: var(--sp-2);
  font-size: var(--fs-2xs); color: var(--st-valid-ink);
  animation: fq-settle var(--motion-standard) both;
}
.reveal-log svg { width: 12px; height: 12px; }
.masked-denied { color: var(--st-hold-ink); }

/* ══ 28. EFFECTIVE-DATED VERSION LIST — Phase 5 ══════════════════════════ */
.ver-list { display: grid; gap: var(--sp-2); }
.ver {
  display: grid; grid-template-columns: 132px minmax(0, 1fr) auto; gap: var(--sp-4); align-items: center;
  padding: var(--sp-3) var(--sp-4);
  background: var(--surface); border: 1px solid var(--line);
  border-inline-start: 1px solid var(--line); border-radius: var(--r-md);
  transition: border-color var(--motion-micro), box-shadow var(--motion-micro);
}
.ver:hover { box-shadow: var(--e-1); }
.ver--current   { background: color-mix(in srgb, var(--st-valid-bg) 32%, var(--surface)); }
.ver--scheduled { border-style: dashed; }
.ver--expired   { opacity: .68; }
.ver--pending   { background: color-mix(in srgb, var(--st-review-bg) 38%, var(--surface)); }
.ver-when { font-family: var(--font-mono); font-size: var(--fs-xs); color: var(--ink-2); font-variant-numeric: tabular-nums; }
.ver-what { font-size: var(--fs-sm); color: var(--ink); min-width: 0; }
.ver-who  { font-size: var(--fs-xs); color: var(--ink-3); margin-top: 2px; }
@media (max-width: 767px) {
  .ver { grid-template-columns: minmax(0, 1fr); gap: var(--sp-2); }
}

/* ══ 29. COMPARISON LAYOUT — Phase 5, reused by Phase 6 ══════════════════
   Master value beside extracted value with an explicit verdict. Never merge
   the two into one column: a reviewer must always be able to see what the
   controlled source says AND what the cheque said.                        */
.cmp { width: 100%; border: 1px solid var(--line); border-radius: var(--r-lg); overflow: hidden; background: var(--surface); }
.cmp-head, .cmp-row { display: grid; grid-template-columns: 168px minmax(0, 1fr) minmax(0, 1fr) 148px; }
.cmp-head > * {
  padding: var(--sp-2) var(--sp-4); background: var(--surface-2); border-bottom: 1px solid var(--line-strong);
  font-family: var(--font-head); font-size: var(--fs-2xs); font-weight: 600;
  letter-spacing: var(--tr-wide); text-transform: uppercase; color: var(--ink-3);
}
.cmp-row > * { padding: var(--sp-3) var(--sp-4); border-bottom: 1px solid var(--line); font-size: var(--fs-sm); min-width: 0; }
.cmp-row:last-child > * { border-bottom: 0; }
.cmp-row > :first-child { color: var(--ink-3); font-size: var(--fs-xs); }
.cmp-row .cmp-val { font-family: var(--font-mono); color: var(--ink); overflow: hidden; text-overflow: ellipsis; }
.cmp-row .cmp-val.is-blank { font-family: var(--font-ui); font-style: italic; color: var(--ink-3); }
/* ONE mismatch technique across every component that shows a discrepancy:
   a coloured left cap, a small icon, a tint. Never bold-only, never three
   competing treatments. Matches .chk--review / .chk--fail exactly.        */
.cmp-row.is-mismatch, .cmp-row.is-fail, .cmp-row.is-missing { border-inline-start: 3px solid transparent; }
.cmp-row.is-mismatch > :first-child, .cmp-row.is-fail > :first-child, .cmp-row.is-missing > :first-child {
  display: flex; align-items: center; gap: 6px;
}
.cmp-row.is-mismatch > :first-child::before,
.cmp-row.is-fail > :first-child::before,
.cmp-row.is-missing > :first-child::before {
  content: ''; width: 13px; height: 13px; flex: none; background: currentColor;
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3E%3Cpath d='M10 2.6 18.6 17.4H1.4Z' fill='none' stroke='%23000' stroke-width='1.8' stroke-linejoin='round'/%3E%3Cpath d='M10 8v3.4M10 14.2h.01' stroke='%23000' stroke-width='1.8' stroke-linecap='round'/%3E%3C/svg%3E") center/contain no-repeat;
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3E%3Cpath d='M10 2.6 18.6 17.4H1.4Z' fill='none' stroke='%23000' stroke-width='1.8' stroke-linejoin='round'/%3E%3Cpath d='M10 8v3.4M10 14.2h.01' stroke='%23000' stroke-width='1.8' stroke-linecap='round'/%3E%3C/svg%3E") center/contain no-repeat;
}
.cmp-row.is-mismatch {
  background: color-mix(in srgb, var(--st-review-bg) 46%, var(--surface));
 box-shadow: inset 3px 0 0 var(--st-review);
}
.cmp-row.is-mismatch > :first-child { color: var(--st-review-ink); }
.cmp-row.is-mismatch .cmp-val:last-of-type { color: var(--st-review-ink); font-weight: 600; }
.cmp-row.is-missing {
  background: color-mix(in srgb, var(--st-unusable-bg) 52%, var(--surface));
  box-shadow: inset 3px 0 0 var(--st-unusable);
}
.cmp-row.is-missing > :first-child { color: var(--st-unusable-ink); }
.cmp-row.is-fail {
  background: color-mix(in srgb, var(--st-invalid-bg) 42%, var(--surface));
  box-shadow: inset 3px 0 0 var(--st-invalid);
}
.cmp-row.is-fail > :first-child { color: var(--st-invalid-ink); }
.cmp-source { font-family: var(--font-head); font-size: var(--fs-3xs); letter-spacing: var(--tr-wide);
  text-transform: uppercase; color: var(--ink-3); display: block; margin-bottom: 2px; }
@media (max-width: 1023px) {
  .cmp-head { display: none; }
  .cmp-row { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
  .cmp-row > :first-child { grid-column: 1 / -1; padding-bottom: 0; border-bottom: 0; }
  .cmp-row > :last-child  { grid-column: 1 / -1; padding-top: var(--sp-2); }
  .cmp-row > :nth-child(2)::before { content: 'Master'; }
  .cmp-row > :nth-child(3)::before { content: 'Extracted'; }
  .cmp-row > :nth-child(2)::before, .cmp-row > :nth-child(3)::before {
    display: block; font-family: var(--font-head); font-size: var(--fs-3xs); letter-spacing: var(--tr-wide);
    text-transform: uppercase; color: var(--ink-3); margin-bottom: 2px;
  }
  .cmp-row > :nth-child(2), .cmp-row > :nth-child(3) { border-bottom: 0; }
}

/* operationally-important gap on a reference row — noticeable, not alarming */
.dt tbody tr.is-flagged td:first-child { box-shadow: inset 3px 0 0 var(--st-review); }
@media (max-width: 767px) {
  .dt--cards tbody tr.is-flagged { border-inline-start: 3px solid var(--st-review); }
  .dt--cards tbody tr.is-flagged td:first-child { box-shadow: none; }
}

/* ══ 30. DECISION HERO — Phase 6 ═════════════════════════════════════════
   The structured validation decision (FR-021). Highest thing in the
   hierarchy, entering with confidence — never celebration.                */
.decision {
  display: grid; grid-template-columns: auto minmax(0, 1fr) auto; gap: var(--sp-5); align-items: center;
  padding: var(--sp-6); background: var(--surface);
  border: 1px solid var(--line); border-inline-start: 1px solid var(--line);
  border-radius: var(--r-lg); box-shadow: var(--e-1);
  animation: fq-decision var(--motion-emphasis) var(--ease-entry) both;
}
@keyframes fq-decision { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: none; } }
.decision-mark { width: 54px; height: 54px; flex: none; display: grid; place-items: center;
  border-radius: var(--r-lg); border: 1px solid; }
.decision-mark svg { width: 26px; height: 26px; }
.decision h2 { font-size: var(--fs-2xl); line-height: var(--lh-2xl); }
.decision .decision-sub { font-size: var(--fs-sm); color: var(--ink-3); margin-top: 5px; max-width: 72ch; }
.decision .decision-meta { display: flex; gap: var(--sp-4); flex-wrap: wrap; margin-top: var(--sp-3);
  font-family: var(--font-mono); font-size: var(--fs-2xs); color: var(--ink-3); }
.decision .decision-actions { display: flex; flex-direction: column; gap: var(--sp-2); }
.decision--valid      { }
.decision--valid      .decision-mark { background: var(--st-valid-bg); border-color: var(--st-valid-line); color: var(--st-valid); }
.decision--review     { }
.decision--review     .decision-mark { background: var(--st-review-bg); border-color: var(--st-review-line); color: var(--st-review); }
.decision--invalid    { }
.decision--invalid    .decision-mark { background: var(--st-invalid-bg); border-color: var(--st-invalid-line); color: var(--st-invalid); }
.decision--hold       { }
.decision--hold       .decision-mark { background: var(--st-hold-bg); border-color: var(--st-hold-line); color: var(--st-hold); }
.decision--processing { }
.decision--processing .decision-mark { background: var(--st-processing-bg); border-color: var(--st-processing-line); color: var(--st-processing); }
@media (max-width: 1023px) {
  .decision { grid-template-columns: auto minmax(0, 1fr); }
  .decision .decision-actions { grid-column: 1 / -1; flex-direction: row; flex-wrap: wrap; }
}
@media (max-width: 599px) {
  .decision { grid-template-columns: minmax(0, 1fr); padding: var(--sp-5); }
  .decision h2 { font-size: var(--fs-xl); }
  .decision .decision-actions .btn { flex: 1 1 100%; }
}

/* ══ 31. CHECK LIST — Phase 6 ════════════════════════════════════════════
   Every check the engine ran, grouped. Failures must be scannable first,
   so each carries a left cap and the group header counts them.           */
.chk-group + .chk-group { margin-top: var(--sp-4); }
.chk-group-head {
  display: flex; align-items: center; justify-content: space-between; gap: var(--sp-3); flex-wrap: wrap;
  padding: var(--sp-3) var(--sp-5); background: var(--surface-2);
  border: 1px solid var(--line); border-bottom: 0; border-radius: var(--r-lg) var(--r-lg) 0 0;
}
.chk-group-head h3 { font-size: var(--fs-md); }
.chk-group-head .chk-counts { display: flex; gap: var(--sp-2); flex-wrap: wrap; }
.chk-body { border: 1px solid var(--line); border-radius: 0 0 var(--r-lg) var(--r-lg); overflow: hidden; background: var(--surface); }

.chk { border-top: 1px solid var(--line); }
.chk:first-child { border-top: 0; }
.chk-row {
  display: grid; grid-template-columns: 20px minmax(0, 1.1fr) minmax(0, 1fr) 152px 20px;
  gap: var(--sp-3); align-items: center; width: 100%; text-align: start;
  padding: var(--sp-3) var(--sp-5);
  border-inline-start: 3px solid transparent;
  transition: background var(--motion-micro), border-color var(--motion-micro);
}
.chk-row:hover { background: var(--surface-2); }
.chk-dot { width: 9px; height: 9px; border-radius: var(--r-full); justify-self: center; flex: none; }
.chk-name { font-size: var(--fs-sm); color: var(--ink); min-width: 0; }
.chk-detail { font-family: var(--font-mono); font-size: var(--fs-xs); color: var(--ink-3);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.chk-chev { width: 0; height: 0; justify-self: center; flex: none;
  border-top: 4px solid transparent; border-bottom: 4px solid transparent; border-left: 6px solid var(--ink-4);
  transition: transform var(--motion-micro); }
.chk.is-open .chk-chev { transform: rotate(90deg); }

.chk--pass    .chk-dot { background: var(--st-valid); }
.chk--review  { }
.chk--review  .chk-row { border-inline-start-color: var(--st-review);  background: color-mix(in srgb, var(--st-review-bg) 34%, var(--surface)); }
.chk--review  .chk-dot { background: var(--st-review); }
.chk--fail    .chk-row { border-inline-start-color: var(--st-invalid); background: color-mix(in srgb, var(--st-invalid-bg) 34%, var(--surface)); }
.chk--fail    .chk-dot { background: var(--st-invalid); }
/* a check that could not run is NOT a check that ran and failed */
.chk--error   .chk-row { border-inline-start-color: var(--st-unusable); background: color-mix(in srgb, var(--st-unusable-bg) 46%, var(--surface)); }
.chk--error   .chk-dot { background: var(--st-unusable);
  -webkit-mask: repeating-linear-gradient(135deg, #000 0 1.5px, transparent 1.5px 3.5px);
  mask: repeating-linear-gradient(135deg, #000 0 1.5px, transparent 1.5px 3.5px); }
.chk--pending .chk-dot { border: 2px solid var(--st-pending); background: transparent; }

.chk-why { display: grid; grid-template-rows: 0fr; transition: grid-template-rows var(--motion-standard); }
.chk.is-open .chk-why { grid-template-rows: 1fr; }
.chk-why > div { overflow: hidden; min-height: 0; }
.chk-why-inner { padding: 0 var(--sp-5) var(--sp-4) calc(var(--sp-5) + 32px); }
.chk-why-inner p { font-size: var(--fs-sm); color: var(--ink-2); max-width: 78ch; }
.chk-why-inner .chk-evidence {
  margin-top: var(--sp-3); padding: var(--sp-3); background: var(--surface-2);
  border: 1px solid var(--line); border-radius: var(--r-md);
  font-family: var(--font-mono); font-size: var(--fs-xs); color: var(--ink-2);
}
@media (max-width: 1023px) {
  .chk-row { grid-template-columns: 20px minmax(0, 1fr) 140px 20px; }
  .chk-row .chk-detail { display: none; }
  .chk-why-inner { padding-inline-start: var(--sp-5); }
}
@media (max-width: 599px) {
  .chk-row { grid-template-columns: 20px minmax(0, 1fr) 20px; padding: var(--sp-3) var(--sp-4); }
  .chk-row .chk-verdict { grid-column: 2; }
}

/* jump-to-failure strip */
.attention-strip {
  display: flex; align-items: center; gap: var(--sp-2); flex-wrap: wrap;
  padding: var(--sp-3) var(--sp-4);
  background: var(--st-review-bg); border: 1px solid var(--st-review-line);
  border-inline-start: 1px solid var(--line); border-radius: var(--r-md);
  font-size: var(--fs-sm); color: var(--st-review-ink);
}
.attention-strip .chip { background: var(--surface); border-color: var(--st-review-line); color: var(--st-review-ink); }
.attention-strip .chip:hover { background: var(--st-review-bg); }

/* risk indicator chips — indicators, never conclusions */
.risk-list { display: grid; gap: var(--sp-2); }
.risk-item {
  display: grid; grid-template-columns: auto minmax(0, 1fr) auto; gap: var(--sp-3); align-items: start;
  padding: var(--sp-3) var(--sp-4);
  background: var(--surface); border: 1px solid var(--line);
  border-inline-start: 1px solid var(--line); border-radius: var(--r-md);
}
.risk-item .risk-mark { width: 20px; height: 20px; display: grid; place-items: center; color: var(--st-hold); }
.risk-item .risk-mark svg { width: 15px; height: 15px; }
.risk-name { font-size: var(--fs-sm); font-weight: 500; color: var(--ink); }
.risk-why { font-size: var(--fs-xs); color: var(--ink-3); margin-top: 2px; }

/* ══ 32. SIGNATURE COMPARISON — Phase 6, reused by Phase 7 ═══════════════
   Registered reference beside the signature lifted from the cheque, with an
   overlay mode for genuine stroke-by-stroke inspection. Built once here and
   mounted verbatim inside the Manual Review Workbench.                    */
.sigcmp-stage { display: grid; }
.sigcmp-pane {
  grid-area: 1 / 1; opacity: 0; transform: scale(.988); pointer-events: none;
  transition: opacity var(--motion-standard), transform var(--motion-standard);
}
.sigcmp-pane.is-active { opacity: 1; transform: none; pointer-events: auto; }

.sig-pair { display: grid; grid-template-columns: minmax(0, 1fr) 58px minmax(0, 1fr); gap: var(--sp-3); align-items: center; }
.sig-side { min-width: 0; }
.sig-side-head {
  display: flex; align-items: baseline; justify-content: space-between; gap: var(--sp-2);
  margin-bottom: var(--sp-2); flex-wrap: wrap;
}
.sig-side-label {
  font-family: var(--font-head); font-size: var(--fs-2xs); font-weight: 600;
  letter-spacing: var(--tr-wide); text-transform: uppercase; color: var(--ink-3);
}
.sig-side-meta { font-family: var(--font-mono); font-size: var(--fs-2xs); color: var(--ink-3); }
.sig-frame { border: 1px solid var(--line); border-radius: var(--r-md); overflow: hidden; background: var(--paper); }
.sig-frame svg { display: block; width: 100%; height: auto; }
.sig-vs {
  justify-self: center; width: 42px; height: 42px; display: grid; place-items: center;
  background: var(--surface); border: 1px solid var(--line-strong); border-radius: var(--r-full);
  box-shadow: var(--e-1);
  font-family: var(--font-head); font-size: var(--fs-2xs); font-weight: 700;
  letter-spacing: var(--tr-wide); color: var(--ink-3);
}
@media (max-width: 1023px) {
  .sig-pair { grid-template-columns: minmax(0, 1fr); gap: var(--sp-4); }
  .sig-vs { width: 34px; height: 34px; }
}

/* overlay: the two specimens tinted apart and multiplied together */
.sig-overlay { display: grid; border: 1px solid var(--line); border-radius: var(--r-md); overflow: hidden; background: var(--paper); }
.sig-layer { grid-area: 1 / 1; --paper: transparent; }
.sig-layer svg { display: block; width: 100%; height: auto; }
.sig-layer--ref { --paper-hand: var(--brand); }
.sig-layer--chq { --paper-hand: var(--st-invalid); mix-blend-mode: multiply; }
.sig-overlay-controls {
  display: flex; align-items: center; gap: var(--sp-3); flex-wrap: wrap;
  margin-top: var(--sp-3); font-size: var(--fs-xs); color: var(--ink-3);
}
.sig-key { display: inline-flex; align-items: center; gap: var(--sp-2); }
.sig-key i { width: 14px; height: 3px; border-radius: 2px; flex: none; }

.range { -webkit-appearance: none; appearance: none; height: 4px; flex: 1 1 140px; min-width: 120px;
  background: var(--canvas-sunken); border-radius: var(--r-xs); cursor: pointer; }
/* a slider is keyboard-operable, so it must show focus — the default outline is
   suppressed only where a ring replaces it */
.range:focus { outline: none; }
.range:focus-visible { outline: 2px solid var(--focus-ring); outline-offset: 3px; }
.range:focus-visible::-webkit-slider-thumb { box-shadow: 0 0 0 3px var(--brand-tint-2), var(--e-1); }
.range::-webkit-slider-thumb { -webkit-appearance: none; appearance: none; width: 15px; height: 15px;
  border-radius: var(--r-full); background: var(--brand); border: 2px solid var(--surface); box-shadow: var(--e-1); cursor: grab; }
.range::-moz-range-thumb { width: 15px; height: 15px; border: 2px solid var(--surface);
  border-radius: var(--r-full); background: var(--brand); box-shadow: var(--e-1); cursor: grab; }

/* the "we are not claiming certainty" note — responsible, not legalistic */
.probabilistic {
  display: flex; align-items: flex-start; gap: var(--sp-3);
  padding: var(--sp-3) var(--sp-4);
  background: var(--surface-2); border: 1px solid var(--line);
  border-inline-start: 1px solid var(--line); border-radius: var(--r-md);
  font-size: var(--fs-xs); color: var(--ink-2); line-height: 1.5;
}
.probabilistic svg { width: 16px; height: 16px; flex: none; margin-top: 1px; color: var(--ink-3); }
.probabilistic strong { color: var(--ink); font-weight: 600; }

/* score summary strip */
.score-grid { display: grid; gap: var(--sp-4); grid-template-columns: repeat(auto-fit, minmax(186px, 1fr)); }
.score-cell { padding: var(--sp-4); background: var(--surface-2); border: 1px solid var(--line); border-radius: var(--r-md); }
.score-cell .score-label { font-size: var(--fs-xs); color: var(--ink-3); }
.score-cell .score-value { font-family: var(--font-mono); font-size: var(--fs-num-sm); font-weight: 600;
  font-variant-numeric: tabular-nums; letter-spacing: -0.02em; margin-top: 4px; }
.score-cell .score-sub { font-size: var(--fs-2xs); color: var(--ink-3); margin-top: 4px; }

/* a specimen lifted from a poor cheque image, shown as it actually is */
.sig-frame.is-degraded svg, .sig-layer.is-degraded svg { filter: blur(1.1px) opacity(.62); }
.sig-frame.is-absent {
  display: grid; place-items: center; gap: var(--sp-2); min-height: 132px; padding: var(--sp-5);
  background: var(--surface-2); border-style: dashed; text-align: center;
}
.sig-frame.is-absent .absent-mark { width: 30px; height: 30px; display: grid; place-items: center;
  border-radius: var(--r-md); background: var(--st-unusable-bg); color: var(--st-unusable); }
.sig-frame.is-absent .absent-mark svg { width: 16px; height: 16px; }
.sig-frame.is-absent p { font-size: var(--fs-xs); color: var(--ink-3); max-width: 34ch; }

/* ══ 33. REVIEW WORKBENCH — Phase 7 ══════════════════════════════════════
   The densest screen in the product. It earns its density with hierarchy:
   evidence pinned left, findings scrollable right, decision always reachable. */
.wb { display: grid; gap: var(--sp-5); grid-template-columns: minmax(0, 1.02fr) minmax(0, 1fr); align-items: start; }
.wb-evidence { position: sticky; top: calc(var(--topbar-h) + var(--sp-4)); }
.wb-detail { display: grid; gap: var(--sp-4); min-width: 0; }
@media (max-width: 1279px) {
  .wb { grid-template-columns: minmax(0, 1fr); }
  .wb-evidence { position: static; }
}

/* section shells in the detail column — collapsed sections must still say
   whether they hold a problem, or collapsing them hides the finding */
.wb-sec { background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-lg); box-shadow: var(--e-1); overflow: hidden; min-width: 0; }
.wb-sec.has-issue { border-color: var(--st-review-line); }
.wb-sec.has-fail  { border-color: var(--st-invalid-line); }
.wb-sec-head {
  display: flex; align-items: center; gap: var(--sp-3); width: 100%; text-align: start;
  padding: var(--sp-3) var(--sp-5);
  border-inline-start: 3px solid transparent;
  transition: background var(--motion-micro);
}
.wb-sec-head:hover { background: var(--surface-2); }
.wb-sec.has-issue .wb-sec-head { background: color-mix(in srgb, var(--st-review-bg) 30%, var(--surface)); }
.wb-sec.has-fail  .wb-sec-head { background: color-mix(in srgb, var(--st-invalid-bg) 30%, var(--surface)); }
.wb-sec-head h3 { font-size: var(--fs-md); flex: 1; min-width: 0; }
.wb-sec-head .wb-chev {
  width: 0; height: 0; flex: none;
  border-top: 4.5px solid transparent; border-bottom: 4.5px solid transparent; border-left: 6.5px solid var(--ink-4);
  transition: transform var(--motion-micro);
}
.wb-sec.is-open .wb-chev { transform: rotate(90deg); }
.wb-sec-body { display: grid; grid-template-rows: 0fr; transition: grid-template-rows var(--motion-standard); }
.wb-sec.is-open .wb-sec-body { grid-template-rows: 1fr; }
.wb-sec-body > div { overflow: hidden; min-height: 0; }
.wb-sec-inner { padding: var(--sp-4) var(--sp-5) var(--sp-5); border-top: 1px solid var(--line); }
.wb-sec-inner.tight { padding: 0; }

/* decision panel — sticky right-edge at desktop, bottom sheet on a phone */
.decision-panel {
  position: sticky; bottom: var(--sp-4); z-index: var(--z-sticky);
  background: var(--surface); border: 1px solid var(--line-strong);
  border-radius: var(--r-xl); box-shadow: var(--e-3); overflow: hidden;
}
.decision-panel-head {
  display: flex; align-items: center; justify-content: space-between; gap: var(--sp-3); flex-wrap: wrap;
  padding: var(--sp-3) var(--sp-5); background: var(--surface-2); border-bottom: 1px solid var(--line);
}
.decision-panel-head h3 { font-size: var(--fs-sm); }
.decision-panel-body { padding: var(--sp-4) var(--sp-5); }
.decision-choice { display: grid; gap: var(--sp-2); grid-template-columns: repeat(3, minmax(0, 1fr)); }
.decision-opt {
  display: flex; flex-direction: column; align-items: flex-start; gap: 3px;
  padding: var(--sp-3) var(--sp-4); text-align: start;
  background: var(--surface); border: 1px solid var(--line-strong); border-radius: var(--r-md);
  transition: border-color var(--motion-micro), background var(--motion-micro), box-shadow var(--motion-micro);
}
.decision-opt:hover { border-color: var(--ink-4); }
.decision-opt .opt-name { font-size: var(--fs-sm); font-weight: 600; }
.decision-opt .opt-sub { font-size: var(--fs-2xs); color: var(--ink-3); }
.decision-opt[aria-pressed="true"] { box-shadow: 0 0 0 2px currentColor inset; }
.decision-opt--approve[aria-pressed="true"] { border-color: var(--st-valid);   background: var(--st-valid-bg);   color: var(--st-valid-ink); }
.decision-opt--reject[aria-pressed="true"]  { border-color: var(--st-invalid); background: var(--st-invalid-bg); color: var(--st-invalid-ink); }
.decision-opt--escalate[aria-pressed="true"]{ border-color: var(--st-hold);    background: var(--st-hold-bg);    color: var(--st-hold-ink); }
.decision-foot {
  display: flex; align-items: center; justify-content: space-between; gap: var(--sp-3); flex-wrap: wrap;
  padding: var(--sp-3) var(--sp-5); border-top: 1px solid var(--line); background: var(--surface-2);
}
.maker-note { display: flex; align-items: center; gap: var(--sp-2); font-size: var(--fs-xs); color: var(--ink-3); }
@media (max-width: 767px) {
  .decision-choice { grid-template-columns: minmax(0, 1fr); }
  .decision-panel {
    position: fixed; inset-inline-start: 0; inset-inline-end: 0; bottom: 0; border-radius: var(--r-xl) var(--r-xl) 0 0;
    border-inline-start: 0; border-inline-end: 0; border-bottom: 0; max-height: 78vh; overflow-y: auto;
  }
  .decision-panel.is-collapsed .decision-panel-body, .decision-panel.is-collapsed .decision-foot { display: none; }
  .wb-sheet-spacer { height: 96px; }
}
@media (min-width: 768px) { .wb-sheet-spacer { display: none; } }

/* ══ 34. MAKER DECISION CARD — Phase 7 ═══════════════════════════════════ */
.maker-card {
  border: 1px solid var(--line-strong); border-inline-start: 1px solid var(--line);
  border-radius: var(--r-lg); background: var(--surface); box-shadow: var(--e-1); overflow: hidden;
  animation: fq-decision var(--motion-emphasis) var(--ease-entry) both;
}
.maker-card--approve { }
.maker-card--reject  { }
.maker-card--escalate{ }
.maker-card-head {
  display: flex; align-items: flex-start; gap: var(--sp-4); flex-wrap: wrap;
  padding: var(--sp-5); background: var(--surface-2); border-bottom: 1px solid var(--line);
}
.maker-card-head .maker-who { display: flex; align-items: center; gap: var(--sp-3); }
.maker-card-head .maker-name { font-size: var(--fs-md); font-weight: 600; }
.maker-card-head .maker-when { font-family: var(--font-mono); font-size: var(--fs-2xs); color: var(--ink-3); }
.maker-card-head .maker-decision { margin-inline-start: auto; }
.maker-rationale {
  padding: var(--sp-5); font-size: var(--fs-md); line-height: 1.55; color: var(--ink);
  border-inline-start: 3px solid var(--line-strong); margin: var(--sp-5); background: var(--surface-2);
  border-radius: 0 var(--r-md) var(--r-md) 0;
}
.maker-rationale::before { content: '“'; font-family: var(--font-head); font-size: var(--fs-3xl); line-height: 0;
  color: var(--ink-3); margin-inline-end: 4px; vertical-align: -8px; }
.maker-rationale::after { content: '”'; font-family: var(--font-head); font-size: var(--fs-3xl); line-height: 0;
  color: var(--ink-3); margin-inline-start: 2px; vertical-align: -8px; }

/* ══ 35. SEGREGATION-OF-DUTIES BLOCK — Phase 7 ═══════════════════════════
   A routine control working correctly, not a mistake by the user. Neutral
   and informative — never a red error state.                              */
.sod-block {
  display: flex; align-items: flex-start; gap: var(--sp-4);
  padding: var(--sp-5);
  background: var(--st-processing-bg); border: 1px solid var(--st-processing-line);
  border-inline-start: 1px solid var(--line); border-radius: var(--r-lg);
  color: var(--st-processing-ink);
  animation: fq-settle var(--motion-standard) var(--ease-out) both;
}
.sod-block .sod-mark { width: 40px; height: 40px; flex: none; display: grid; place-items: center;
  background: var(--surface); border: 1px solid var(--st-processing-line); border-radius: var(--r-md); }
.sod-block .sod-mark svg { width: 20px; height: 20px; }
.sod-block h3 { font-size: var(--fs-lg); color: var(--st-processing-ink); }
.sod-block p { font-size: var(--fs-sm); margin-top: 6px; max-width: 76ch; }
.sod-block .sod-identity {
  display: flex; gap: var(--sp-4); flex-wrap: wrap; margin-top: var(--sp-4);
  padding-top: var(--sp-3); border-top: 1px solid var(--st-processing-line);
  font-size: var(--fs-xs);
}

/* SLA ageing — existing status tokens only, no new colour */
.age { font-family: var(--font-mono); font-variant-numeric: tabular-nums; white-space: nowrap; }
.age--ok     { color: var(--ink-2); }
.age--warn   { color: var(--st-review-ink);  font-weight: 600; }
.age--breach { color: var(--st-invalid-ink); font-weight: 600; }
.age-bar { height: 3px; border-radius: var(--r-xs); background: var(--canvas-sunken); margin-top: 4px; overflow: hidden; }
.age-bar i { display: block; height: 100%; border-radius: var(--r-xs); }
.age--ok     .age-bar i { background: var(--st-pending); }
.age--warn   .age-bar i { background: var(--st-review); }
.age--breach .age-bar i { background: var(--st-invalid); }

/* the reasons are the scan value of a review queue, but they are a signal, not
   a paragraph — two chips and a count, never a wrapping block */
.reason-chips { display: flex; gap: 5px; flex-wrap: wrap; max-width: 340px; }

/* viewer: stacked control group + the enhanced/original pre-processing toggle */
.viewer-controls { display: flex; flex-direction: column; gap: 6px; align-items: flex-start; }
.viewer-canvas.is-enhanced { filter: contrast(1.16) saturate(.92) brightness(1.02) drop-shadow(0 6px 18px rgba(17, 26, 36, .18)); }

/* condensed signature module for the workbench */
.sig-mini { display: grid; grid-template-columns: minmax(0, 1fr) 34px minmax(0, 1fr); gap: var(--sp-2); align-items: center; }
.sig-mini .sig-frame svg { max-height: 88px; }
.sig-mini .sig-vs { width: 30px; height: 30px; font-size: var(--fs-3xs); }
@media (max-width: 599px) { .sig-mini { grid-template-columns: minmax(0, 1fr); } }
.sig-mini-scores { display: flex; gap: var(--sp-4); flex-wrap: wrap; margin-top: var(--sp-3); }
.sig-mini-score { display: flex; flex-direction: column; gap: 2px; }
.sig-mini-score .m-label { font-size: var(--fs-2xs); color: var(--ink-3); }
.sig-mini-score .m-value { font-family: var(--font-mono); font-size: var(--fs-md); font-weight: 600; font-variant-numeric: tabular-nums; }
.chk-passed-note { padding: var(--sp-3) var(--sp-5); font-size: var(--fs-xs); color: var(--ink-3);
  display: flex; align-items: center; gap: var(--sp-2); }
.chk-passed-note .chk-dot { background: var(--st-valid); }

/* ══ 36. NOTIFICATION ITEM — Phase 9 ═════════════════════════════════════
   ONE component. It powers the Notification Center feed and the topbar bell
   preview — the bell was hard-coded in Phase 1 and has been rebuilt on this. */
.notif {
  position: relative; display: grid; grid-template-columns: 32px minmax(0, 1fr) auto;
  gap: var(--sp-3); align-items: start; width: 100%; text-align: start;
  padding: var(--sp-3) var(--sp-4) var(--sp-3) var(--sp-5);
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-md);
  transition: background var(--motion-micro), border-color var(--motion-micro), opacity var(--motion-standard);
  animation: fq-settle var(--motion-standard) var(--ease-out) both;
}
.notif + .notif { margin-top: var(--sp-2); }
.notif:hover { border-color: var(--line-strong); background: var(--surface-2); }
/* unread: a quiet accent bar, not a shout — the read transition fades it out */
.notif::before {
  content: ''; position: absolute; inset-inline-start: 0; top: 10px; bottom: 10px; width: 3px;
  border-radius: 0 var(--r-xs) var(--r-xs) 0; background: var(--brand);
  opacity: 0; transition: opacity var(--motion-standard);
}
.notif.is-unread::before { opacity: 1; }
.notif.is-unread .notif-title { font-weight: 600; }
.notif.is-read { background: var(--surface-2); }
.notif.is-read .notif-title { color: var(--ink-2); }
.notif.is-resolved { opacity: .62; }
.notif.is-resolved .notif-title { text-decoration: line-through; text-decoration-color: var(--line-strong); }

.notif-mark { width: 32px; height: 32px; display: grid; place-items: center; border-radius: var(--r-md); border: 1px solid; }
.notif-mark svg { width: 16px; height: 16px; }
.notif-mark--valid      { background: var(--st-valid-bg);      border-color: var(--st-valid-line);      color: var(--st-valid); }
.notif-mark--review     { background: var(--st-review-bg);     border-color: var(--st-review-line);     color: var(--st-review); }
.notif-mark--invalid    { background: var(--st-invalid-bg);    border-color: var(--st-invalid-line);    color: var(--st-invalid); }
.notif-mark--processing { background: var(--st-processing-bg); border-color: var(--st-processing-line); color: var(--st-processing); }
.notif-mark--hold       { background: var(--st-hold-bg);       border-color: var(--st-hold-line);       color: var(--st-hold); }
.notif-mark--pending    { background: var(--st-pending-bg);    border-color: var(--st-pending-line);    color: var(--st-pending); }

.notif-title { font-size: var(--fs-sm); color: var(--ink); line-height: 1.4; }
.notif-body  { font-size: var(--fs-xs); color: var(--ink-3); margin-top: 3px; line-height: 1.45; }
.notif-meta  { display: flex; align-items: center; gap: var(--sp-2); flex-wrap: wrap; margin-top: var(--sp-2); }
.notif-time  { font-family: var(--font-mono); font-size: var(--fs-2xs); color: var(--ink-3); white-space: nowrap; }
.notif-side  { display: flex; flex-direction: column; align-items: flex-end; gap: var(--sp-2); }

/* compact variant for the topbar bell */
.notif--compact { padding: var(--sp-2) var(--sp-3) var(--sp-2) var(--sp-4); border: 0; border-radius: var(--r-md); background: transparent; }
.notif--compact + .notif--compact { margin-top: 0; }
.notif--compact:hover { background: var(--surface-2); border-color: transparent; }
.notif--compact .notif-mark { width: 26px; height: 26px; }
.notif--compact .notif-mark svg { width: 14px; height: 14px; }
.notif--compact { grid-template-columns: 26px minmax(0, 1fr); }
.notif--compact .notif-side { display: none; }
.notif--compact .notif-body { display: none; }

.notif-group { margin-bottom: var(--sp-5); }
.notif-group-head {
  display: flex; align-items: baseline; justify-content: space-between; gap: var(--sp-3);
  margin-bottom: var(--sp-3); padding-bottom: var(--sp-2); border-bottom: 1px solid var(--line);
}
.notif-group-head h3 {
  font-family: var(--font-head); font-size: var(--fs-2xs); font-weight: 600;
  letter-spacing: var(--tr-wide); text-transform: uppercase; color: var(--ink-3);
}
.notif-group-head .notif-group-count { font-size: var(--fs-xs); color: var(--ink-3); }

/* ══ 37. AUDIT TRAIL — Phase 9 ═══════════════════════════════════════════
   Deliberately denser than the reference screens: completeness and precision
   over airy spacing. Evidentiary, unembellished, read-only.               */
.dt.is-dense th { padding: var(--sp-2) var(--sp-3); }
.dt.is-dense td { padding: 7px var(--sp-3); font-size: var(--fs-dense); }
.dt.is-dense tbody tr.audit-row { cursor: pointer; }
.dt.is-dense .audit-hash { font-family: var(--font-mono); font-size: var(--fs-2xs); color: var(--ink-3); }
.dt.is-dense tr.audit-detail-row > td { padding: 0; border-bottom: 1px solid var(--line); }
.audit-detail { display: grid; grid-template-rows: 0fr; transition: grid-template-rows var(--motion-standard); }
.audit-detail.is-open { grid-template-rows: 1fr; }
.audit-detail > div { overflow: hidden; min-height: 0; }
.audit-detail-inner { padding: var(--sp-4) var(--sp-5); background: var(--surface-2); border-inline-start: 3px solid var(--line-strong); }
.audit-detail-inner .diff-row { padding: var(--sp-2) 0; }
.audit-chain {
  display: flex; align-items: center; gap: var(--sp-2); margin-top: var(--sp-4);
  padding-top: var(--sp-3); border-top: 1px solid var(--line);
  font-family: var(--font-mono); font-size: var(--fs-2xs); color: var(--ink-3); flex-wrap: wrap;
}
.audit-chain .chain-link { color: var(--ink-3); }
.tamper-badge {
  display: inline-flex; align-items: center; gap: var(--sp-2);
  padding: var(--sp-2) var(--sp-3);
  background: var(--st-valid-bg); border: 1px solid var(--st-valid-line);
  border-radius: var(--r-md); font-size: var(--fs-xs); color: var(--st-valid-ink);
}
.tamper-badge svg { width: 14px; height: 14px; }
.readonly-rail {
  display: flex; align-items: center; gap: var(--sp-3);
  padding: var(--sp-3) var(--sp-4);
  background: var(--surface-2); border: 1px solid var(--line);
  border-inline-start: 1px solid var(--line); border-radius: var(--r-md);
  font-size: var(--fs-xs); color: var(--ink-3);
}
.readonly-rail svg { width: 15px; height: 15px; flex: none; color: var(--ink-4); }

/* ══ 38. REPORT CATALOG — Phase 9 ════════════════════════════════════════ */
.report-card {
  display: flex; flex-direction: column; gap: var(--sp-2); width: 100%; text-align: start;
  padding: var(--sp-5); background: var(--surface);
  border: 1px solid var(--line); border-radius: var(--r-lg);
  box-shadow: var(--e-1);
  transition: border-color var(--motion-micro), box-shadow var(--motion-micro), transform var(--motion-micro);
}
.report-card:hover { border-color: var(--line-strong); box-shadow: var(--e-2); transform: translateY(-1px); }
.report-card[aria-pressed="true"] { border-color: var(--brand-tint-2); background: var(--brand-tint); }
.report-card h3 { font-size: var(--fs-md); }
.report-card p { font-size: var(--fs-xs); color: var(--ink-3); line-height: 1.45; }
.report-card .report-meta { display: flex; gap: var(--sp-3); flex-wrap: wrap; margin-top: auto; padding-top: var(--sp-2);
  font-family: var(--font-mono); font-size: var(--fs-2xs); color: var(--ink-3); }

/* ══ 39. ANALYTICS PICKER — Phase 9 ══════════════════════════════════════
   A clearly-labelled control group, never a query builder.                */
.picker { display: grid; gap: var(--sp-4); grid-template-columns: repeat(auto-fit, minmax(230px, 1fr)); align-items: end; }
.picker-field { display: flex; flex-direction: column; gap: var(--sp-2); min-width: 0; }
.picker-label {
  font-family: var(--font-head); font-size: var(--fs-2xs); font-weight: 600;
  letter-spacing: var(--tr-wide); text-transform: uppercase; color: var(--ink-3);
}
.picker-sentence {
  font-size: var(--fs-md); color: var(--ink-2); line-height: 1.7;
}
.picker-sentence strong { color: var(--ink); font-weight: 600; }
.sparse-state {
  display: flex; flex-direction: column; align-items: center; gap: var(--sp-3);
  padding: var(--sp-9) var(--sp-5); text-align: center;
  background: var(--surface-2); border: 1px dashed var(--st-processing-line); border-radius: var(--r-lg);
}
.sparse-state .sparse-mark { width: 40px; height: 40px; display: grid; place-items: center;
  background: var(--st-processing-bg); border: 1px solid var(--st-processing-line);
  border-radius: var(--r-md); color: var(--st-processing); }
.sparse-state .sparse-mark svg { width: 20px; height: 20px; }
.sparse-state h4 { font-size: var(--fs-lg); }
.sparse-state p { font-size: var(--fs-sm); color: var(--ink-3); max-width: 48ch; }

/* ══ 40. CONFIGURATION SCREEN TEMPLATE — Phase 10 ════════════════════════
   One shell for every configuration screen: header, sections, version
   history, pending-approval banner, sticky unsaved-changes bar.           */
.cfg-section + .cfg-section { margin-top: var(--sp-4); }
.cfg-section-head {
  display: flex; align-items: baseline; justify-content: space-between; gap: var(--sp-4); flex-wrap: wrap;
  padding: var(--sp-4) var(--sp-5); border-bottom: 1px solid var(--line);
}
.cfg-section-head h3 { font-size: var(--fs-md); }
.cfg-section-head p { font-size: var(--fs-xs); color: var(--ink-3); margin-top: 4px; max-width: 76ch; }

.unsaved-bar {
  position: sticky; bottom: var(--sp-4); z-index: var(--z-sticky);
  display: flex; align-items: center; gap: var(--sp-4); flex-wrap: wrap;
  margin-top: var(--sp-5); padding: var(--sp-3) var(--sp-5);
  background: var(--surface); border: 1px solid var(--st-review-line);
  border-inline-start: 1px solid var(--line); border-radius: var(--r-xl); box-shadow: var(--e-3);
  animation: fq-settle var(--motion-standard) var(--ease-out) both;
}
.unsaved-bar .unsaved-what { font-size: var(--fs-sm); color: var(--st-review-ink); }
.unsaved-bar .unsaved-what strong { font-weight: 600; }
.unsaved-bar .unsaved-actions { margin-inline-start: auto; display: flex; gap: var(--sp-2); flex-wrap: wrap; }
@media (max-width: 599px) {
  .unsaved-bar { position: fixed; inset-inline-start: var(--sp-3); inset-inline-end: var(--sp-3); bottom: var(--sp-3); }
  .unsaved-bar .unsaved-actions { margin-inline-start: 0; width: 100%; }
  .unsaved-bar .unsaved-actions .btn { flex: 1; }
}

/* ══ 41. THRESHOLD ZONE BAND — Phase 10 ══════════════════════════════════
   The point of this control is the CONSEQUENCE, not the number: the band
   shows the three outcomes a cheque can land in, sized live as you drag.  */
.thzone { display: grid; gap: var(--sp-3); }
.thzone-head { display: flex; align-items: baseline; justify-content: space-between; gap: var(--sp-3); flex-wrap: wrap; }
.thzone-head h4 { font-size: var(--fs-sm); }
.thzone-head .thzone-sub { font-size: var(--fs-xs); color: var(--ink-3); }
.thzone-band {
  display: flex; height: 42px; border-radius: var(--r-md); overflow: hidden;
  border: 1px solid var(--line); box-shadow: var(--e-inset);
}
.thzone-seg {
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 1px;
  min-width: 0; overflow: hidden; padding: 0 var(--sp-1);
  transition: flex-basis var(--motion-micro);
  font-family: var(--font-head); font-size: var(--fs-2xs); font-weight: 600;
  letter-spacing: var(--tr-wide); text-transform: uppercase; text-align: center;
}
.thzone-seg .seg-pct { font-family: var(--font-mono); font-size: var(--fs-micro); font-weight: 500; opacity: .78; letter-spacing: 0; text-transform: none; }
.thzone-seg--reject { background: var(--st-invalid-bg); color: var(--st-invalid-ink); }
.thzone-seg--review { background: var(--st-review-bg);  color: var(--st-review-ink); }
.thzone-seg--accept { background: var(--st-valid-bg);   color: var(--st-valid-ink); }
.thzone-scale { display: flex; justify-content: space-between; font-family: var(--font-mono); font-size: var(--fs-micro); color: var(--ink-3); }
.thzone-boundaries { display: flex; gap: var(--sp-4); flex-wrap: wrap; font-size: var(--fs-xs); }
.thzone-boundaries b { font-family: var(--font-mono); font-variant-numeric: tabular-nums; }
.thzone-ctrl { display: grid; grid-template-columns: 190px minmax(0, 1fr) 88px; gap: var(--sp-3); align-items: center; }
.thzone-ctrl label { font-size: var(--fs-xs); color: var(--ink-2); }
.thzone-ctrl .input { height: 32px; text-align: end; font-family: var(--font-mono); }
@media (max-width: 767px) {
  .thzone-ctrl { grid-template-columns: minmax(0, 1fr) 88px; }
  .thzone-ctrl label { grid-column: 1 / -1; }
}
.thzone-impact {
  display: flex; align-items: flex-start; gap: var(--sp-3);
  padding: var(--sp-3) var(--sp-4);
  background: var(--surface-2); border: 1px solid var(--line);
  border-inline-start: 1px solid var(--line); border-radius: var(--r-md);
  font-size: var(--fs-xs); color: var(--ink-2); line-height: 1.5;
}
.thzone-impact svg { width: 15px; height: 15px; flex: none; margin-top: 1px; color: var(--ink-4); }
.thzone-impact .impact-num { font-family: var(--font-mono); font-weight: 600; color: var(--ink); }
.thzone.is-dirty .thzone-band { box-shadow: 0 0 0 2px var(--st-review-line), var(--e-inset); }

/* ══ 42. PERMISSION MATRIX — Phase 10 ════════════════════════════════════ */
.perm-layout { display: grid; gap: var(--sp-5); grid-template-columns: 268px minmax(0, 1fr); align-items: start; }
@media (max-width: 1023px) { .perm-layout { grid-template-columns: minmax(0, 1fr); } }
.role-list { display: grid; gap: var(--sp-2); }
.role-item {
  display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: var(--sp-2); align-items: center;
  width: 100%; text-align: start; padding: var(--sp-3) var(--sp-4);
  background: var(--surface); border: 1px solid var(--line);
  border-inline-start: 3px solid transparent; border-radius: var(--r-md);
  transition: border-color var(--motion-micro), background var(--motion-micro);
}
.role-item:hover { border-color: var(--line-strong); }
.role-item[aria-pressed="true"] { background: var(--brand-tint); border-color: var(--brand-tint-2); }
.role-item .role-name { font-size: var(--fs-sm); font-weight: 500; color: var(--ink); }
.role-item .role-cite { font-family: var(--font-mono); font-size: var(--fs-2xs); color: var(--ink-3); }
.perm-group-head td {
  background: var(--surface-2) !important; font-family: var(--font-head); font-size: var(--fs-2xs);
  font-weight: 600; letter-spacing: var(--tr-wide); text-transform: uppercase; color: var(--ink-3);
}
.perm-cell { text-align: center; width: 84px; }
.perm-cell input { width: 16px; height: 16px; accent-color: var(--brand); cursor: pointer; }
.perm-cell input:disabled { cursor: not-allowed; opacity: .4; }
.perm-row.is-changed td { background: color-mix(in srgb, var(--st-review-bg) 40%, var(--surface)); }

/* ══ 43. TREE NAVIGATOR — Phase 10 ═══════════════════════════════════════ */
.tree { display: grid; gap: 2px; }
.tree-node {
  display: grid; grid-template-columns: 16px minmax(0, 1fr) auto; gap: var(--sp-2); align-items: center;
  width: 100%; text-align: start; padding: var(--sp-2) var(--sp-3); border-radius: var(--r-md);
  font-size: var(--fs-sm); color: var(--ink-2);
  transition: background var(--motion-micro), color var(--motion-micro);
}
.tree-node:hover { background: var(--surface-2); color: var(--ink); }
.tree-node[aria-current="true"] { background: var(--brand-tint); color: var(--brand); font-weight: 500; }
.tree-node.is-child { padding-inline-start: var(--sp-6); }
.tree-node .tree-chev { width: 0; height: 0; border-top: 4px solid transparent; border-bottom: 4px solid transparent;
  border-left: 5.5px solid var(--ink-4); transition: transform var(--motion-micro); justify-self: center; }
.tree-node.is-open .tree-chev { transform: rotate(90deg); }
.tree-node .tree-count { font-family: var(--font-mono); font-size: var(--fs-2xs); color: var(--ink-3); }

/* ══ 44. ZONE-OVERLAY EDITOR — Phase 10 ══════════════════════════════════ */
.zed { position: relative; border: 1px solid var(--line); border-radius: var(--r-lg); overflow: hidden; background: var(--canvas-sunken); }
.zed-canvas { position: relative; }
.zed-canvas svg { display: block; width: 100%; height: auto; }
.zone {
  position: absolute; border: 2px solid; border-radius: 3px;
  cursor: move; touch-action: none;
  transition: box-shadow var(--motion-micro), background var(--motion-micro);
}
.zone .zone-tag {
  position: absolute; top: -1px; inset-inline-start: -1px; transform: translateY(-100%);
  padding: 1px 5px; border-radius: 3px 3px 0 0; white-space: nowrap;
  font-family: var(--font-head); font-size: var(--fs-3xs); font-weight: 600;
  letter-spacing: .04em; text-transform: uppercase; color: #fff;
}
.zone.is-selected { box-shadow: 0 0 0 3px var(--brand-tint-2); z-index: 2; }
.zone .zone-handle {
  position: absolute; inset-inline-end: -5px; bottom: -5px; width: 11px; height: 11px;
  background: var(--surface); border: 2px solid currentColor; border-radius: 2px; cursor: nwse-resize;
}
.zone--micr      { border-color: var(--st-processing); background: color-mix(in srgb, var(--st-processing) 12%, transparent); color: var(--st-processing); }
.zone--micr      .zone-tag { background: var(--st-processing); }
.zone--icr       { border-color: var(--st-review); background: color-mix(in srgb, var(--st-review) 12%, transparent); color: var(--st-review); }
.zone--icr       .zone-tag { background: var(--st-review); }
.zone--ocr       { border-color: var(--st-valid); background: color-mix(in srgb, var(--st-valid) 12%, transparent); color: var(--st-valid); }
.zone--ocr       .zone-tag { background: var(--st-valid); }
.zone--cv        { border-color: var(--st-hold); background: color-mix(in srgb, var(--st-hold) 12%, transparent); color: var(--st-hold); }
.zone--cv        .zone-tag { background: var(--st-hold); }

.zed-fallback-note {
  display: flex; align-items: flex-start; gap: var(--sp-3); padding: var(--sp-4);
  background: var(--st-processing-bg); border: 1px solid var(--st-processing-line);
  border-inline-start: 1px solid var(--line); border-radius: var(--r-md);
  font-size: var(--fs-sm); color: var(--st-processing-ink);
}
.zed-fallback-note svg { width: 17px; height: 17px; flex: none; margin-top: 1px; }
.zone-form-row { display: grid; grid-template-columns: minmax(0, 1fr) repeat(4, 74px); gap: var(--sp-2); align-items: center;
  padding: var(--sp-3) var(--sp-4); background: var(--surface); border: 1px solid var(--line);
  border-inline-start: 3px solid transparent; border-radius: var(--r-md); }
.zone-form-row + .zone-form-row { margin-top: var(--sp-2); }
.zone-form-row .input { height: 30px; text-align: end; font-family: var(--font-mono); font-size: var(--fs-xs); padding: 0 var(--sp-2); }
.zone-form-row--micr { }
.zone-form-row--icr  { }
.zone-form-row--ocr  { }
.zone-form-row--cv   { }
@media (max-width: 767px) {
  .zone-form-row { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .zone-form-row > :first-child { grid-column: 1 / -1; }
}
/* the drag editor is desktop-only; the form editor is the real fallback */
@media (max-width: 1023px) { .zed-drag-only { display: none; } }
@media (min-width: 1024px) { .zed-form-only { display: none; } }

/* ══ 45. WORKFLOW DIAGRAM — Phase 10 ═════════════════════════════════════ */
.wf-canvas { position: relative; padding: var(--sp-5); background: var(--canvas-sunken);
  border: 1px solid var(--line); border-radius: var(--r-lg); overflow-x: auto; }
.wf-grid { position: relative; display: grid; gap: var(--sp-5) var(--sp-7); min-width: 720px; }
.wf-node {
  position: relative; z-index: 1; display: flex; flex-direction: column; align-items: flex-start; gap: 5px;
  padding: var(--sp-3) var(--sp-4); text-align: start;
  background: var(--surface); border: 1px solid var(--line-strong); border-radius: var(--r-md);
  box-shadow: var(--e-1);
  transition: box-shadow var(--motion-micro), border-color var(--motion-micro), transform var(--motion-micro);
}
.wf-node:hover { border-color: var(--brand); transform: translateY(-1px); box-shadow: var(--e-2); }
.wf-node[aria-pressed="true"] { border-color: var(--brand); box-shadow: 0 0 0 3px var(--brand-tint-2), var(--e-2); }
.wf-node .wf-name { font-size: var(--fs-sm); font-weight: 500; }
.wf-node .wf-sla { font-family: var(--font-mono); font-size: var(--fs-2xs); color: var(--ink-3); }
.wf-node.is-custom { border-style: dashed; border-color: var(--st-hold); }
.wf-lines { position: absolute; inset: 0; pointer-events: none; z-index: 0; }
.wf-lines path { fill: none; stroke: var(--line-strong); stroke-width: 1.5; }
.wf-lines .wf-branch { stroke: var(--st-hold); stroke-dasharray: 4 3; }
@media (max-width: 1023px) { .wf-canvas { display: none; } }
@media (min-width: 1024px) { .wf-list-only { display: none; } }

/* ══ 46. MASKED CREDENTIAL — Phase 10 ════════════════════════════════════
   Same deliberate, logged reveal as a reference signature (Phase 5).      */
.cred { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: var(--sp-3); align-items: center;
  padding: var(--sp-3) var(--sp-4); background: var(--surface-2);
  border: 1px solid var(--line); border-radius: var(--r-md); }
.cred-value { font-family: var(--font-mono); font-size: var(--fs-sm); color: var(--ink); letter-spacing: .06em;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cred.is-masked .cred-value { color: var(--ink-3); letter-spacing: .18em; }

/* ══ 47. BULK IMPORT STEPS — Phase 10 ════════════════════════════════════ */
.import-summary { display: grid; gap: var(--sp-3); grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); }
.import-stat { padding: var(--sp-4); background: var(--surface-2); border: 1px solid var(--line);
  border-inline-start: 3px solid var(--line-strong); border-radius: var(--r-md); }
.import-stat .is-label { font-size: var(--fs-xs); color: var(--ink-3); }
.import-stat .is-value { font-family: var(--font-mono); font-size: var(--fs-2xl); font-weight: 600;
  font-variant-numeric: tabular-nums; margin-top: 3px; }
.import-stat--ok   { }
.import-stat--warn { }
.import-stat--bad  { }

/* ══ 48. SERVICE HEALTH GRID — Phase 11 ══════════════════════════════════
   All-healthy is the common state and must read as unremarkable, not
   under-designed: a quiet heartbeat, a metric, and nothing shouting.     */
.svc-grid { display: grid; gap: var(--sp-3); grid-template-columns: repeat(auto-fit, minmax(232px, 1fr)); }
.svc {
  display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: var(--sp-2) var(--sp-3); align-items: center;
  width: 100%; text-align: start; padding: var(--sp-4);
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--r-md);
  transition: border-color var(--motion-micro), box-shadow var(--motion-micro);
}
.svc:hover { box-shadow: var(--e-1); border-color: var(--line-strong); }
.svc--degraded { border-inline-start-color: var(--st-review); background: color-mix(in srgb, var(--st-review-bg) 26%, var(--surface)); }
.svc--down     { border-inline-start-color: var(--st-invalid); background: color-mix(in srgb, var(--st-invalid-bg) 30%, var(--surface)); }
.svc-name { font-size: var(--fs-sm); font-weight: 500; color: var(--ink); }
.svc-metric { grid-column: 1 / -1; display: flex; gap: var(--sp-4); flex-wrap: wrap;
  font-family: var(--font-mono); font-size: var(--fs-2xs); color: var(--ink-3); }
.svc-metric b { color: var(--ink-2); font-weight: 500; }
.svc-detail { grid-column: 1 / -1; display: grid; grid-template-rows: 0fr; transition: grid-template-rows var(--motion-standard); }
.svc.is-open .svc-detail { grid-template-rows: 1fr; }
.svc-detail > div { overflow: hidden; min-height: 0; }
.svc-detail-inner { padding-top: var(--sp-3); margin-top: var(--sp-3); border-top: 1px solid var(--line);
  font-size: var(--fs-xs); color: var(--ink-2); line-height: 1.5; }

/* queue depth — the Phase 1 meter with a capacity notch */
.gauge-row { display: grid; grid-template-columns: 200px minmax(0, 1fr); gap: var(--sp-3); align-items: center; }
.gauge-row + .gauge-row { margin-top: var(--sp-4); }
.gauge-label { font-size: var(--fs-sm); color: var(--ink-2); }
.gauge-label span { display: block; font-family: var(--font-mono); font-size: var(--fs-2xs); color: var(--ink-3); }
@media (max-width: 599px) { .gauge-row { grid-template-columns: minmax(0, 1fr); } }

/* sync freshness */
.fresh-row {
  display: grid; grid-template-columns: minmax(0, 1fr) auto auto; gap: var(--sp-3); align-items: center;
  padding: var(--sp-3) var(--sp-4); background: var(--surface);
  border: 1px solid var(--line); border-radius: var(--r-md);
}
.fresh-row + .fresh-row { margin-top: var(--sp-2); }
.fresh-row--stale { border-inline-start-color: var(--st-review); background: color-mix(in srgb, var(--st-review-bg) 28%, var(--surface)); }
.fresh-name { font-size: var(--fs-sm); color: var(--ink); }
.fresh-name span { display: block; font-size: var(--fs-2xs); color: var(--ink-3); }
.fresh-age { font-family: var(--font-mono); font-size: var(--fs-sm); font-variant-numeric: tabular-nums; color: var(--ink-2); }

/* ══ 49. ALERT / ANOMALY LIST — Phase 11 ═════════════════════════════════
   Entrance is scaled to severity: low fades, high settles in slightly more
   assertively. Never a flash, never a repeat.                            */
.alert-item {
  display: grid; grid-template-columns: 30px minmax(0, 1fr) auto; gap: var(--sp-3); align-items: start;
  padding: var(--sp-4);
  background: var(--surface); border: 1px solid var(--line);
  border-inline-start: 3px solid var(--st-pending); border-radius: var(--r-md);
  animation: fq-settle var(--motion-standard) var(--ease-out) both;
}
.alert-item + .alert-item { margin-top: var(--sp-2); }
.alert-item--high { border-inline-start-color: var(--st-invalid); background: color-mix(in srgb, var(--st-invalid-bg) 28%, var(--surface));
  animation: fq-alert-in var(--motion-emphasis) var(--ease-entry) both; }
.alert-item--medium { border-inline-start-color: var(--st-review); background: color-mix(in srgb, var(--st-review-bg) 26%, var(--surface)); }
.alert-item--low { border-inline-start-color: var(--st-processing); }
@keyframes fq-alert-in { from { opacity: 0; transform: translateY(7px) scale(.995); } to { opacity: 1; transform: none; } }
.alert-item.is-ack { opacity: .62; border-inline-start-color: var(--st-pending); background: var(--surface); }
.alert-item.is-ack .alert-title { text-decoration: line-through; text-decoration-color: var(--line-strong); }
.alert-mark { width: 30px; height: 30px; display: grid; place-items: center; border-radius: var(--r-md); border: 1px solid; }
.alert-mark svg { width: 16px; height: 16px; }
.alert-item--high .alert-mark   { background: var(--st-invalid-bg); border-color: var(--st-invalid-line); color: var(--st-invalid); }
.alert-item--medium .alert-mark { background: var(--st-review-bg);  border-color: var(--st-review-line);  color: var(--st-review); }
.alert-item--low .alert-mark    { background: var(--st-processing-bg); border-color: var(--st-processing-line); color: var(--st-processing); }
.alert-item.is-ack .alert-mark  { background: var(--surface-2); border-color: var(--line); color: var(--ink-4); }
.alert-title { font-size: var(--fs-sm); font-weight: 500; color: var(--ink); }
.alert-body  { font-size: var(--fs-xs); color: var(--ink-3); margin-top: 3px; line-height: 1.45; }
.alert-meta  { display: flex; gap: var(--sp-3); flex-wrap: wrap; margin-top: var(--sp-2);
  font-family: var(--font-mono); font-size: var(--fs-2xs); color: var(--ink-3); }
.alert-side { display: flex; flex-direction: column; align-items: flex-end; gap: var(--sp-2); }
@media (max-width: 599px) {
  .alert-item { grid-template-columns: 30px minmax(0, 1fr); }
  .alert-side { grid-column: 1 / -1; flex-direction: row; align-items: center; }
}

/* ══ 50. AUDIT INTEGRITY CARD — Phase 11 ═════════════════════════════════
   The trust signal underneath every audit claim in the product. Verified is
   calm and settled. Failed is the most serious state in the prototype and
   earns that through colour, mark and copy — never through motion tricks. */
.integrity {
  display: grid; grid-template-columns: 64px minmax(0, 1fr) auto; gap: var(--sp-5); align-items: center;
  min-width: 0;
  padding: var(--sp-6);
  background: var(--surface); border: 1px solid var(--st-valid-line);
  border-inline-start: 1px solid var(--line); border-radius: var(--r-lg); box-shadow: var(--e-1);
}
.integrity-mark {
  width: 64px; height: 64px; display: grid; place-items: center; border-radius: var(--r-lg);
  background: var(--st-valid-bg); border: 1px solid var(--st-valid-line); color: var(--st-valid);
}
.integrity-mark svg { width: 32px; height: 32px; }
.integrity h2 { font-size: var(--fs-xl); color: var(--st-valid-ink); }
.integrity p { font-size: var(--fs-sm); color: var(--ink-2); margin-top: 5px; max-width: 78ch; }
.integrity-meta { display: flex; gap: var(--sp-4); flex-wrap: wrap; margin-top: var(--sp-3);
  font-family: var(--font-mono); font-size: var(--fs-2xs); color: var(--ink-3); }
.integrity-side { display: flex; flex-direction: column; align-items: flex-end; gap: var(--sp-2); }

.integrity--failed {
  border-color: var(--st-invalid);
  background: color-mix(in srgb, var(--st-invalid-bg) 40%, var(--surface));
  box-shadow: var(--e-2);
}
.integrity--failed .integrity-mark { background: var(--st-invalid); border-color: var(--st-invalid); color: #fff; }
@media (max-width: 599px) {
  /* three columns do not fit a phone. The mark stays beside the verdict — that
     pairing is the whole point of the block — and the side column drops under
     them rather than being squeezed to nothing. */
  .integrity { grid-template-columns: 48px minmax(0, 1fr); gap: var(--sp-4); padding: var(--sp-5); }
  .integrity-side { grid-column: 1 / -1; align-items: flex-start; }
  .integrity-mark { width: 48px; height: 48px; }
  .integrity-mark svg { width: 24px; height: 24px; }
}
.integrity--failed h2 { color: var(--st-invalid-ink); font-size: var(--fs-2xl); }
.integrity--failed p { color: var(--st-invalid-ink); }
.integrity-break {
  grid-column: 1 / -1; margin-top: var(--sp-4); padding: var(--sp-4);
  background: var(--surface); border: 1px solid var(--st-invalid-line); border-radius: var(--r-md);
  font-family: var(--font-mono); font-size: var(--fs-xs); color: var(--ink-2);
}
.integrity-break .break-line { display: flex; gap: var(--sp-3); flex-wrap: wrap; padding: 3px 0; }
.integrity-break .break-line.is-broken { color: var(--st-invalid-ink); font-weight: 600; }
@media (max-width: 1023px) {
  .integrity { grid-template-columns: 64px minmax(0, 1fr); }
  .integrity-side { grid-column: 1 / -1; flex-direction: row; align-items: center; }
}
@media (max-width: 599px) {
  .integrity { grid-template-columns: minmax(0, 1fr); padding: var(--sp-5); }
  .integrity-side .btn { flex: 1; }
}

/* monitoring zone ordering — alerts and service health first on a phone */
.mon-zones { display: grid; gap: var(--sp-5); }
@media (max-width: 1023px) {
  .mon-zones > .zone-alerts  { order: 1; }
  .mon-zones > .zone-health  { order: 2; }
  .mon-zones > .zone-through { order: 3; }
  .mon-zones > .zone-integr  { order: 4; }
}

/* ══ 51. QUEUE-STATE BADGE — Phase 8 ═════════════════════════════════════
   Eleven states is too many to tell apart by colour and shape alone, so the
   queue badge EXTENDS the Phase 1 badge rather than replacing it: family
   colour + family glyph as always, plus a six-pip rail showing how far the
   cheque has travelled. Colour says what kind of state; pips say how far.  */
/* The one sanctioned chip modifier: the queue chip carries a six-pip journey
   rail inside its trailing space, so it trims right padding to keep the overall
   box on the same rhythm. Same fill, same 4px radius, same height as every
   other chip — a modifier, not a second construction. */
.qbadge { padding-inline-end: var(--sp-2); }
.q-pips { display: inline-flex; align-items: center; gap: 2px; margin-inline-start: 5px; flex: none; }
.q-pips i {
  width: 4px; height: 4px; border-radius: var(--r-full);
  background: currentColor; opacity: .22;
  transition: opacity var(--motion-micro);
}
.q-pips i.is-done { opacity: .95; }
.q-pips i.is-here { opacity: 1; width: 9px; border-radius: 2px; }
.q-pips i.is-stuck {
  opacity: 1; width: 9px; border-radius: 2px;
  background-image: repeating-linear-gradient(135deg, transparent 0 1px, var(--surface) 1px 2px);
}
.qbadge-lg .q-pips i { width: 5px; height: 5px; }
.qbadge-lg .q-pips i.is-here, .qbadge-lg .q-pips i.is-stuck { width: 11px; }

/* summary strip — counts by sub-family, one click to filter */
.q-summary { display: grid; gap: var(--sp-3); grid-template-columns: repeat(auto-fit, minmax(168px, 1fr)); }
.q-sum {
  display: flex; flex-direction: column; gap: 3px; width: 100%; text-align: start;
  padding: var(--sp-4); background: var(--surface);
  border: 1px solid var(--line); border-inline-start: 1px solid var(--line); border-radius: var(--r-md);
  transition: border-color var(--motion-micro), box-shadow var(--motion-micro), transform var(--motion-micro);
}
.q-sum:hover { box-shadow: var(--e-1); transform: translateY(-1px); }
.q-sum[aria-pressed="true"] { box-shadow: 0 0 0 2px var(--brand-tint-2), var(--e-1); border-color: var(--brand-tint-2); }
.q-sum .q-sum-label { font-size: var(--fs-xs); color: var(--ink-3); display: flex; align-items: center; gap: var(--sp-2); }
.q-sum .q-sum-value { font-family: var(--font-mono); font-size: var(--fs-num-md); font-weight: 600;
  font-variant-numeric: tabular-nums; letter-spacing: -0.02em; }
.q-sum .q-sum-sub { font-size: var(--fs-2xs); color: var(--ink-3); }
.q-sum--waiting  { }
.q-sum--inflight { }
.q-sum--success  { }
.q-sum--failure  { }
.q-sum--held     { }

/* ══ 52. CONNECTION HEALTH — Phase 8 ═════════════════════════════════════ */
.conn {
  display: grid; grid-template-columns: 56px minmax(0, 1fr) auto; gap: var(--sp-5); align-items: center;
  padding: var(--sp-6); background: var(--surface);
  border: 1px solid var(--line); border-inline-start: 1px solid var(--line);
  border-radius: var(--r-lg); box-shadow: var(--e-1);
}
.conn--down { background: color-mix(in srgb, var(--st-hold-bg) 22%, var(--surface)); }
.conn-mark { width: 56px; height: 56px; display: grid; place-items: center; border-radius: var(--r-lg);
  background: var(--st-valid-bg); border: 1px solid var(--st-valid-line); color: var(--st-valid); }
.conn--down .conn-mark { background: var(--st-hold-bg); border-color: var(--st-hold-line); color: var(--st-hold); }
.conn-mark svg { width: 26px; height: 26px; }
.conn h2 { font-size: var(--fs-xl); }
.conn--down h2 { color: var(--st-hold-ink); }
.conn p { font-size: var(--fs-sm); color: var(--ink-3); margin-top: 5px; max-width: 76ch; }
.conn-meta { display: flex; gap: var(--sp-4); flex-wrap: wrap; margin-top: var(--sp-3);
  font-family: var(--font-mono); font-size: var(--fs-2xs); color: var(--ink-3); }
.conn-side { display: flex; flex-direction: column; align-items: flex-end; gap: var(--sp-2); }
@media (max-width: 1023px) {
  .conn { grid-template-columns: 56px minmax(0, 1fr); }
  .conn-side { grid-column: 1 / -1; flex-direction: row; align-items: center; }
}
@media (max-width: 599px) { .conn { grid-template-columns: minmax(0, 1fr); padding: var(--sp-5); } }

/* the holding queue is a supported condition, not a failure */
.holding-note {
  display: flex; align-items: flex-start; gap: var(--sp-3);
  padding: var(--sp-4) var(--sp-5);
  background: var(--st-hold-bg); border: 1px solid var(--st-hold-line);
  border-inline-start: 1px solid var(--line); border-radius: var(--r-md);
  font-size: var(--fs-sm); color: var(--st-hold-ink); line-height: 1.55;
}
.holding-note svg { width: 18px; height: 18px; flex: none; margin-top: 2px; }
.holding-note strong { font-weight: 600; }

/* ══ 53. PAYLOAD / CODE VIEWER — Phase 8 ═════════════════════════════════ */
.code-panel {
  border: 1px solid var(--line); border-radius: var(--r-lg); overflow: hidden;
  background: var(--chrome); box-shadow: var(--e-1);
}
.code-head {
  display: flex; align-items: center; justify-content: space-between; gap: var(--sp-3); flex-wrap: wrap;
  padding: var(--sp-3) var(--sp-4); background: var(--chrome-2); border-bottom: 1px solid var(--line-inverse);
}
.code-head .code-title { font-family: var(--font-head); font-size: var(--fs-2xs); font-weight: 600;
  letter-spacing: var(--tr-wide); text-transform: uppercase; color: var(--chrome-ink-2); }
.code-head .code-meta { font-family: var(--font-mono); font-size: var(--fs-2xs); color: var(--chrome-ink-3); }
.code-body { max-height: 420px; overflow: auto; }
.code-body table { border-collapse: collapse; width: 100%; }
.code-body td { padding: 0; vertical-align: top; }
.code-ln {
  width: 44px; text-align: end; padding: 0 var(--sp-3) 0 var(--sp-4) !important;
  font-family: var(--font-mono); font-size: var(--fs-2xs); line-height: 1.75;
  color: var(--chrome-ink-3); opacity: .55; user-select: none;
  border-inline-end: 1px solid var(--line-inverse); background: color-mix(in srgb, var(--chrome-2) 60%, transparent);
}
.code-src {
  padding: 0 var(--sp-4) !important;
  font-family: var(--font-mono); font-size: var(--fs-xs); line-height: 1.75;
  color: var(--chrome-ink); white-space: pre;
}
.code-body tr:hover .code-src { background: var(--chrome-2); }
.tok-key { color: var(--code-key); }
.tok-str { color: var(--code-str); }
.tok-num { color: var(--code-num); }
.tok-bool{ color: var(--code-bool); }
.tok-null{ color: var(--chrome-ink-3); font-style: italic; }
.tok-pun { color: var(--chrome-ink-3); }
.code-empty {
  display: flex; flex-direction: column; align-items: center; gap: var(--sp-2);
  padding: var(--sp-8) var(--sp-5); text-align: center; color: var(--chrome-ink-2);
}
.code-empty .code-empty-mark { width: 34px; height: 34px; display: grid; place-items: center;
  border-radius: var(--r-md); background: var(--chrome-2); border: 1px solid var(--line-inverse); }
.code-empty .code-empty-mark svg { width: 18px; height: 18px; }
.code-empty p { font-size: var(--fs-xs); color: var(--chrome-ink-3); max-width: 40ch; }

/* ══ 54. EXCEPTION TYPE CHIPS — Phase 8 ══════════════════════════════════ */
.ex-chips { display: flex; gap: var(--sp-2); flex-wrap: wrap; }
.ex-chip {
  display: inline-flex; align-items: center; gap: var(--sp-2);
  height: 34px; padding: 0 var(--sp-4);
  background: var(--surface); color: var(--ink-2);
  border: 1px solid var(--line); border-radius: var(--r-md);
  font-size: var(--fs-sm); white-space: nowrap;
  transition: background var(--motion-micro), border-color var(--motion-micro), color var(--motion-micro);
}
.ex-chip:hover { border-color: var(--line-strong); background: var(--surface-2); }
.ex-chip .ex-count { font-family: var(--font-mono); font-size: var(--fs-2xs); color: var(--ink-3);
  padding: 1px 5px; background: var(--surface-2); border-radius: var(--r-sm); }
.ex-chip[aria-pressed="true"] { background: var(--brand-tint); border-color: var(--brand-tint-2); color: var(--brand); }
.ex-chip[aria-pressed="true"] .ex-count { background: var(--surface); color: var(--brand); }
.ex-chip .ex-dot { width: 8px; height: 8px; border-radius: var(--r-full); flex: none; }

/* retry countdown — ticks without reflowing its neighbours */
.retry-eta { font-family: var(--font-mono); font-variant-numeric: tabular-nums; white-space: nowrap;
  min-width: 5ch; display: inline-block; text-align: end; }

/* ============================================================================
   BIDIRECTIONAL LAYER — Arabic / RTL
   ----------------------------------------------------------------------------
   The stylesheets above were converted to logical properties (margin-inline,
   padding-inline, border-inline-start, inset-inline-*, text-align: start/end),
   so the bulk of the interface mirrors from `dir="rtl"` alone. What remains here
   is everything logical properties cannot reach: transforms that encode a
   direction, icons whose glyph points somewhere, and the artefacts that must
   never mirror no matter what the layout does.
   ========================================================================== */

/* ── 1. Arabic typography ──────────────────────────────────────────────────
   IBM Plex Sans Arabic is the same superfamily as the Latin face already in
   use, so weights, x-height and colour match rather than merely coexist.
   Arabic needs more vertical room at the same size — ascenders and the
   diacritic band clip at Latin line-heights, worst at the 11px table-header
   and caption sizes — so the leading is opened up for the Arabic locale only. */
[lang="ar"] {
  --font-ui:   'IBM Plex Sans Arabic', 'IBM Plex Sans', system-ui, sans-serif;
  --font-head: 'IBM Plex Sans Arabic', 'IBM Plex Sans Condensed', system-ui, sans-serif;
  --lh-3xl: 1.34; --lh-2xl: 1.4;  --lh-xl: 1.45; --lh-lg: 1.5;
  --lh-md:  1.62; --lh-sm:  1.7;  --lh-xs: 1.72; --lh-2xs: 1.66;
  /* Arabic is cursive: letter-spacing breaks joins, so the Latin tracking
     tokens are neutralised rather than inherited */
  --tr-tight: 0; --tr-normal: 0; --tr-wide: 0.02em; --tr-mono: 0;
}
[lang="ar"] .dt thead th,
[lang="ar"] .nav-group-label,
[lang="ar"] .proto-tag { text-transform: none; }   /* Arabic has no letter case */

/* ── 2. Numerals, identifiers and money ────────────────────────────────────
   Deliberate convention: every amount, account number, cheque number, MICR
   string, IBAN and timestamp stays in Western digits and reads left-to-right in
   both languages. A reviewer compares these against the physical cheque, whose
   MICR band is printed in Western digits — switching the UI to Arabic-Indic
   would put the screen and the paper into different scripts on the one field
   where they must match exactly. `.num`, `.id-ref` and the mono family are
   isolated so a Latin identifier inside an Arabic sentence cannot reorder. */
[lang="ar"] .num,
[lang="ar"] .id-ref,
[lang="ar"] .col-num,
[lang="ar"] .kpi-value,
[lang="ar"] .cmp-val,
[lang="ar"] .audit-hash,
[lang="ar"] .code-src {
  direction: ltr; unicode-bidi: isolate; font-variant-numeric: tabular-nums;
}
/* a right-aligned numeric column stays right-aligned in RTL: the decimal must
   keep lining up, which is the whole reason the column is aligned at all */
[dir="rtl"] .dt .col-num { text-align: left; }

/* ── 3. Direction-encoding transforms ──────────────────────────────────────
   Logical properties do not reach `transform`. Each of these has a physical
   direction baked in and needs its mirror image. */
[dir="rtl"] .drawer                    { transform: translateX(-100%); }
[dir="rtl"] .drawer.is-open            { transform: none; }
[dir="rtl"] .switch input:checked::after { transform: translateX(-14px); }
[dir="rtl"] .toast                     { animation-name: fq-toast-in-rtl; }
@keyframes fq-toast-in-rtl  { from { opacity: 0; transform: translateX(-18px) scale(.98); } to { opacity: 1; transform: none; } }
@keyframes fq-toast-out-rtl { to   { opacity: 0; transform: translateX(-18px) scale(.98); } }
[dir="rtl"] .toast.is-leaving          { animation-name: fq-toast-out-rtl; }

/* ── 4. Directional icons flip; the rest must not ──────────────────────────
   A chevron, a back arrow and a sign-out arrow point somewhere, so they mirror.
   A checkmark, a magnifier, a bell, a shield, a clock or a status glyph mean
   the same thing in both directions and mirroring them just makes them wrong. */
[dir="rtl"] svg use[href="#i-chev-l"],
[dir="rtl"] svg:has(use[href="#i-chev-l"]),
[dir="rtl"] svg:has(use[href="#i-out"]),
[dir="rtl"] svg:has(use[href="#i-route"]),
[dir="rtl"] .wb-chev,
[dir="rtl"] .crumbs .sep,
[dir="rtl"] .tree-node .tree-caret,
[dir="rtl"] .diff-arrow,
[dir="rtl"] .pager button[data-pg="prev"],
[dir="rtl"] .pager button[data-pg="next"] { transform: scaleX(-1); }
/* the CSS-triangle carets are geometry, so they are flipped rather than rebuilt */
[dir="rtl"] .kv-toggle::before,
[dir="rtl"] .audit-row .chev::before { transform: scaleX(-1); }

/* ── 5. Never mirrored ─────────────────────────────────────────────────────
   A cheque image and a signature specimen are evidence. They have a fixed
   physical orientation: a mirrored cheque is not an RTL cheque, it is a
   forgery-shaped artefact, and a mirrored signature cannot be compared against
   the registered one at all. The artwork stays LTR in every locale; only the
   chrome around it — toolbar order, labels, captions — follows the layout. */
[dir="rtl"] .viewer-canvas,
[dir="rtl"] .viewer-canvas svg,
[dir="rtl"] .thumb, [dir="rtl"] .thumb svg,
[dir="rtl"] .slot-thumb, [dir="rtl"] .slot-thumb svg,
[dir="rtl"] .sig-frame, [dir="rtl"] .sig-frame svg,
[dir="rtl"] .sig-overlay, [dir="rtl"] .sig-layer, [dir="rtl"] .sig-layer svg,
[dir="rtl"] .sigcmp-pane, [dir="rtl"] .sig-mini, [dir="rtl"] .sig-mini svg,
[dir="rtl"] .cheque-art {
  direction: ltr;
}
[dir="rtl"] .viewer-canvas, [dir="rtl"] .sig-frame svg, [dir="rtl"] .sig-layer svg { transform: none; }

/* THE REGISTERED / CHEQUE PAIR DOES NOT SWAP SIDES.
   Decision, and the reasoning: the reviewer is comparing a screen against a
   physical process in which the registered specimen is always the reference and
   always sits in the same place. If the two panes swapped by locale, an
   English-reading and an Arabic-reading reviewer at adjacent desks would point
   at opposite sides of the screen while saying "the registered one". The pair
   keeps its LTR order in both languages; the labels, the VS marker, the scores
   and every control around it mirror normally. */
[dir="rtl"] .sig-pair { direction: ltr; }
[dir="rtl"] .sig-side-head, [dir="rtl"] .sig-side-label,
[dir="rtl"] .sig-side-meta, [dir="rtl"] .sig-key { direction: rtl; }

/* ── 6. The comparison table keeps its pairing ─────────────────────────────
   "Customer Master | Extracted from cheque | Verdict" mirrors as a whole, so
   the master value stays adjacent to the value it is being compared with and
   the verdict stays at the end of the row. The relationship survives the flip
   because the grid mirrors as one unit rather than per cell. */
[dir="rtl"] .cmp-head, [dir="rtl"] .cmp-row { direction: rtl; }
[dir="rtl"] .cmp-val { direction: ltr; unicode-bidi: isolate; text-align: end; }

/* A comparison cell normally holds data — an id, an amount, a code — which is
   why it is mono and pinned to LTR. A cell holding a role name or a delivery
   channel is language, not data: forcing it LTR renders Arabic letter-spaced
   and in the wrong reading order, so it takes the UI family and the page's
   own direction instead. */
.cmp-row .cmp-val--text, .cmp-val--text { font-family: var(--font-ui); letter-spacing: normal; }
[lang="ar"] .cmp-val--text,
[dir="rtl"] .cmp-val--text { direction: inherit; unicode-bidi: normal; text-align: start; }

/* ── 7. Mixed-script content ───────────────────────────────────────────────
   An Arabic customer name beside a Latin account number, or an Arabic sentence
   containing "MICR", must not reorder. Isolation is applied at the boundary. */
.bidi-isolate, [lang="ar"] .cite, [lang="ar"] .cmp-source { unicode-bidi: isolate; }

/* ── the language toggle ───────────────────────────────────────────────────
   Prototype chrome sits next to the acting-role control because both answer
   "who am I and how am I reading this". The switch is one click, always
   visible, and legible before sign-in. */
.lang-btn {
  display: inline-flex; align-items: center; gap: 5px; height: 30px; padding: 0 var(--sp-2);
  border: 1px solid var(--line); border-radius: var(--r-sm);
  background: var(--surface); color: var(--ink-2);
  font-family: var(--font-head); font-size: var(--fs-2xs); font-weight: 600;
  letter-spacing: var(--tr-wide); white-space: nowrap;
  transition: background var(--motion-micro), border-color var(--motion-micro), color var(--motion-micro);
}
.lang-btn:hover { background: var(--surface-3); border-color: var(--line-strong); color: var(--ink); }
.lang-btn .lang-sep { color: var(--ink-4); font-weight: 400; }
/* the active language is the one in brand ink; the other is the offer */
.lang-btn [data-lang-opt] { color: var(--ink-4); transition: color var(--motion-micro); }
.lang-btn [data-lang-opt].is-active { color: var(--brand); }
.lang-btn:hover [data-lang-opt]:not(.is-active) { color: var(--ink-2); }
.auth-bar .lang-btn { background: rgba(255,255,255,.05); border-color: var(--line-inverse); color: var(--chrome-ink-2); }
.auth-bar .lang-btn:hover { background: rgba(255,255,255,.10); color: var(--chrome-ink); }
.auth-bar .lang-btn [data-lang-opt] { color: var(--chrome-ink-3); }
.auth-bar .lang-btn [data-lang-opt].is-active { color: var(--chrome-ink); }

/* the direction change is a considered transition, not a reload flash */
html.is-switching-lang body { opacity: .55; }
html body { transition: opacity var(--motion-standard); }
@media (prefers-reduced-motion: reduce) {
  html.is-switching-lang body { opacity: 1; }
  html body { transition: none; }
}
