    /* ────────────────────────────────────────────────────────────────
       TOKENS — single source of truth.
       Deep forest green is the brand commitment (ledger-cover green).
       Pure paper-white body. Near-black ink with a green undertone so
       the document feels of-a-piece, not stitched.
       Verified for WCAG AA+ at body sizes; see brief.
       ──────────────────────────────────────────────────────────────── */
    :root {
      /* GREEN & WHITE THEME — deep forest, ledger-paper neutrals.
         The brand is the Saudi-adjacent forest green; the desk is white. */
      --brand:        oklch(0.38 0.095 152);    /* deep forest green */
      --brand-deep:   oklch(0.26 0.075 152);    /* shadow brand · header rim, footer */
      --brand-soft:   oklch(0.44 0.090 152);    /* hover lift on brand surfaces */
      --brand-on:     oklch(0.985 0.005 145);   /* near-white type on brand */
      --brand-on-mu:  oklch(0.92 0.015 145);    /* muted white · secondary on brand */
      --brand-on-fa:  oklch(0.82 0.020 145);    /* faint white · captions / stamps on brand */
      --brand-tint:   oklch(0.97 0.020 152);    /* pale moss · paper accent that ties to brand */

      --paper:        oklch(1.000 0 0);         /* pure white */
      --paper-warm:   oklch(0.985 0.004 145);   /* a whisper of green, ledger band */
      --paper-sunk:   oklch(0.968 0.006 145);   /* a hair darker — for sunken / inset surfaces */
      --ink:          oklch(0.18 0.012 155);    /* body ink with a green undertone, ~16:1 on paper */
      --ink-muted:    oklch(0.42 0.014 155);    /* secondary, ~6:1 on paper */
      --ink-faint:    oklch(0.56 0.012 155);    /* tertiary, captions */
      --rule:         oklch(0.88 0.010 152);    /* hairlines */
      --rule-deep:    oklch(0.70 0.014 152);    /* heavier register lines */

      /* Ramp for state words — no fills, just typographic colour.
         state-pass is deliberately deeper than --brand so the verdict word
         still reads as distinct from the brand surface. */
      --state-pass:   oklch(0.32 0.105 150);    /* deeper forest */
      --state-deny:   oklch(0.40 0.13 25);      /* burnt red, only on words */
      --state-gov:    oklch(0.30 0.08 260);     /* deep ink-blue */
      --state-pass-tint: oklch(0.96 0.045 150); /* pale moss wash */
      --state-deny-tint: oklch(0.96 0.04 25);   /* pale red wash */
      --state-near:      oklch(0.45 0.10 70);   /* burnt amber ink — partial/fuzzy match */
      --state-near-tint: oklch(0.97 0.04 85);   /* pale amber wash */
      --state-gov-tint:  oklch(0.96 0.03 260);  /* pale blue wash */

      --z-base: 0; --z-sticky: 30; --z-overlay: 40; --z-toast: 50;
    }

    *, *::before, *::after { box-sizing: border-box; }

    html, body {
      background: var(--paper);
      color: var(--ink);
      font-family: 'IBM Plex Sans', system-ui, sans-serif;
      font-feature-settings: 'ss01', 'ss02';
      -webkit-font-smoothing: antialiased;
      text-rendering: optimizeLegibility;
    }

    /* Sticky footer — short pages (e.g. /admin/users) used to end where
       their content ended, leaving the footer floating with a bare band
       of page background below it. Body becomes a full-viewport flex
       column; <main> absorbs the slack so the footer always sits at the
       bottom edge. margin:0 is required — the UA default 8px body margin
       otherwise adds a bar outside the flex box. */
    body {
      margin: 0;
      min-height: 100vh;
      min-height: 100dvh;
      display: flex;
      flex-direction: column;
    }
    .app-shell { flex: 1; display: flex; align-items: stretch; min-width: 0; }
    .app-content { flex: 1; min-width: 0; display: flex; flex-direction: column; }
    main#main { flex: 1 0 auto; width: 100%; }
    .app-content > footer { margin-top: auto; }

    /* Arabic mode: IBM Plex stays the single voice — Latin glyphs from
       IBM Plex Sans, Arabic glyphs from IBM Plex Sans Arabic (via
       unicode-range). Lift line-height a hair so Plex Arabic sits
       comfortably. */
    html[dir="rtl"], html[dir="rtl"] body {
      font-family: 'IBM Plex Sans Arabic', 'IBM Plex Sans', system-ui, sans-serif;
      line-height: 1.6;
    }
    /* Inside RTL mode, things tagged .ar are already Arabic — make sure they
       inherit and don't re-flip direction unnecessarily. */
    html[dir="rtl"] .ar { direction: rtl; }
    /* Latin-only artifacts (codes, hashes, mono) keep their LTR direction
       even inside an RTL document. */
    html[dir="rtl"] .t-mono, html[dir="rtl"] code, html[dir="rtl"] pre {
      direction: ltr;
      unicode-bidi: isolate;
    }
    /* Arabic script must never be letter-spaced — tracking (positive or
       negative) visibly breaks the cursive letter joins. In RTL mode zero
       the tracking on every tracked style: headings (negative tracking),
       label/meta styles and inline tracking-[…] utilities (wide positive
       tracking), and the Arabic verdict stamp. Latin runs inside RTL
       pages lose their decorative tracking too — acceptable. */
    html[dir="rtl"] :is(h1, h2, h3,
        .t-display, .t-h1, .t-h2, .t-h3, .t-meta,
        .field-label, .pill, .page-meta, .kv-label,
        .side-group-label, .mobile-nav-group-label,
        .verdict-stamp-ar, [class*="tracking-"]) {
      letter-spacing: 0;
    }

    body { font-size: 16px; line-height: 1.5; }

    h1, h2, h3 { text-wrap: balance; letter-spacing: -0.022em; }
    p { text-wrap: pretty; }

    /* Arabic helper — RTL direction + a hair of extra line-height for the
       IBM Plex Sans Arabic for Arabic glyphs via unicode-range; IBM Plex
       Sans as Latin fallback for any mixed content. */
    .ar {
      font-family: 'IBM Plex Sans Arabic', 'IBM Plex Sans', system-ui, sans-serif;
      direction: rtl;
      unicode-bidi: isolate;
      line-height: 1.6;
      font-feature-settings: 'kern', 'liga';
    }

    /* ────────────────────────────────────────────────────────────────
       BILINGUAL PAIRED-TEXT GRID
       Architecture, not garnish (Design Principle #2).
       Default LTR: Latin on the start side, Arabic on the end side,
       both on the same baseline. Reverses cleanly under `dir="rtl"`.
       ──────────────────────────────────────────────────────────────── */
    .pair {
      display: grid;
      grid-template-columns: 1fr auto;
      column-gap: clamp(1rem, 2vw, 2rem);
      align-items: baseline;
    }
    .pair > .ar { text-align: end; }
    .pair-block { display: grid; row-gap: 0.25rem; }
    .pair-block > .ar { justify-self: end; }

    /* Long-form bilingual rows used in the ledger: two columns share a row
       but each holds full text in its language. */
    .pair-row {
      display: grid;
      grid-template-columns: minmax(0, 1.4fr) minmax(0, 1fr);
      column-gap: clamp(1rem, 2.5vw, 2.5rem);
      align-items: baseline;
    }
    .pair-row > .ar { text-align: end; }

    /* ────────────────────────────────────────────────────────────────
       SURFACES
       ──────────────────────────────────────────────────────────────── */
    .surface-brand {
      background: var(--brand);
      color: var(--brand-on);
    }
    .surface-brand-deep { background: var(--brand-deep); color: var(--brand-on); }
    .surface-paper {
      background: var(--paper);
      color: var(--ink);
    }
    .surface-warm {
      background: var(--paper-warm);
      color: var(--ink);
    }

    .on-brand-muted     { color: var(--brand-on-mu); }
    .ink-muted          { color: var(--ink-muted); }
    .ink-faint          { color: var(--ink-faint); }

    /* ────────────────────────────────────────────────────────────────
       TYPE SCALE
       Modular, fluid; weight contrast inside one Latin family carries
       hierarchy. No display serif (the editorial-typographic reflex).
       ──────────────────────────────────────────────────────────────── */
    .t-display {
      font-family: 'IBM Plex Sans', system-ui, sans-serif;
      font-weight: 500;
      /* Sized for a ~430px column at 1440 viewport. */
      font-size: clamp(1.875rem, 2.7vw, 2.5rem);
      line-height: 1.1;
      letter-spacing: -0.025em;
    }
    .t-display-ar {
      font-family: 'IBM Plex Sans Arabic', 'IBM Plex Sans', system-ui, sans-serif;
      direction: rtl;
      unicode-bidi: isolate;
      font-weight: 500;
      font-size: clamp(1.375rem, 2vw, 1.875rem);
      line-height: 1.65;
    }
    .t-h1 {
      font-weight: 600;
      font-size: clamp(1.875rem, 3vw, 2.5rem);
      line-height: 1.08;
      letter-spacing: -0.025em;
    }
    .t-h2 {
      font-weight: 600;
      font-size: clamp(1.75rem, 2.4vw, 2.125rem);
      line-height: 1.1;
      letter-spacing: -0.022em;
    }
    /* Arabic counterpart used INSIDE h2 partners — meaningfully smaller
       than the Latin h2 so the pair reads as title + translation, not
       two competing display lines. */
    .t-h2-ar {
      font-family: 'IBM Plex Sans Arabic', 'IBM Plex Sans', system-ui, sans-serif;
      direction: rtl;
      unicode-bidi: isolate;
      font-weight: 500;
      font-size: clamp(1.125rem, 1.5vw, 1.375rem);
      line-height: 1.65;
    }
    .t-h3 {
      font-weight: 600;
      font-size: clamp(1.125rem, 1.5vw, 1.375rem);
      line-height: 1.2;
      letter-spacing: -0.012em;
    }
    .t-lead {
      font-size: clamp(1rem, 1.2vw, 1.125rem);
      line-height: 1.55;
      max-width: 64ch;
    }
    .t-body { font-size: 0.9375rem; line-height: 1.6; max-width: 70ch; }
    .t-meta { font-size: 0.75rem; letter-spacing: 0.04em; }
    /* Plex Mono has no Arabic glyphs — without the Sans Arabic fallback,
       Arabic label text in mono slots falls to the system monospace and
       renders as disconnected per-cell letters. Latin/digits still hit
       Plex Mono first; only Arabic glyphs fall through. */
    .t-mono { font-family: 'IBM Plex Mono', 'IBM Plex Sans Arabic', ui-monospace, monospace; font-feature-settings: 'tnum'; }

    /* ────────────────────────────────────────────────────────────────
       INPUTS — registry-form, bottom-border discipline.
       No rounded card chrome. The desk does not bevel its forms.
       ──────────────────────────────────────────────────────────────── */
    .field {
      display: grid;
      row-gap: 0.5rem;
    }
    .field-label {
      font-size: 0.75rem;
      letter-spacing: 0.06em;
      text-transform: uppercase;
      font-weight: 600;
      color: var(--ink);
      display: flex;
      gap: 0.75rem;
      align-items: baseline;
      justify-content: space-between;
    }
    .field-label .ar {
      font-size: 0.8125rem;
      letter-spacing: 0;
      text-transform: none;
      color: var(--ink-muted);
      font-weight: 500;
    }
    /* Stacked bilingual label — Latin over Arabic on its own line, no cramping. */
    .field-label.is-stacked {
      flex-direction: column;
      align-items: stretch;
      gap: 0.2rem;
    }
    .field-label.is-stacked .ar { align-self: flex-start; }
    .field-input,
    .field input[type="text"],
    .field input[type="number"],
    .field input:not([type]),
    .field select,
    .field textarea {
      width: 100%;
      background: transparent;
      border: 0;
      border-bottom: 1.5px solid var(--rule-deep);
      border-radius: 0;
      padding: 0.625rem 0;
      font-size: 0.9375rem;
      font-family: inherit;
      color: var(--ink);
      transition: border-color 120ms ease, background-color 120ms ease;
    }
    /* Filled variant — used in compact admin forms where bottom-border floats
       too thin against dense content. Same ink, paper-sunk surface, hairline. */
    .field.is-filled input,
    .field.is-filled select,
    .field.is-filled textarea {
      background: var(--paper-sunk);
      border: 1px solid var(--rule);
      padding: 0.625rem 0.75rem;
    }
    .field.is-filled input:focus,
    .field.is-filled select:focus,
    .field.is-filled textarea:focus {
      background: var(--paper);
      border-color: var(--brand);
      box-shadow: 0 0 0 3px oklch(0.38 0.095 152 / 0.12);
    }
    .field input::placeholder { color: var(--ink-faint); }
    .field input:focus,
    .field select:focus,
    .field textarea:focus {
      outline: none;
      border-bottom-color: var(--brand);
      background: linear-gradient(to top, oklch(0.38 0.095 152 / 0.05), transparent 60%);
    }
    .field input[type="checkbox"] { accent-color: var(--brand); width: auto; }
    .field-mono input { font-family: 'IBM Plex Mono', ui-monospace, monospace; font-feature-settings: 'tnum'; letter-spacing: 0.02em; }

    /* Inputs on the brand surface need ivory rules. */
    .surface-brand .field-label,
    .surface-brand .field-input { color: var(--brand-on); }
    .surface-brand .field-label .ar { color: var(--brand-on-mu); }
    .surface-brand .field-input,
    .surface-brand .field input,
    .surface-brand .field select,
    .surface-brand .field textarea {
      border-bottom-color: oklch(0.97 0.012 60 / 0.42);
      color: var(--brand-on);
    }
    .surface-brand .field input::placeholder { color: oklch(0.985 0.012 60 / 0.62); }
    .surface-brand .field input:focus,
    .surface-brand .field select:focus,
    .surface-brand .field textarea:focus {
      border-bottom-color: var(--brand-on);
      background: linear-gradient(to top, oklch(0.97 0.012 60 / 0.08), transparent 60%);
    }
    .surface-brand select { color-scheme: dark; }
    .surface-brand select option { background: var(--brand-deep); color: var(--brand-on); }

    /* Checkbox row presented as a discrete field with the same baseline. */
    .check-row {
      display: flex;
      align-items: center;
      gap: 0.625rem;
      padding: 0.625rem 0;
      border-bottom: 1.5px solid var(--rule-deep);
      cursor: pointer;
      user-select: none;
    }
    .surface-brand .check-row { border-bottom-color: oklch(0.97 0.012 60 / 0.42); }
    .check-row input { width: 1rem; height: 1rem; accent-color: var(--brand); }
    .surface-brand .check-row input { accent-color: var(--brand-on); }

    /* ────────────────────────────────────────────────────────────────
       BUTTONS — verbs, not affordance theatre.
       ──────────────────────────────────────────────────────────────── */
    .btn {
      display: inline-flex;
      align-items: center;
      justify-content: center;
      gap: 0.5rem;
      font-family: inherit;
      font-size: 0.875rem;
      font-weight: 600;
      letter-spacing: 0.01em;
      padding: 0.875rem 1.25rem;
      border-radius: 2px;
      border: 1px solid transparent;
      cursor: pointer;
      transition: background-color 120ms ease, border-color 120ms ease, color 120ms ease;
    }
    .btn:focus-visible {
      outline: 2px solid var(--brand-on);
      outline-offset: 3px;
    }
    .btn-primary {
      background: var(--brand-on);
      color: var(--brand-deep);
      border-color: var(--brand-on);
    }
    .btn-primary:hover { background: oklch(1 0 0); border-color: oklch(1 0 0); }

    /* Same button on paper surfaces — invert. */
    .surface-paper .btn-primary,
    .surface-warm  .btn-primary {
      background: var(--brand);
      color: var(--brand-on);
      border-color: var(--brand);
    }
    .surface-paper .btn-primary:hover,
    .surface-warm  .btn-primary:hover { background: var(--brand-soft); border-color: var(--brand-soft); }

    .btn-ghost {
      background: transparent;
      color: var(--brand-on);
      border-color: oklch(0.97 0.012 60 / 0.55);
    }
    .btn-ghost:hover { border-color: var(--brand-on); background: oklch(0.97 0.012 60 / 0.06); }

    /* Ghost on paper — outline button. */
    .surface-paper .btn-ghost,
    .surface-warm  .btn-ghost {
      color: var(--ink);
      border-color: var(--rule-deep);
    }
    .surface-paper .btn-ghost:hover,
    .surface-warm  .btn-ghost:hover { border-color: var(--ink); background: var(--paper-warm); }

    /* Compact verb-button, no chrome — for inline row actions.
       inline-flex + nowrap so a leading icon sits on the text line instead
       of wrapping when a flex parent squeezes the button. */
    .btn-text {
      display: inline-flex;
      align-items: center;
      gap: 0.4rem;
      white-space: nowrap;
      font: 600 0.75rem/1 'IBM Plex Sans', system-ui, sans-serif;
      letter-spacing: 0.04em;
      text-transform: uppercase;
      color: var(--ink);
      background: transparent;
      border: 0;
      padding: 0.45rem 0.65rem;
      cursor: pointer;
      border-radius: 1px;
      transition: background-color 100ms ease, color 100ms ease;
    }
    .btn-text:hover { background: var(--paper-warm); }
    .btn-text.is-danger { color: var(--state-deny); }
    .btn-text.is-danger:hover { background: var(--state-deny-tint); }
    .btn-text.is-go { color: var(--state-pass); }
    .btn-text.is-go:hover { background: var(--state-pass-tint); }

    /* ────────────────────────────────────────────────────────────────
       STATE WORDS — Design Principle #4 in CSS form.
       No pills. No coloured backgrounds. The state is a WORD with a
       leading glyph (a paragraph mark / pilcrow analogue), in a single
       deep-saturated ink. Colorblind-safe because the word carries it.
       ──────────────────────────────────────────────────────────────── */
    .state {
      display: inline-flex;
      align-items: baseline;
      gap: 0.4rem;
      font-weight: 600;
      letter-spacing: 0.02em;
      font-size: 0.8125rem;
    }
    .state::before {
      content: '';
      width: 6px; height: 6px;
      border-radius: 1px;
      display: inline-block;
      background: currentColor;
      align-self: center;
    }
    .state-pass { color: var(--state-pass); }
    .state-deny { color: var(--state-deny); }
    .state-gov  { color: var(--state-gov); }
    .state-near { color: var(--state-near); }
    .state-pend { color: var(--ink-muted); }
    .state-pend::before { background: transparent; border: 1.5px solid currentColor; border-radius: 0; }

    /* ────────────────────────────────────────────────────────────────
       LEGACY pill class kept for templates we haven't migrated yet.
       Minimised; will be removed when interview/admin/audit are refit.
       ──────────────────────────────────────────────────────────────── */
    .pill {
      display: inline-flex; align-items: center; gap: 0.375rem;
      padding: 0.125rem 0.5rem;
      font-size: 0.6875rem; font-weight: 600; letter-spacing: 0.04em;
      border: 1px solid var(--rule); border-radius: 1px;
      color: var(--ink-muted);
    }
    .pill-ok    { color: var(--state-pass); border-color: oklch(0.38 0.10 150 / 0.4); }
    .pill-no    { color: var(--state-deny); border-color: oklch(0.40 0.13 25 / 0.45); }
    .pill-gov   { color: var(--state-gov);  border-color: oklch(0.30 0.08 260 / 0.4); }
    .pill-rev   { color: var(--ink); border-color: var(--rule-deep); }
    .pill-pend  { color: var(--ink-muted); }
    .pill-admin { color: var(--brand-on); background: var(--brand-deep); border-color: var(--brand-deep); }
    .pill-user  { color: var(--brand-on); background: var(--brand);      border-color: var(--brand); }
    .chain-ok      { color: var(--state-pass); border-color: oklch(0.38 0.10 150 / 0.4); }
    .chain-tamper  { color: var(--state-deny); border-color: oklch(0.40 0.13 25 / 0.45); }

    /* ────────────────────────────────────────────────────────────────
       INTAKE CARD — landing "new check-in" panel.
       White paper card on a warm wash. Rounded soft inputs replace the
       bottom-border discipline used elsewhere; the card is a focused
       task surface, not a register row.
       ──────────────────────────────────────────────────────────────── */
    .intake-shell {
      background: var(--paper-warm);
    }
    .intake-card {
      background: var(--paper);
      border: 1px solid var(--rule);
      border-radius: 24px;
      padding: clamp(1.75rem, 3.2vw, 2.75rem);
      box-shadow:
        0 1px 2px oklch(0.18 0.012 155 / 0.04),
        0 18px 40px -18px oklch(0.18 0.012 155 / 0.10);
    }
    .intake-title {
      font-family: 'IBM Plex Sans', system-ui, sans-serif;
      font-weight: 400;
      font-size: clamp(1.875rem, 2.6vw, 2.375rem);
      line-height: 1.05;
      letter-spacing: -0.015em;
      color: var(--ink);
    }
    .intake-badge {
      display: inline-flex;
      align-items: center;
      gap: 0.4rem;
      padding: 0.4rem 0.75rem;
      border-radius: 999px;
      background: var(--paper-sunk);
      color: var(--ink-muted);
      font-size: 0.75rem;
      font-weight: 500;
      letter-spacing: 0.005em;
    }
    .intake-badge::before {
      content: '';
      width: 6px; height: 6px; border-radius: 999px;
      background: var(--state-pass);
    }
    /* Soft rounded input field — pill border, internal padding. */
    .field-soft {
      display: grid;
      row-gap: 0.5rem;
    }
    .field-soft > .field-label {
      font-size: 0.875rem;
      font-weight: 500;
      letter-spacing: 0;
      text-transform: none;
      color: var(--ink);
      gap: 0.5rem;
      /* Keep icon + label together at the start edge: a label that sits
         at the far end of its column loses its visual bond with the
         input below it. Inline actions (e.g. "use today") opt back into
         the end edge with ms-auto. */
      justify-content: flex-start;
    }
    .field-soft input,
    .field-soft select,
    .field-soft textarea {
      width: 100%;
      background: var(--paper);
      border: 1px solid var(--rule);
      border-radius: 10px;
      padding: 0.75rem 0.9rem;
      font-size: 0.9375rem;
      font-family: inherit;
      color: var(--ink);
      transition: border-color 120ms ease, box-shadow 120ms ease;
      appearance: none;
    }
    .field-soft select {
      background-image: url("data:image/svg+xml,%3Csvg width='12' height='8' viewBox='0 0 12 8' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M1 1.5l5 5 5-5' stroke='%237A8A82' fill='none' stroke-width='1.4' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
      background-repeat: no-repeat;
      background-position: right 0.9rem center;
      padding-right: 2.25rem;
    }
    /* RTL: flip chevron to the logical start (left) side. */
    html[dir="rtl"] .field-soft select {
      background-position: left 0.9rem center;
      padding-right: 0.9rem;
      padding-left: 2.25rem;
    }
    .field-soft input::placeholder { color: var(--ink-faint); }
    .field-soft input:focus,
    .field-soft select:focus,
    .field-soft textarea:focus {
      outline: none;
      border-color: var(--brand);
      box-shadow: 0 0 0 3px oklch(0.38 0.095 152 / 0.14);
    }
    /* Field-pair: stack two inputs inside one rounded box (Airline + flight). */
    .field-pair {
      display: grid;
      grid-template-columns: 1fr 7rem;
      align-items: stretch;
      border: 1px solid var(--rule);
      border-radius: 10px;
      background: var(--paper);
      overflow: hidden;
      transition: border-color 120ms ease, box-shadow 120ms ease;
    }
    .field-pair:focus-within {
      border-color: var(--brand);
      box-shadow: 0 0 0 3px oklch(0.38 0.095 152 / 0.14);
    }
    .field-pair input {
      border: 0;
      background: transparent;
      padding: 0.75rem 0.9rem;
      font-size: 0.9375rem;
      font-family: inherit;
      color: var(--ink);
    }
    .field-pair input:focus { outline: none; }
    .field-pair input + input {
      border-inline-start: 1px solid var(--rule);
      font-family: 'IBM Plex Sans', system-ui, sans-serif;
      font-feature-settings: 'tnum';
      letter-spacing: 0.02em;
    }

    /* Checkbox row card — same border language as a rounded field. */
    .intake-check {
      display: flex;
      align-items: center;
      gap: 0.75rem;
      padding: 0.85rem 1rem;
      background: var(--paper);
      border: 1px solid var(--rule);
      border-radius: 10px;
      cursor: pointer;
      user-select: none;
      transition: border-color 120ms ease, background-color 120ms ease;
    }
    .intake-check:hover { border-color: var(--rule-deep); }
    .intake-check input {
      width: 1.05rem;
      height: 1.05rem;
      accent-color: var(--brand);
      margin: 0;
    }
    .intake-check.is-on { border-color: var(--brand); background: oklch(0.38 0.095 152 / 0.04); }

    /* Go button — solid forest green, rounded. */
    .btn-go {
      display: inline-flex;
      align-items: center;
      gap: 0.55rem;
      padding: 0.85rem 1.4rem;
      background: var(--brand);
      color: var(--brand-on);
      border: 1px solid var(--brand);
      border-radius: 12px;
      font-family: inherit;
      font-size: 0.9375rem;
      font-weight: 500;
      letter-spacing: 0;
      cursor: pointer;
      transition: background-color 120ms ease, border-color 120ms ease, transform 120ms ease;
    }
    .btn-go:hover { background: var(--brand-soft); border-color: var(--brand-soft); }
    .btn-go:active { transform: translateY(1px); }

    /* ────────────────────────────────────────────────────────────────
       LEDGER — the table aesthetic for Zone C.
       A real register, not a card grid.
       ──────────────────────────────────────────────────────────────── */
    .ledger {
      width: 100%;
      border-collapse: separate;
      border-spacing: 0;
      font-size: 0.875rem;
    }
    .ledger thead th {
      text-align: start;
      padding: 0.875rem 1rem;
      font-size: 0.6875rem;
      letter-spacing: 0.12em;
      text-transform: uppercase;
      font-weight: 600;
      color: var(--ink-muted);
      border-bottom: 1.5px solid var(--ink);
      vertical-align: bottom;
    }
    .ledger thead th .ar {
      display: block;
      text-transform: none;
      letter-spacing: 0;
      font-size: 0.75rem;
      color: var(--ink-faint);
      font-weight: 500;
      margin-top: 0.125rem;
    }
    .ledger tbody td {
      padding: 1rem;
      border-bottom: 1px solid var(--rule);
      vertical-align: top;
    }
    .ledger tbody tr { transition: background-color 100ms ease; }
    .ledger tbody tr:hover { background: var(--paper-warm); }
    .ledger tbody tr:hover td { border-bottom-color: var(--rule-deep); }
    .ledger tbody tr.is-empty td {
      text-align: center;
      color: var(--ink-faint);
      padding: 3rem 1rem;
    }
    .ledger a { color: inherit; text-decoration: none; display: block; }

    /* Ledger header row — columns are supplied inline per page via
       grid-template-columns so header and body rows share one spec. */
    .ledger-grid {
      display: grid;
      align-items: baseline;
    }

    /* Div-grid ledger row used by the redesigned landing. */
    .ledger-row {
      padding: 1rem 0;
      border-bottom: 1px solid var(--rule);
      color: inherit;
      text-decoration: none;
      transition: background-color 100ms ease, border-color 100ms ease, padding 100ms ease;
    }
    .ledger-row:hover {
      background: var(--paper);
      border-bottom-color: var(--rule-deep);
      padding-inline: 0.75rem;
    }

    /* ────────────────────────────────────────────────────────────────
       PANEL — paper-surface block with a single hairline frame.
       The desk doesn't shadow its documents; it rules them.
       ──────────────────────────────────────────────────────────────── */
    .panel {
      background: var(--paper);
      border: 1px solid var(--rule);
      padding: clamp(1.5rem, 3vw, 2.5rem);
    }
    .panel-sunk { background: var(--paper-warm); border: 1px solid var(--rule); }
    .panel-head {
      padding: 1.25rem clamp(1.5rem, 3vw, 2.5rem);
      border-bottom: 1px solid var(--rule);
      background: var(--paper-warm);
    }
    .panel-body { padding: clamp(1.5rem, 3vw, 2.5rem); }

    /* Page header — eyebrow + display headline + meta column.
       Used on every internal page so they share posture. */
    .page-head {
      display: grid;
      grid-template-columns: 1fr auto;
      column-gap: 2.5rem;
      row-gap: 0.5rem;
      align-items: end;
      padding-block: clamp(2rem, 4vw, 3rem);
      border-bottom: 1.5px solid var(--ink);
    }
    .page-meta {
      font: 500 0.75rem/1.4 'IBM Plex Sans', system-ui, sans-serif;
      letter-spacing: 0.06em;
      text-transform: uppercase;
      color: var(--ink-muted);
      text-align: end;
    }

    /* ────────────────────────────────────────────────────────────────
       VERDICT BAND — used on the decision page header.
       Tints are deliberately whisper-thin so the word still carries it.
       A giant rotated stamp (.verdict-stamp) sits behind the headline
       on the side opposite the confidence number, like a rubber stamp
       impressed on the registry page after the verdict was written.
       ──────────────────────────────────────────────────────────────── */
    .verdict {
      padding: clamp(2.5rem, 5vw, 4rem) clamp(1.75rem, 4vw, 3rem);
      border-block: 1.5px solid currentColor;
      position: relative;
      overflow: hidden;     /* keeps the rotated stamp from leaking out */
    }
    .verdict-pass { background: var(--state-pass-tint); color: var(--state-pass); }
    .verdict-deny { background: var(--state-deny-tint); color: var(--state-deny); }
    .verdict-gov  { background: var(--state-gov-tint);  color: var(--state-gov); }

    /* Rubber-stamp impression behind the verdict headline. Hollow letters
       (transparent fill + thick stroke) inside a heavy bordered box,
       rotated and offset toward the right edge so it whispers behind the
       headline rather than crowding it. Animates in on page load with a
       tiny "stamp down" gesture — translate + scale + opacity. */
    .verdict-stamp {
      position: absolute;
      top: 50%;
      inset-inline-end: clamp(-1rem, -2vw, 1rem);
      transform: translateY(-50%) rotate(-12deg) scale(1);
      display: grid;
      gap: 0.1em;
      justify-items: center;
      padding: 0.45em 0.85em;
      border: 0.18em solid currentColor;
      border-radius: 14px;
      color: currentColor;
      opacity: 0.16;
      pointer-events: none;
      user-select: none;
      white-space: nowrap;
      line-height: 1;
      filter: blur(0.4px);  /* soft 'inked impression' */
      animation: mw-stamp 700ms cubic-bezier(0.34, 1.56, 0.64, 1) both;
      animation-delay: 380ms;
    }
    .verdict-stamp-en {
      font-size: clamp(3.5rem, 9vw, 7.5rem);
      font-weight: 700;
      letter-spacing: 0.08em;
      -webkit-text-stroke: 0.05em currentColor;
      color: transparent;
    }
    .verdict-stamp-ar {
      font-size: clamp(1.5rem, 3vw, 2.25rem);
      font-weight: 600;
      /* No tracking: Arabic joins break under letter-spacing, and this
         span is Arabic in BOTH language modes. */
      letter-spacing: 0;
      direction: rtl;
      unicode-bidi: isolate;
      -webkit-text-stroke: 0.04em currentColor;
      color: transparent;
    }
    @keyframes mw-stamp {
      0%   { opacity: 0; transform: translateY(-50%) rotate(-12deg) scale(2.6);     filter: blur(8px); }
      55%  { opacity: 0.32; transform: translateY(-50%) rotate(-12deg) scale(1.04); filter: blur(0px); }
      80%  { opacity: 0.20; transform: translateY(-50%) rotate(-12deg) scale(0.98); }
      100% { opacity: 0.16; transform: translateY(-50%) rotate(-12deg) scale(1);    filter: blur(0.4px); }
    }
    /* RTL: mirror the stamp to the opposite side so the confidence
       number on the leading edge still has clear air around it.
       The @keyframes block CANNOT nest under html[dir="rtl"] — that is
       invalid CSS. Instead we define a separate named keyframe and point
       the RTL stamp at it via animation-name. */
    html[dir="rtl"] .verdict-stamp {
      inset-inline-end: auto;
      inset-inline-start: clamp(-1rem, -2vw, 1rem);
      transform: translateY(-50%) rotate(12deg);
      animation-name: mw-stamp-rtl;
    }
    @keyframes mw-stamp-rtl {
      0%   { opacity: 0; transform: translateY(-50%) rotate(12deg) scale(2.6);     filter: blur(8px); }
      55%  { opacity: 0.32; transform: translateY(-50%) rotate(12deg) scale(1.04); filter: blur(0px); }
      80%  { opacity: 0.20; transform: translateY(-50%) rotate(12deg) scale(0.98); }
      100% { opacity: 0.16; transform: translateY(-50%) rotate(12deg) scale(1);    filter: blur(0.4px); }
    }
    @media (max-width: 760px) {
      .verdict-stamp { display: none; }   /* would crowd the small-screen verdict */
    }
    @media (prefers-reduced-motion: reduce) {
      .verdict-stamp { animation: none; filter: blur(0.4px); }
    }

    /* ────────────────────────────────────────────────────────────────
       AUDIT CHAIN ENTRY ANIMATION
       Each event panel fades up in sequence (the chain "lays itself
       down"), and within each panel the row_hash glyph types in via a
       width-clipping animation. Reads as the registry being written
       in real time — fits the audit-chain aesthetic. Staggered via
       inline --i custom property (0..N) set in the template.
       ──────────────────────────────────────────────────────────────── */
    @keyframes mw-chain-in {
      from { opacity: 0; transform: translateY(8px); }
      to   { opacity: 1; transform: translateY(0); }
    }
    @keyframes mw-hash-type {
      from { clip-path: inset(0 100% 0 0); }
      to   { clip-path: inset(0 0 0 0); }
    }
    .chain-row {
      animation: mw-chain-in 520ms cubic-bezier(0.2, 0.7, 0.2, 1) both;
      animation-delay: calc(var(--i, 0) * 90ms + 120ms);
      position: relative;
    }
    .chain-row::before {
      /* a hairline tick that connects rows visually — a slim leading
         rule between consecutive cards, like the index lines of a ledger */
      content: '';
      position: absolute;
      top: -0.6rem;
      inset-inline-start: 1.25rem;
      width: 1px;
      height: 0.6rem;
      background: var(--rule-deep);
      opacity: 0;
      animation: mw-chain-in 520ms ease both;
      animation-delay: calc(var(--i, 0) * 90ms + 60ms);
    }
    .chain-row:first-child::before { display: none; }
    .chain-hash {
      display: inline-block;
      overflow: hidden;
      vertical-align: bottom;
      animation: mw-hash-type 700ms cubic-bezier(0.7, 0, 0.3, 1) both;
      animation-delay: calc(var(--i, 0) * 90ms + 380ms);
    }
    @media (prefers-reduced-motion: reduce) {
      .chain-row, .chain-row::before, .chain-hash { animation: none; }
    }

    /* ────────────────────────────────────────────────────────────────
       EMPTY STATE — for ledgers with zero records.
       A stamped 'no entries on this register' card that uses the
       brand's registry-form language: hairline frame, an inset paper
       stamp at the top, a single line of copy, an optional hint, and
       an optional CTA. Looks like a blank registry page, not a 404.
       ──────────────────────────────────────────────────────────────── */
    .empty-state {
      display: grid;
      justify-items: center;
      gap: 1.25rem;
      padding: clamp(3rem, 6vw, 5rem) clamp(1.5rem, 3vw, 2.5rem);
      text-align: center;
      background:
        repeating-linear-gradient(
          to bottom,
          transparent 0,
          transparent 28px,
          oklch(0.88 0.010 152 / 0.45) 28px,
          oklch(0.88 0.010 152 / 0.45) 29px
        ),
        var(--paper-warm);
      border: 1px solid var(--rule);
      border-radius: 2px;
      position: relative;
      color: var(--ink);
      animation: mw-page-in 420ms cubic-bezier(0.2, 0.7, 0.2, 1) both;
    }
    .empty-state::before,
    .empty-state::after {
      /* faint margin marks — the binder holes / clip notches of a ledger */
      content: '';
      position: absolute;
      top: 1.5rem;
      width: 7px;
      height: 7px;
      border-radius: 50%;
      background: var(--rule-deep);
      opacity: 0.45;
    }
    .empty-state::before { inset-inline-start: 1.5rem; }
    .empty-state::after  { inset-inline-end:   1.5rem; }
    .empty-state-mark {
      display: inline-flex;
      align-items: center;
      gap: 0.55rem;
      padding: 0.4rem 0.85rem;
      border: 1.5px solid var(--brand);
      border-radius: 999px;
      color: var(--brand);
      font-size: 0.6875rem;
      font-weight: 700;
      letter-spacing: 0.18em;
      text-transform: uppercase;
      transform: rotate(-2deg);
      background: var(--paper);
    }
    .empty-state-title {
      font-size: clamp(1.25rem, 2.2vw, 1.75rem);
      font-weight: 600;
      letter-spacing: -0.015em;
      max-width: 26ch;
      color: var(--ink);
    }
    .empty-state-hint {
      font-size: 0.9375rem;
      color: var(--ink-muted);
      max-width: 48ch;
      line-height: 1.55;
    }
    .empty-state-cta {
      margin-top: 0.5rem;
    }

    /* Verdict band — used on the decision page header. (See above for the full block.) */
    .verdict-headline {
      font: 500 clamp(2.5rem, 5vw, 4rem)/0.98 'IBM Plex Sans', system-ui, sans-serif;
      letter-spacing: -0.032em;
      color: currentColor;
    }
    .verdict-ar {
      font: 500 clamp(1.5rem, 2.4vw, 2rem)/1.4 'IBM Plex Sans', system-ui, sans-serif;
      direction: rtl;
      unicode-bidi: isolate;
      color: currentColor;
      opacity: 0.78;
    }

    /* ────────────────────────────────────────────────────────────────
       META GRID — KV pairs used on decision / audit cards.
       ──────────────────────────────────────────────────────────────── */
    .kv-grid {
      display: grid;
      grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
      gap: 1.5rem 2rem;
    }
    .kv-label {
      font: 600 0.6875rem/1 'IBM Plex Sans', system-ui, sans-serif;
      letter-spacing: 0.14em;
      text-transform: uppercase;
      color: var(--ink-faint);
      margin-bottom: 0.5rem;
      display: block;
    }
    .kv-value { font-size: 0.9375rem; color: var(--ink); line-height: 1.4; }
    .kv-value .ar { color: var(--ink-muted); font-size: 0.8125rem; }

    /* ────────────────────────────────────────────────────────────────
       TIMELINE — vertical audit trail with rail and dots.
       ──────────────────────────────────────────────────────────────── */
    .timeline { position: relative; padding-inline-start: 1.25rem; }
    .timeline::before {
      content: '';
      position: absolute;
      inset-inline-start: 4px;
      top: 6px;
      bottom: 6px;
      width: 1px;
      background: var(--rule-deep);
    }
    .timeline-item { position: relative; padding-bottom: 1.5rem; }
    .timeline-item:last-child { padding-bottom: 0; }
    .timeline-item::before {
      content: '';
      position: absolute;
      inset-inline-start: -1.25rem;
      top: 6px;
      width: 9px;
      height: 9px;
      background: var(--paper);
      border: 1.5px solid var(--ink);
      transform: translateX(-1px);
    }
    .timeline-item.is-pass::before { border-color: var(--state-pass); }
    .timeline-item.is-deny::before { border-color: var(--state-deny); }
    .timeline-item.is-gov::before  { border-color: var(--state-gov); }

    /* ────────────────────────────────────────────────────────────────
       LAYOUT helpers (used sparingly; most layout via Tailwind utilities)
       ──────────────────────────────────────────────────────────────── */
    .wrap { max-width: 1240px; margin-inline: auto; padding-inline: clamp(1.25rem, 4vw, 2.5rem); }
    .wrap-narrow { max-width: 920px; margin-inline: auto; padding-inline: clamp(1.25rem, 4vw, 2.5rem); }

    .hairline      { height: 1px; background: var(--rule); }
    .hairline-ink  { height: 1px; background: var(--ink); }
    .hairline-on   { height: 1px; background: oklch(0.97 0.012 60 / 0.35); }

    /* ────────────────────────────────────────────────────────────────
       NAV
       ──────────────────────────────────────────────────────────────── */


    /* ────────────────────────────────────────────────────────────────
       MOBILE NAV — below md the primary nav collapses behind a
       hamburger. The panel is absolutely anchored to the sticky header
       so opening it overlays the page instead of reflowing it. Links
       stack full-width with the same grouping as the desktop nav.
       ──────────────────────────────────────────────────────────────── */
    .mobile-nav {
      position: absolute;
      top: 100%;
      left: 0; right: 0;
      display: none;
      background: var(--brand-deep);
      color: var(--brand-on);
      border-top: 1px solid oklch(1 0 0 / 0.12);
      box-shadow: 0 22px 32px -18px oklch(0 0 0 / 0.5);
      max-height: calc(100vh - 68px);
      overflow-y: auto;
      z-index: var(--z-sticky);
    }
    .mobile-nav.is-open { display: block; }
    /* Breakpoint split — one rule for everyone: below 900px the compact
       top bar + hamburger panel; at 900px+ the sidebar takes over and the
       mobile chrome is hidden. (display:none here beats tw.css utilities
       of equal specificity because this sheet loads later.) */
    @media (min-width: 900px) {
      .mobile-topbar { display: none !important; }
      #mw-mobile-nav { display: none !important; }
    }

    .mobile-nav-group-label {
      display: block;
      padding: 0.9rem clamp(1.25rem, 2.5vw, 2rem) 0.35rem;
      font: 600 0.625rem/1 'IBM Plex Sans', system-ui, sans-serif;
      letter-spacing: 0.18em;
      text-transform: uppercase;
      color: var(--brand-on-fa);
    }
    .mobile-nav-link {
      display: flex;
      align-items: center;
      gap: 0.7rem;
      padding: 0.8rem clamp(1.25rem, 2.5vw, 2rem);
      font-size: 0.9375rem;
      font-weight: 500;
      color: var(--brand-on-mu);
      border-bottom: 1px solid oklch(1 0 0 / 0.07);
      text-decoration: none;
    }
    .mobile-nav-link:hover { color: var(--brand-on); background: oklch(1 0 0 / 0.05); }
    .mobile-nav-link.active {
      color: var(--brand-on);
      box-shadow: inset 3px 0 0 var(--brand-on);
    }
    html[dir="rtl"] .mobile-nav-link.active { box-shadow: inset -3px 0 0 var(--brand-on); }

    /* ────────────────────────────────────────────────────────────────
       SMALL-SCREEN LEDGERS — below md every multi-column register row
       (annotated with .mw-card-row) collapses from its inline
       grid-template-columns spec into a wrapping card so no value is
       crushed to an unreadable sliver:
         .mw-full-sm  cell takes its own full line
         .mw-push-sm  cell rides the end of its line
         .mw-hide-sm  cell (or the column-header row) is dropped —
                      only for values repeated in the expanded detail
       The !important display flips are deliberate: they must beat both
       the Tailwind .grid class and the per-page inline column specs.
       ──────────────────────────────────────────────────────────────── */
    @media (max-width: 767px) {
      .mw-hide-sm { display: none !important; }
      .mw-card-row {
        display: flex !important;
        flex-wrap: wrap;
        align-items: baseline;
        gap: 0.3rem 0.75rem;
        padding-block: 0.9rem;
      }
      .mw-card-row > * { min-width: 0; }
      .mw-full-sm { flex-basis: 100%; }
      .mw-push-sm { margin-inline-start: auto; }

      /* Page header — the meta column drops under the title instead of
         squeezing it from the side. */
      .page-head { grid-template-columns: 1fr; align-items: start; }
      .page-meta { text-align: start; margin-top: 0.35rem; }
    }

    .role-select {
      appearance: none;
      background: transparent;
      color: var(--brand-on);
      border: 1px solid oklch(0.97 0.012 60 / 0.35);
      border-radius: 1px;
      padding: 0.375rem 1.5rem 0.375rem 0.625rem;
      font-size: 0.75rem;
      font-weight: 500;
      letter-spacing: 0.02em;
      background-image: url("data:image/svg+xml,%3Csvg width='8' height='5' viewBox='0 0 8 5' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M1 1l3 3 3-3' stroke='%23F5FAF7' fill='none' stroke-width='1.4'/%3E%3C/svg%3E");
      background-repeat: no-repeat;
      background-position: right 0.5rem center;
      color-scheme: dark;
    }
    .role-select option { background: var(--brand-deep); color: var(--brand-on); }
    .role-select:focus { outline: none; border-color: var(--brand-on); }

    /* Language toggle pill — two segments, the active one inverted. */
    .lang-toggle {
      display: inline-flex;
      border: 1px solid oklch(0.97 0.012 60 / 0.35);
      border-radius: 999px;
      overflow: hidden;
      background: transparent;
    }
    .lang-toggle button {
      font: 600 0.6875rem/1 'IBM Plex Sans', system-ui, sans-serif;
      letter-spacing: 0.08em;
      color: var(--brand-on-mu);
      background: transparent;
      border: 0;
      padding: 0.35rem 0.7rem;
      cursor: pointer;
      transition: background-color 120ms ease, color 120ms ease;
    }
    .lang-toggle button:hover { color: var(--brand-on); }
    .lang-toggle button.is-active {
      background: var(--brand-on);
      color: var(--brand-deep);
    }

    /* ────────────────────────────────────────────────────────────────
       FIELD HELP POPOVER — a single floating chip that follows focus
       on text inputs / textareas and hover on <select> elements.
       Drives from data-help (required) and data-help-example (optional)
       on the input. Vanishes the moment the field has a value, so once
       the user types or picks an option the chrome gets out of the way.
       Position is set in JS via top/left and one of these orientation
       classes (so the arrow lands on the correct edge).
       ──────────────────────────────────────────────────────────────── */
    .field-help {
      position: fixed;
      top: 0; left: 0;
      max-width: 280px;
      min-width: 180px;
      padding: 0.7rem 0.85rem;
      background: var(--ink);
      color: var(--paper);
      font-family: 'IBM Plex Sans', system-ui, sans-serif;
      font-size: 0.8125rem;
      line-height: 1.45;
      letter-spacing: 0.005em;
      border-radius: 8px;
      box-shadow:
        0 1px 2px oklch(0.18 0.012 155 / 0.20),
        0 12px 28px -12px oklch(0.18 0.012 155 / 0.45);
      z-index: var(--z-toast);
      pointer-events: none;
      opacity: 0;
      visibility: hidden;
      transform: translate(-4px, 0);
      transition:
        opacity 160ms ease,
        transform 160ms ease,
        visibility 0s linear 160ms;
    }
    .field-help.is-on {
      opacity: 1;
      visibility: visible;
      transform: translate(0, 0);
      transition-delay: 0s;
    }
    .field-help.is-left  { transform: translate(4px, 0); }     /* incoming-from-right slide */
    .field-help.is-left.is-on { transform: translate(0, 0); }

    .field-help-text {
      display: block;
      font-weight: 500;
    }
    .field-help-example {
      display: block;
      margin-top: 0.45rem;
      padding-top: 0.45rem;
      border-top: 1px solid oklch(1 0 0 / 0.14);
      font-size: 0.75rem;
      font-weight: 500;
      letter-spacing: 0.02em;
      color: oklch(1 0 0 / 0.80);
    }
    .field-help-example::before {
      content: 'e.g. ';
      letter-spacing: 0.08em;
      text-transform: uppercase;
      font-size: 0.68rem;
      font-weight: 600;
      opacity: 0.55;
      margin-inline-end: 0.35rem;
    }
    html[dir="rtl"] .field-help-example::before { content: 'مثال: '; }

    /* Arrow — a small triangle that visually anchors the chip to its
       field. Rendered as a rotated square so border-radius doesn't
       break it. Placed on the side opposite the chip's offset. */
    .field-help::after {
      content: '';
      position: absolute;
      width: 10px;
      height: 10px;
      background: var(--ink);
      transform: rotate(45deg);
      top: 50%;
      margin-top: -5px;
      inset-inline-start: -4px;
      border-bottom-left-radius: 2px;
    }
    .field-help.is-left::after {
      inset-inline-start: auto;
      inset-inline-end: -4px;
      border-bottom-left-radius: 0;
      border-top-right-radius: 2px;
    }
    /* Vertical-anchor variant: when there's no horizontal room, the chip
       drops below the field and the arrow swings to the top edge. */
    .field-help.is-below::after {
      top: -4px;
      margin-top: 0;
      left: 18px;
      inset-inline-start: 18px;
      inset-inline-end: auto;
    }
    @media (prefers-reduced-motion: reduce) {
      .field-help { transition: opacity 0s, visibility 0s; transform: none; }
    }

    /* ────────────────────────────────────────────────────────────────
       TOOLTIP — CSS-only, attached via data-tip="..." (no JS).
       Renders a small dark chip below the trigger after a short hover
       delay; appears on keyboard focus too. Stays inside the viewport
       via the data-tip-align="end|start" modifier when needed.
       ──────────────────────────────────────────────────────────────── */
    [data-tip] { position: relative; }
    [data-tip]::after {
      content: attr(data-tip);
      position: absolute;
      top: calc(100% + 8px);
      inset-inline-start: 50%;
      transform: translateX(-50%) translateY(-2px);
      background: var(--ink);
      color: var(--paper);
      font-family: 'IBM Plex Sans', system-ui, sans-serif;
      font-size: 0.6875rem;
      font-weight: 500;
      letter-spacing: 0.02em;
      line-height: 1.25;
      padding: 0.4rem 0.6rem;
      border-radius: 4px;
      white-space: nowrap;
      max-width: 18rem;
      pointer-events: none;
      opacity: 0;
      visibility: hidden;
      transition: opacity 120ms ease 0s, transform 120ms ease 0s, visibility 0s linear 120ms;
      z-index: var(--z-toast);
      box-shadow: 0 6px 16px -6px oklch(0.18 0.012 155 / 0.35);
    }
    html[dir="rtl"] [data-tip]::after {
      transform: translateX(50%) translateY(-2px);
    }
    [data-tip]:hover::after,
    [data-tip]:focus-visible::after {
      opacity: 1;
      visibility: visible;
      transform: translateX(-50%) translateY(0);
      transition-delay: 350ms, 350ms, 0s;
    }
    html[dir="rtl"] [data-tip]:hover::after,
    html[dir="rtl"] [data-tip]:focus-visible::after {
      transform: translateX(50%) translateY(0);
    }
    /* Right-anchor variant so tooltips near the right edge stay on-screen. */
    [data-tip][data-tip-align="end"]::after {
      inset-inline-start: auto;
      inset-inline-end: 0;
      transform: translateY(-2px);
    }
    [data-tip][data-tip-align="end"]:hover::after,
    [data-tip][data-tip-align="end"]:focus-visible::after {
      transform: translateY(0);
    }
    /* Left-anchor variant. */
    [data-tip][data-tip-align="start"]::after {
      inset-inline-start: 0;
      transform: translateY(-2px);
    }
    [data-tip][data-tip-align="start"]:hover::after,
    [data-tip][data-tip-align="start"]:focus-visible::after {
      transform: translateY(0);
    }
    /* Above-trigger variant — for footer-anchored controls. */
    [data-tip][data-tip-side="top"]::after {
      top: auto;
      bottom: calc(100% + 8px);
    }
    @media (prefers-reduced-motion: reduce) {
      [data-tip]::after { transition: none; }
    }

    /* ────────────────────────────────────────────────────────────────
       LOADERS — spinner, skeleton, top-of-page nav progress bar.
       Skeletons reuse the paper-sunk colour so they sit in the page
       without flashing. Spinners use currentColor so they tint to
       whatever button or surface they're embedded in.
       ──────────────────────────────────────────────────────────────── */
    @keyframes mw-spin { to { transform: rotate(360deg); } }
    @keyframes mw-skel {
      0%   { background-position: 100% 0; }
      100% { background-position: -100% 0; }
    }
    @keyframes mw-bar {
      0%   { transform: translateX(-100%); }
      60%  { transform: translateX(20%); }
      100% { transform: translateX(100%); }
    }

    .spinner {
      display: inline-block;
      width: 1rem;
      height: 1rem;
      border: 2px solid currentColor;
      border-right-color: transparent;
      border-radius: 50%;
      animation: mw-spin 720ms linear infinite;
      vertical-align: -0.18em;
    }
    .spinner-sm { width: 0.75rem; height: 0.75rem; border-width: 1.5px; }
    .spinner-lg { width: 1.5rem;  height: 1.5rem;  border-width: 2.5px; }

    /* Page-level loader used on long-running screens (verdict computing,
       chain verifying, large list mount). Centered, with a caption slot. */
    .loader-block {
      display: grid;
      place-items: center;
      gap: 0.85rem;
      padding: clamp(2rem, 5vw, 3.5rem) 1rem;
      color: var(--ink-muted);
      font-size: 0.8125rem;
      letter-spacing: 0.02em;
    }
    .loader-block .spinner { color: var(--brand); }

    /* Skeleton — shimmer-on-sunken-paper. Use .skel as a placeholder shape;
       size via Tailwind width/height utilities or inline width/height. */
    .skel {
      display: block;
      background: linear-gradient(
        90deg,
        var(--paper-sunk) 0%,
        oklch(0.99 0.005 145) 50%,
        var(--paper-sunk) 100%
      );
      background-size: 200% 100%;
      animation: mw-skel 1400ms ease-in-out infinite;
      border-radius: 4px;
      min-height: 0.85rem;
      color: transparent !important;
      user-select: none;
      pointer-events: none;
    }
    .skel-line   { height: 0.85rem; width: 100%; }
    .skel-line-sm{ height: 0.65rem; width: 60%; }
    .skel-title  { height: 1.4rem;  width: 50%; }
    .skel-circle { border-radius: 50%; }
    .skel-card   { height: 8rem; border-radius: 12px; }

    /* Skeleton row inside the ledger — matches the row anatomy so the
       layout doesn't jump when real data lands. */
    .skel-row {
      display: grid;
      grid-template-columns: minmax(0,1.6fr) minmax(0,1fr) minmax(0,1fr) 6rem;
      gap: 1.5rem;
      padding: 1rem 0;
      border-bottom: 1px solid var(--rule);
      align-items: center;
    }

    /* Submit-disabled state used by the form-loader JS hook below. */
    .is-loading[disabled],
    [data-loading-form].is-submitting button[type="submit"],
    [data-loading-form].is-submitting .btn,
    [data-loading-form].is-submitting .btn-go {
      opacity: 0.7;
      cursor: progress;
      pointer-events: none;
    }
    [data-loading-form].is-submitting button[type="submit"] .btn-label,
    [data-loading-form].is-submitting .btn .btn-label,
    [data-loading-form].is-submitting .btn-go .btn-label {
      visibility: hidden;
    }
    /* When a button is mid-submit, we drop a centered spinner over it. */
    .btn, .btn-go { position: relative; }
    [data-loading-form].is-submitting .btn::after,
    [data-loading-form].is-submitting .btn-go::after {
      content: '';
      position: absolute;
      top: 50%; left: 50%;
      width: 1rem; height: 1rem;
      margin: -0.5rem 0 0 -0.5rem;
      border: 2px solid currentColor;
      border-right-color: transparent;
      border-radius: 50%;
      animation: mw-spin 720ms linear infinite;
    }

    /* Top-of-page navigation progress bar (fires on link clicks / form
       submits, hidden after pageshow). Pure CSS animation; JS only adds
       the .is-on class to start it. */
    .nav-progress {
      position: fixed;
      top: 0; left: 0; right: 0;
      height: 2px;
      background: transparent;
      z-index: var(--z-toast);
      pointer-events: none;
      overflow: hidden;
    }
    .nav-progress::before {
      content: '';
      position: absolute;
      inset: 0;
      background: linear-gradient(
        90deg,
        transparent,
        var(--brand) 30%,
        var(--brand-soft) 60%,
        transparent
      );
      transform: translateX(-100%);
    }
    .nav-progress.is-on::before {
      animation: mw-bar 900ms ease-in-out infinite;
    }

    @media (prefers-reduced-motion: reduce) {
      .spinner, .skel, .nav-progress.is-on::before { animation: none; }
      .skel { background: var(--paper-sunk); }
    }

    /* ────────────────────────────────────────────────────────────────
       PAGE TRANSITIONS — native cross-document View Transitions where
       supported (Chrome/Edge/Safari ≥18), graceful CSS fade-up fallback
       everywhere else (gated behind @supports so motion never doubles).

       One motion language, three dialects — the DESTINATION's
       data-vt-zone on <html> (set server-side from the route) picks the
       choreography, so every kind of movement through the app reads
       differently:

         desk    · passenger flow — inline "page-turn": the next form is
                   slid across the counter. Axis honours the reading
                   direction (--vt-x flips under RTL) and reverses on
                   history back-traversal (--vt-flow, set by the
                   pagereveal handler in <head>).
         verdict · decision & contact-gov — "the settle": the incoming
                   document starts a hair oversized and settles flat
                   onto the desk. Slower on purpose; the verdict-stamp
                   animation then lands on top of a still page.
         ledger  · admin & audit — "drawer riffle": a short block-axis
                   slide, quick and clerical.

       Same-path navigations (language switch, form re-renders) crossfade
       only — movement would lie about where the user went.
       Sticky header stays fixed across all of it (own snapshot group).
       ──────────────────────────────────────────────────────────────── */
    @view-transition { navigation: auto; }

    :root {
      --vt-x: 1;        /* inline axis sign — flipped by dir="rtl" */
      --vt-flow: 1;     /* -1 on back-traversal (data-vt-dir="back") */
      --vt-ease-out: cubic-bezier(0.55, 0, 0.58, 0.24); /* exits: accelerate away */
      --vt-ease-in:  cubic-bezier(0.16, 1, 0.3, 1);     /* entries: long settle */
    }
    html[dir="rtl"] { --vt-x: -1; }
    html[data-vt-dir="back"] { --vt-flow: -1; }

    /* desk — inline page-turn (the default zone) */
    @keyframes mw-vt-desk-out {
      to { opacity: 0; transform: translateX(calc(var(--vt-x) * var(--vt-flow) * -18px)); }
    }
    @keyframes mw-vt-desk-in {
      from { opacity: 0; transform: translateX(calc(var(--vt-x) * var(--vt-flow) * 26px)); }
    }
    ::view-transition-old(root) {
      animation: mw-vt-desk-out 160ms var(--vt-ease-out) both;
    }
    ::view-transition-new(root) {
      animation: mw-vt-desk-in 300ms var(--vt-ease-in) both;
    }

    /* verdict — the settle */
    @keyframes mw-vt-verdict-out {
      to { opacity: 0; }
    }
    @keyframes mw-vt-verdict-in {
      from { opacity: 0; transform: scale(1.015) translateY(calc(var(--vt-flow) * 6px)); }
    }
    html[data-vt-zone="verdict"]::view-transition-old(root) {
      animation: mw-vt-verdict-out 200ms ease both;
    }
    html[data-vt-zone="verdict"]::view-transition-new(root) {
      animation: mw-vt-verdict-in 380ms var(--vt-ease-in) both;
    }

    /* ledger — drawer riffle */
    @keyframes mw-vt-ledger-out {
      to { opacity: 0; transform: translateY(calc(var(--vt-flow) * -8px)); }
    }
    @keyframes mw-vt-ledger-in {
      from { opacity: 0; transform: translateY(calc(var(--vt-flow) * 12px)); }
    }
    html[data-vt-zone="ledger"]::view-transition-old(root) {
      animation: mw-vt-ledger-out 130ms var(--vt-ease-out) both;
    }
    html[data-vt-zone="ledger"]::view-transition-new(root) {
      animation: mw-vt-ledger-in 240ms var(--vt-ease-in) both;
    }

    /* Same-path navigation — crossfade only. Declared last so it wins
       the equal-specificity contest against the zone rules above. */
    html[data-vt-same]::view-transition-old(root) {
      animation: mw-vt-verdict-out 140ms ease both;
    }
    html[data-vt-same]::view-transition-new(root) {
      animation: mw-vt-fade-in 200ms ease both;
    }
    @keyframes mw-vt-fade-in {
      from { opacity: 0; }
    }

    /* Pin the persistent chrome so it doesn't re-animate — only the page
       beneath moves. Each piece has a stable, identical viewport box on
       every route, which is what makes freezing it safe:
         · mw-side   — the desktop left rail (.app-side, sticky full-height,
                       shown ≥900px). Without this it rides inside the root
                       snapshot and slides/fades on every navigation.
         · mw-header — the mobile sticky top bar (shown <900px).
         · mw-progress — the top-of-page loading bar.
       On viewports where a piece is display:none it has no box, so its
       freeze rule is simply inert — desktop and mobile never both apply. */
    .app-side { view-transition-name: mw-side; }
    header.surface-brand-deep { view-transition-name: mw-header; }
    .nav-progress { view-transition-name: mw-progress; }
    ::view-transition-group(mw-side),
    ::view-transition-group(mw-header),
    ::view-transition-group(mw-progress) {
      animation-duration: 0ms;
    }

    /* Fallback page-in for browsers without View Transitions (Firefox at
       time of writing). Gated so supporting browsers don't run BOTH the
       snapshot slide and this one — that would double every offset.
       (mw-page-in stays global: .empty-state reuses it.) */
    @keyframes mw-page-in {
      from { opacity: 0; transform: translateY(6px); }
      to   { opacity: 1; transform: translateY(0); }
    }
    @supports not (view-transition-name: none) {
      main { animation: mw-page-in 320ms cubic-bezier(0.2, 0.7, 0.2, 1) both; }
    }

    @media (prefers-reduced-motion: reduce) {
      ::view-transition-old(root),
      ::view-transition-new(root),
      html[data-vt-zone]::view-transition-old(root),
      html[data-vt-zone]::view-transition-new(root) { animation: none; }
      main { animation: none; }
    }

    /* ────────────────────────────────────────────────────────────────
       HERO REVEAL — one deliberate animation per Design Principle #5.
       Latin lands, Arabic follows; equal voice in two beats.
       Page is fully visible without it (no opacity:0 gate).
       ──────────────────────────────────────────────────────────────── */
    @keyframes lift {
      from { transform: translateY(6px); opacity: 0.6; }
      to   { transform: translateY(0); opacity: 1; }
    }
    .lift     { animation: lift 600ms cubic-bezier(0.2, 0.7, 0.2, 1) both; }
    .lift-1   { animation-delay: 80ms; }
    .lift-2   { animation-delay: 280ms; }
    .lift-3   { animation-delay: 460ms; }

    @media (prefers-reduced-motion: reduce) {
      .lift, .lift-1, .lift-2, .lift-3 { animation: none; }
      * { transition: none !important; }
    }

    /* ────────────────────────────────────────────────────────────────
       FOCUS — visible, on-brand, never browser default only.
       ──────────────────────────────────────────────────────────────── */
    :focus-visible {
      outline: 2px solid var(--brand);
      outline-offset: 2px;
    }

    /* Skip link (WCAG 2.4.1) — parked above the viewport until focused. */
    .skip-link {
      position: absolute;
      inset-inline-start: 1rem;
      top: -3.5rem;
      z-index: var(--z-toast);
      padding: 0.6rem 1rem;
      background: var(--ink);
      color: var(--paper);
      font-size: 0.8125rem;
      text-decoration: none;
      border-radius: 0 0 6px 6px;
      transition: top 120ms ease;
    }
    .skip-link:focus {
      top: 0;
      outline: 2px solid var(--brand-on);
      outline-offset: -4px;
    }
    .surface-brand :focus-visible,
    .surface-brand-deep :focus-visible {
      outline-color: var(--brand-on);
    }

    a { color: inherit; }
    a.link {
      color: var(--brand);
      text-decoration: underline;
      text-underline-offset: 3px;
      text-decoration-thickness: 1px;
      text-decoration-color: var(--rule-deep);
    }
    a.link:hover { text-decoration-color: var(--brand); }

    /* ────────────────────────────────────────────────────────────────
       Logo seal — recoloured to read on either surface via currentColor.
       ──────────────────────────────────────────────────────────────── */
    .seal { display: inline-block; color: currentColor; }
    .seal-nav { width: 30px; height: 36px; }

    /* Header mark — the shield + scales from the official logo, no
       wordmark. The live header supplies the Arabic / Latin label next
       to it in the active language, so the SVG stays mark-only. Sized
       a touch larger than the previous seal so the new logo's finer
       scale detail (pans, stepped pedestal) reads cleanly. */
    .header-mark {
      display: inline-block;
      width: 38px;
      height: 40px;
      color: currentColor;
      flex-shrink: 0;
    }

    /* ────────────────────────────────────────────────────────────────
       APP DIALOG — replaces window.confirm()/alert() console-wide.
       Native <dialog> for focus trap + Escape; styled as registry paper.
       ──────────────────────────────────────────────────────────────── */
    dialog.mw-dialog {
      border: 1px solid var(--rule);
      border-radius: 8px;
      padding: 1.5rem;
      width: min(92vw, 28rem);
      background: var(--paper);
      color: var(--ink);
      box-shadow: 0 24px 60px oklch(0.18 0.012 155 / 0.18);
    }
    dialog.mw-dialog::backdrop { background: oklch(0.18 0.012 155 / 0.45); }
    dialog.mw-dialog[open] { animation: mw-dialog-in 160ms ease-out; }
    @keyframes mw-dialog-in {
      from { opacity: 0; transform: translateY(6px); }
      to   { opacity: 1; transform: none; }
    }
    @media (prefers-reduced-motion: reduce) {
      dialog.mw-dialog[open] { animation: none; }
    }

    /* ────────────────────────────────────────────────────────────────
       INLINE SVG ICON SYSTEM — server-side sprite, no CDN dependency.
       Icons are <svg><use href="#icon-name"></svg> rendered by the
       icon() macro from _macros.html. Inherits currentColor so they
       adapt to any surface automatically.
       Size with .ico-* or Tailwind width/height utilities.
       ──────────────────────────────────────────────────────────────── */
    .ico   { width: 1rem;     height: 1rem;     stroke-width: 1.75; vertical-align: -0.15em; flex-shrink: 0; }
    .ico-sm{ width: 0.875rem; height: 0.875rem; stroke-width: 1.75; vertical-align: -0.15em; flex-shrink: 0; }
    .ico-lg{ width: 1.25rem;  height: 1.25rem;  stroke-width: 1.75; vertical-align: -0.18em; flex-shrink: 0; }
    .ico-xl{ width: 1.5rem;   height: 1.5rem;   stroke-width: 1.75; vertical-align: -0.2em;  flex-shrink: 0; }
    /* In RTL, directional glyphs (arrow-right, chevron-right) flip to
       match reading flow. Target the <svg> inside .ico-* wrappers whose
       use-href ends in "-right". */
    html[dir="rtl"] .ico-sm[class*="right"] use,
    html[dir="rtl"] .ico[class*="right"] use { transform: scaleX(-1); }
    html[dir="rtl"] #icon-arrow-right use,
    html[dir="rtl"] #icon-chevron-right use,
    html[dir="rtl"] #icon-move-right use { transform: scaleX(-1); }
    html[dir="rtl"] svg.ico-sm:has(use[href="#icon-arrow-right"]),
    html[dir="rtl"] svg.ico-sm:has(use[href="#icon-chevron-right"]),
    html[dir="rtl"] svg.ico-sm:has(use[href="#icon-move-right"]),
    html[dir="rtl"] svg.ico:has(use[href="#icon-arrow-right"]),
    html[dir="rtl"] svg.ico:has(use[href="#icon-chevron-right"]),
    html[dir="rtl"] svg.ico:has(use[href="#icon-move-right"]) { transform: scaleX(-1); }

    /* Orange unread-count badge on the Inbox nav link. Rendered
       server-side (ctx.inbox_unread) and kept live by polling
       /admin/inbox/feed.json — see the inline script near the footer. */
    .inbox-dot{
      display:inline-flex; align-items:center; justify-content:center;
      min-width:1.05rem; height:1.05rem; padding:0 0.28rem;
      border-radius:999px; background:#E8730C; color:#fff;
      font-size:0.625rem; font-weight:700; line-height:1;
      font-variant-numeric: tabular-nums;
      margin-inline-start:0.2rem;
    }
    .inbox-dot[hidden]{ display:none; }

    /* ────────────────────────────────────────────────────────────────
       CLERICAL NOTICE — boxed, square-cornered, full hairline border.
       (Deliberately NOT the rounded-card-with-accent-side-border
       pattern; a notice on this surface reads as a stamped slip.)
       ──────────────────────────────────────────────────────────────── */
    .notice {
      border: 1px solid var(--rule-deep);
      background: var(--paper);
      color: var(--ink);
      padding: 0.75rem 1rem;
      font-size: 0.875rem;
      line-height: 1.5;
    }
    .notice-deny {
      border-color: var(--state-deny);
      background: var(--state-deny-tint);
    }

    /* ────────────────────────────────────────────────────────────────
       INBOX — filter tabs + wait-age chips (list page).
       ──────────────────────────────────────────────────────────────── */
    .inbox-tabs {
      display: flex;
      gap: 0;
      border-bottom: 1.5px solid var(--rule);
      margin-bottom: 1.5rem;
      overflow-x: auto;
    }
    .inbox-tab {
      display: inline-flex;
      align-items: baseline;
      gap: 0.45rem;
      padding: 0.6rem 1rem 0.55rem;
      font: 600 0.78rem/1 'IBM Plex Sans', system-ui, sans-serif;
      letter-spacing: 0.04em;
      color: var(--ink-muted);
      text-decoration: none;
      border-bottom: 2px solid transparent;
      margin-bottom: -1.5px;
      white-space: nowrap;
      transition: color 120ms ease, border-color 120ms ease;
    }
    .inbox-tab:hover { color: var(--ink); }
    .inbox-tab.is-active {
      color: var(--ink);
      border-bottom-color: var(--brand);
    }
    .inbox-tab-count {
      font: 600 0.68rem/1 'IBM Plex Mono', ui-monospace, monospace;
      font-feature-settings: 'tnum';
      padding: 0.1rem 0.4rem;
      border-radius: 2px;
      background: var(--paper-warm);
      color: var(--ink-faint);
      border: 1px solid var(--rule);
    }
    .inbox-tab.is-active .inbox-tab-count {
      background: var(--brand);
      color: var(--brand-on);
      border-color: var(--brand);
    }
    .inbox-tabs-note {
      margin-inline-start: auto;
      align-self: center;
      font-size: 0.6875rem;
      text-transform: uppercase;
      letter-spacing: 0.12em;
      color: var(--ink-faint);
      padding-inline-start: 1rem;
      white-space: nowrap;
    }

    /* Wait-age chip — how long an unresolved case has been sitting.
       Filled in client-side; .is-hot past the 30-minute SLA. */
    .inbox-age {
      font: 600 0.68rem/1 'IBM Plex Mono', ui-monospace, monospace;
      font-variant-numeric: tabular-nums;
      color: var(--ink-faint);
      padding-inline-start: 0.5rem;
    }
    .inbox-age.is-hot {
      color: var(--state-deny);
    }

    /* ────────────────────────────────────────────────────────────────
       APP SIDEBAR — desktop navigation (≥900px). Vertical, grouped,
       one selection theme per category via --grp. The aside sits at
       the inline-start edge, so it lands on the right automatically
       under dir="rtl".
       ──────────────────────────────────────────────────────────────── */
    .app-side { display: none; }
    @media (min-width: 900px) {
      .app-side {
        display: flex;
        flex-direction: column;
        width: 250px;
        flex: none;
        position: sticky;
        top: 0;
        height: 100dvh;
        overflow-y: auto;
        overflow-x: hidden;
        background: var(--brand-deep);
        color: var(--brand-on);
        padding: 1rem 0.8rem;
        border-inline-end: 1px solid oklch(1 0 0 / 0.08);
        z-index: var(--z-sticky);
        /* Keep the rail vertically scrollable on short screens but hide the
           scrollbar chrome; kill horizontal scroll from long labels. */
        scrollbar-width: none;
        transition: width 160ms ease, padding 160ms ease;
      }
      .app-side::-webkit-scrollbar { width: 0; height: 0; }
      @media (prefers-reduced-motion: reduce) {
        .app-side { transition: none; }
      }
    }
    .side-top {
      display: flex; align-items: center; justify-content: space-between;
      gap: 0.25rem;
      margin-bottom: 0.9rem;
      border-bottom: 1px solid oklch(1 0 0 / 0.12);
    }
    .side-brand {
      display: flex; align-items: center; gap: 0.7rem;
      color: var(--brand-on); text-decoration: none;
      padding: 0.4rem 0.65rem 1rem;
      min-width: 0;
    }
    .side-collapse {
      display: inline-flex; align-items: center; justify-content: center;
      width: 1.9rem; height: 1.9rem; flex: none;
      margin-bottom: 0.6rem;
      border: 0; border-radius: 8px;
      background: transparent; color: var(--brand-on-mu);
      cursor: pointer;
      transition: color 140ms ease, background 140ms ease;
    }
    .side-collapse:hover { color: var(--brand-on); background: oklch(1 0 0 / 0.06); }
    .side-collapse .side-collapse-open { display: none; }
    /* The panel glyph is drawn for a left rail — mirror it when the rail
       sits on the right under dir="rtl". */
    html[dir="rtl"] .side-collapse .ico-sm { transform: scaleX(-1); }
    .side-nav { display: flex; flex-direction: column; }

    /* Category themes — each group's selection accent. */
    .side-group[data-theme="desk"]      { --grp: oklch(0.80 0.13 152); }  /* moss */
    .side-group[data-theme="cases"]     { --grp: oklch(0.82 0.12 75);  }  /* amber */
    .side-group[data-theme="reference"] { --grp: oklch(0.78 0.09 245); }  /* slate blue */
    .side-group[data-theme="system"]    { --grp: oklch(0.86 0.02 152); }  /* neutral */

    .side-group {
      margin-bottom: 1.15rem;
    }

    .side-group-label {
      display: block;
      font-size: 0.625rem; font-weight: 600;
      letter-spacing: 0.18em; text-transform: uppercase;
      color: var(--brand-on-fa);
      padding: 0 0.65rem 0.5rem;
    }
    .side-link {
      position: relative;
      display: flex; align-items: center; gap: 0.6rem;
      padding: 0.5rem 0.65rem;
      border-radius: 8px;
      font-size: 0.8125rem; font-weight: 500; letter-spacing: 0.02em;
      color: var(--brand-on-mu); text-decoration: none; white-space: nowrap;
      transition: color 140ms ease, background 140ms ease,
                  padding-inline-start 160ms ease;
    }
    .side-link:hover {
      color: var(--brand-on);
      background: oklch(1 0 0 / 0.06);
      padding-inline-start: 0.9rem;
    }
    .side-link.active {
      color: var(--brand-on);
      font-weight: 600;
      background: color-mix(in oklab, var(--grp, var(--brand-on)) 20%, transparent);
    }
    .side-link.active .ico-sm { color: var(--grp, currentColor); }
    .side-link.active::before {
      content: '';
      position: absolute;
      inset-inline-start: -0.8rem;   /* hugs the sidebar edge (its padding) */
      top: 22%; bottom: 22%;
      width: 3px; border-radius: 0 3px 3px 0;
      background: var(--grp, var(--brand-on));
    }
    @media (prefers-reduced-motion: reduce) {
      .side-link { transition: none; }
    }

    .side-foot {
      margin-top: auto;
      padding-top: 0.9rem;
      border-top: 1px solid oklch(1 0 0 / 0.12);
      display: grid; gap: 0.65rem;
    }
    .side-account {
      display: flex; align-items: center; justify-content: space-between;
      gap: 0.5rem; min-width: 0;
    }
    .side-account-id {
      display: inline-flex; align-items: center; gap: 0.4rem; min-width: 0;
      font-size: 0.6875rem; letter-spacing: 0.08em; text-transform: uppercase;
      color: var(--brand-on-mu);
    }
    .side-account-email {
      overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
      max-width: 8.5rem;
    }

    /* ── Collapsed rail — html[data-side-collapsed] (persisted in
       localStorage, applied pre-paint from the head). The rail narrows
       to an icon strip; the logo mark stays pinned at the top and the
       group labels compress into hairline dividers. Desktop only —
       below 900px the rail is hidden and the top bar takes over. ── */
    @media (min-width: 900px) {
      html[data-side-collapsed] .app-side {
        width: 72px;
        padding: 1rem 0.55rem;
      }
      html[data-side-collapsed] .side-top {
        flex-direction: column; align-items: center; gap: 0.1rem;
      }
      html[data-side-collapsed] .side-brand {
        justify-content: center;
        padding: 0.4rem 0 0.7rem;
      }
      html[data-side-collapsed] .side-brand-word { display: none; }
      html[data-side-collapsed] .side-collapse .side-collapse-close { display: none; }
      html[data-side-collapsed] .side-collapse .side-collapse-open { display: inline-flex; }

      /* Group labels become hairline dividers so the grouping survives;
         the text stays in the DOM for screen readers. */
      html[data-side-collapsed] .side-group-label {
        height: 1px; padding: 0; margin: 0 0.45rem 0.6rem;
        font-size: 0; line-height: 0; letter-spacing: 0;
        background: oklch(1 0 0 / 0.12);
        overflow: hidden;
      }
      html[data-side-collapsed] .side-label { display: none; }
      html[data-side-collapsed] .side-link {
        justify-content: center;
        padding: 0.55rem 0;
      }
      html[data-side-collapsed] .side-link:hover { padding-inline-start: 0; }
      html[data-side-collapsed] .side-link .ico-sm { width: 1.05rem; height: 1.05rem; }
      html[data-side-collapsed] .side-link.active::before { inset-inline-start: -0.55rem; }
      /* Unread badge rides the icon's corner instead of trailing a label. */
      html[data-side-collapsed] .inbox-dot {
        position: absolute;
        top: 0; inset-inline-end: 4px;
        margin-inline-start: 0;
        min-width: 0.9rem; height: 0.9rem;
        font-size: 0.5625rem;
      }

      html[data-side-collapsed] .side-foot { justify-items: center; }
      html[data-side-collapsed] .side-foot .lang-toggle {
        flex-direction: column; border-radius: 10px;
      }
      html[data-side-collapsed] .side-foot .lang-toggle button {
        padding: 0.35rem 0.55rem;
      }
      html[data-side-collapsed] .side-account {
        flex-direction: column; justify-content: center; gap: 0.4rem;
      }
      html[data-side-collapsed] .side-account-email { display: none; }
    }

/* ═══════════════════════════════════════════════════════════════════════
   CSP hardening — externalised inline styles (roadmap 1.7 residual close)
   Every rule below replaces a former inline style="…" attribute or a
   page-scoped <style> block so the CSP can drop style-src 'unsafe-inline'.
   Selectors are page-unique or explicitly scoped; nothing here is a new
   Tailwind utility (tw.css is a frozen prebuilt subset).
   ═══════════════════════════════════════════════════════════════════════ */

/* ── Themed staff-gate pages (admin login / MFA): scoped brand override.
   Formerly a per-page :root block; now keyed off a body class so it does
   not leak onto the rest of the app. ───────────────────────────────────── */
body.theme-staff-gate {
  --brand:        oklch(0.36 0.10  264);
  --brand-deep:   oklch(0.24 0.075 264);
  --brand-soft:   oklch(0.44 0.10  264);
  --brand-on:     oklch(0.985 0.005 264);
  --brand-on-mu:  oklch(0.92 0.015 264);
  --brand-on-fa:  oklch(0.82 0.020 264);
  --brand-tint:   oklch(0.965 0.020 264);
  --paper-warm:   oklch(0.985 0.004 264);
  --paper-sunk:   oklch(0.968 0.006 264);
}
body.theme-staff-gate header nav,
body.theme-staff-gate header #mw-nav-toggle { display: none !important; }

/* ── Small shared utility classes (from repeated static inline styles) ─── */
.mw-measure-32ch  { max-width: 32ch; }
.mw-measure-36ch  { max-width: 36ch; }
.mw-measure-42ch  { max-width: 42ch; }
.mw-measure-48ch  { max-width: 48ch; }
.mw-measure-52ch  { max-width: 52ch; }
.mw-measure-60ch  { max-width: 60ch; }
.mw-measure-62ch  { max-width: 62ch; }
.mw-measure-64ch  { max-width: 64ch; }
.mw-measure-70ch  { max-width: 70ch; }
.mw-measure-76ch  { max-width: 76ch; }
.mw-measure-100ch { max-width: 100ch; }
.mw-measure-32rem { max-width: 32rem; }
.mw-measure-36rem { max-width: 36rem; }
.mw-italic-note   { font-style: italic; max-width: 60ch; }

.mw-ink        { color: var(--ink); }
.mw-ink-strong { color: var(--ink); font-weight: 600; }
.mw-ink-faint  { color: var(--ink-faint); }
.mw-brand      { color: var(--brand); }
.mw-brand-on   { color: var(--brand-on); }
.mw-state-gov  { color: var(--state-gov); }
.mw-state-deny { color: var(--state-deny); }

.mw-fs-sm   { font-size: 0.8125rem; }
.mw-fs-xs   { font-size: 0.72rem; }
.mw-fs-base { font-size: 0.875rem; }
.mw-display { font-size: clamp(2rem, 3.2vw, 2.75rem); }

.mw-opacity-75    { opacity: 0.75; }
.mw-vmiddle       { vertical-align: middle; }
.mw-word-break    { word-break: break-all; }
.mw-nocaps        { text-transform: none; letter-spacing: 0.02em; }
.mw-overflow-x    { overflow-x: auto; }
.mw-white-bg      { background: #FFFFFF; }
.mw-nomargin      { margin: 0; }
.mw-nopad         { padding: 0; }
.mw-pad-md        { padding: 1rem 1.25rem; }
.mw-pad-lg        { padding: 1.25rem; }
.mw-gap-16        { gap: 1.6rem; }
.mw-minw-220      { min-width: 220px; }
.mw-minw-16       { min-width: 1.6rem; }

.mw-rule-border   { border: 1px solid var(--rule); }
.mw-rule-outline  { border-color: var(--rule); }
.mw-ink-outline   { border-color: var(--ink); }
.mw-top-rule      { border-top: 1px solid var(--rule); }
.mw-bottom-rule   { border-bottom: 1px solid var(--rule); }
.mw-card-white    { border: 1px solid var(--rule); background: #FFFFFF; border-radius: 0.5rem; }
.mw-card-white-lg { border: 1px solid var(--rule); background: #FFFFFF; border-radius: 0.75rem; }
.mw-card-warm     { border: 1px solid var(--rule); background: var(--paper-warm); }

.mw-code-block    { padding: 1rem 1.25rem; overflow-x: auto; font-size: 0.8125rem; line-height: 1.7; }

/* Field-level error hint (was inline color/size/margin) */
.mw-field-error {
  color: var(--state-deny); font-size: 0.75rem;
  margin-top: 0.25rem; display: block;
}

/* Deny / pass verdict pills (were inline border/bg/color triples) */
.mw-pill-deny { border: 1px solid var(--state-deny-tint); background: var(--state-deny-tint); color: var(--state-deny); }
.mw-pill-pass { border: 1px solid var(--state-pass-tint); background: var(--state-pass-tint); color: var(--state-pass); }
.mw-btn-deny  { background: var(--state-deny); color: white; border-color: var(--state-deny); }

/* Deny-tinted callout / notice band (was an 8-property inline style) */
.mw-notice-deny {
  background: var(--state-deny-tint, #fef2f2);
  border-inline-start: 3px solid var(--state-deny);
  padding: 0.625rem 1rem; border-radius: 6px;
  margin-bottom: 1.25rem; color: var(--ink); font-size: 0.875rem;
}

/* QR container + injected SVG (was inline width/height + a page <style>) */
.qr-box     { width: 170px; height: 170px; display: block; }
.qr-box-sm  { width: 96px;  height: 96px;  display: block; }
.qr-box-180 { width: 180px; height: 180px; }
.qr-svg svg { width: 100% !important; height: 100% !important; display: block; }
.qr-svg svg path { fill: var(--ink) !important; }

/* Field error-border toggle (was inline --field-border set only on error) */
.field.is-error { --field-border: var(--state-deny); }

/* Register toolbar status filter pills (was inline active/inactive style) */
.mw-filter-pill      { background: var(--paper-warm); color: var(--ink-muted); border-color: var(--rule); }
.mw-filter-pill.is-on { background: var(--brand); color: var(--paper); border-color: var(--brand); }

/* ── Fixed ledger/table grid templates (were {% set cols %} inline) ───────
   Each ledger's column track list is a compile-time constant; encoded here
   as a class instead of an inline grid-template-columns. ─────────────────── */
.mw-cols-sources        { grid-template-columns: minmax(0, 1.1fr) 4.5rem minmax(0, 1.6fr) 6rem 7rem 8rem 7rem; column-gap: 0.85rem; }
.mw-cols-visa           { grid-template-columns: 9rem minmax(0, 1.4fr) minmax(0, 7rem) 5.5rem 6rem 6rem 7rem minmax(0, 9rem) 5rem; column-gap: 0.85rem; }
.mw-cols-watchlist      { grid-template-columns: 9rem minmax(0, 1.3fr) 5.5rem 7rem minmax(0, 1.3fr) minmax(0, 1fr) 5rem; column-gap: 0.85rem; }
.mw-cols-passport       { grid-template-columns: 9rem minmax(0, 1.4fr) 5.5rem 7rem 6.5rem 7rem 7rem minmax(0, 1fr) 5rem; column-gap: 0.85rem; }
.mw-cols-nationalid     { grid-template-columns: 9rem minmax(0, 1.4fr) 5.5rem 7rem 6rem minmax(0, 8rem) 5rem; column-gap: 0.85rem; }
.mw-cols-sessions       { grid-template-columns: 2rem 8rem minmax(0, 1.4fr) minmax(0, 1fr) minmax(0, 1.2fr) 5rem 6rem; column-gap: 1.25rem; }
.mw-cols-ledger         { grid-template-columns: 3rem minmax(0, 1.4fr) minmax(0, 1.4fr) minmax(0, 1.6fr) 5rem; column-gap: 1.5rem; }
.mw-cols-rules-bi       { grid-template-columns: 3.5rem 13rem minmax(0, 1fr) 11rem; column-gap: 1.25rem; }
.mw-cols-rules-intake   { grid-template-columns: minmax(0, 3fr) 7rem 4.5rem 9rem 6rem minmax(0, 9rem); column-gap: 1.25rem; }
.mw-cols-rules-llm      { grid-template-columns: minmax(0, 3fr) 6.5rem 7.5rem 4.5rem 9rem 6rem minmax(0, 9rem); column-gap: 1.25rem; }
.mw-ledger-head-ink     { border-color: var(--ink); }
.mw-ledger-head-rule    { border-color: var(--rule-deep); }
.mw-ledger-row-rule     { border-color: var(--rule); }
.mw-rule-row-anim       { transition: opacity 130ms ease; }

/* ── Audit chain stagger + verdict confidence bar (dynamic numerics) ─────
   Set via muwafik.js from data-* attributes so no inline style is needed.
   These carry the CSS custom properties the animation/width read. ───────── */
.mw-badrow { border-color: var(--state-deny); box-shadow: 0 0 0 1px var(--state-deny); }
.mw-ink-muted { color: var(--ink-muted); }
.chain-hash { color: var(--brand); font-weight: 500; }
.mw-bg-warm { background: var(--paper-warm); }

/* ═══════════════════════════════════════════════════════════════════════
   Externalised page-scoped <style> blocks
   ═══════════════════════════════════════════════════════════════════════ */

/* ── audit_view.html — hash-link chips + chain summary ─────────────────── */
.chain-chip {
  display: inline-flex; align-items: center; gap: 0.3rem;
  font: 500 0.6rem/1 'IBM Plex Mono', ui-monospace, monospace;
  letter-spacing: 0.06em; padding: 0.15rem 0.45rem; border-radius: 2px;
  border: 1px solid var(--rule); color: var(--ink-faint);
  background: var(--paper-warm);
  transition: color 150ms ease, border-color 150ms ease, background 150ms ease;
  user-select: all;
}
.chain-chip.chip-top { border-style: dashed; }
.chain-chip.chip-bot { border-style: solid; color: var(--brand); border-color: oklch(from var(--brand) l c h / 0.35); }
.chain-chip.chip-bad { color: var(--state-deny) !important; border-color: var(--state-deny) !important; background: var(--state-deny-tint) !important; }
.chain-row-wrap:first-child .chain-row::before { display: none; }
.chain-row-wrap:hover .chip-bot,
.chain-row-wrap:hover + .chain-row-wrap .chip-top {
  color: var(--brand) !important; border-color: var(--brand) !important;
  background: oklch(from var(--brand) l c h / 0.06) !important;
}
@media (prefers-reduced-motion: reduce) { .chain-chip { transition: none; } }
.chain-summary {
  display: flex; flex-wrap: wrap; align-items: center; gap: 0.6rem 1.25rem;
  padding: 0.65rem 1rem; border: 1px solid var(--rule);
  background: var(--paper-warm); font-size: 0.78rem; margin-bottom: 1.25rem;
}
.chain-summary-sep { color: var(--rule-deep); }

/* ── _loading_overlay.html — spinner keyframes ────────────────────────── */
@keyframes mwLoadingSpin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) { .mwLoadingSpinner { animation: none !important; } }

/* ── interview.html — thinking pulse ──────────────────────────────────── */
@keyframes mw_pulse { from { transform: scale(0.65); opacity: 0.4; } to { transform: scale(1); opacity: 1; } }
@media (prefers-reduced-motion: reduce) { #thinking span:first-child { animation: none !important; } }

/* ── admin_inbox_detail.html — inbox side list + system verdict + conf bar ─ */
.inbox-side-item { display: block; padding: 0.6rem 0.7rem; border-inline-start: 3px solid transparent; border-bottom: 1px solid var(--rule); }
.inbox-side-item:hover { background: rgba(0,0,0,0.035); }
.inbox-side-item.is-active { border-inline-start-color: var(--ink); background: rgba(0,0,0,0.05); }
.sys-verdict { border: 1.5px solid currentColor; border-radius: 14px; padding: 1.25rem 1.5rem; position: relative; overflow: hidden; }
.sys-verdict-word { font-weight: 700; font-size: clamp(1.75rem, 2.6vw, 2.375rem); line-height: 1; letter-spacing: -0.01em; }
.conf-bar { height: 6px; border-radius: 999px; background: oklch(0.18 0.012 155 / 0.12); overflow: hidden; }
.conf-bar > span { display: block; height: 100%; background: currentColor; border-radius: 999px; width: 0; }

/* ═══════════════════════════════════════════════════════════════════════
   admin_rules.html — rules workbench (formerly a 244-line page <style>)
   ═══════════════════════════════════════════════════════════════════════ */
.wrap-wide { max-width: 1760px; margin-inline: auto; padding-inline: clamp(1.25rem, 3vw, 3rem); }
.rules-layout { display: grid; grid-template-columns: clamp(240px, 20vw, 300px) minmax(0, 1fr); gap: clamp(1.5rem, 3vw, 3.5rem); align-items: start; }
@media (max-width: 1023px) {
  .rules-layout { grid-template-columns: 1fr; }
  .rules-rail { position: static !important; }
  .rail-pipe, .rail-note { display: none; }
  .rail-tabs { display: grid; grid-template-columns: 1fr 1fr; gap: 0.5rem; }
  .rail-tab { border-inline-start-width: 0 !important; border-block-end: 3px solid transparent; }
  .rail-tab.is-active { border-block-end-color: var(--brand); }
}
.rules-rail { position: sticky; top: 92px; }
.rail-label { font: 600 0.625rem/1 'IBM Plex Sans', system-ui, sans-serif; letter-spacing: 0.18em; text-transform: uppercase; color: var(--ink-faint); padding-block: 0.25rem 0.75rem; }
.rail-tab { display: flex; align-items: flex-start; gap: 0.75rem; width: 100%; text-align: start; background: transparent; border: 1px solid var(--rule); border-inline-start: 3px solid transparent; padding: 0.9rem 1rem; cursor: pointer; font-family: inherit; color: var(--ink-muted); transition: border-color 130ms ease, background-color 130ms ease, color 130ms ease; }
.rail-tab + .rail-tab { margin-top: 0.5rem; }
.rail-tab:hover { background: var(--paper-warm); color: var(--ink); }
.rail-tab.is-active { background: var(--paper-warm); border-color: var(--rule-deep); border-inline-start-color: var(--brand); color: var(--ink); }
.rail-tab .ico { margin-top: 0.1rem; flex-shrink: 0; }
.rail-tab.is-active .ico { color: var(--brand); }
.rail-tab-title { font-size: 0.9rem; font-weight: 600; letter-spacing: -0.01em; }
.rail-tab-sub { font-size: 0.72rem; color: var(--ink-faint); margin-top: 0.2rem; line-height: 1.4; }
.rail-count { margin-inline-start: auto; font-feature-settings: 'tnum'; font-size: 0.9rem; font-weight: 600; color: var(--ink-faint); padding-top: 0.05rem; }
.rail-tab.is-active .rail-count { color: var(--brand); }
.rail-pipe { list-style: none; margin: 0; padding: 0; counter-reset: pipe; }
.rail-pipe li { counter-increment: pipe; position: relative; padding: 0.45rem 0 0.45rem 2rem; font-size: 0.78rem; color: var(--ink-faint); line-height: 1.35; }
html[dir="rtl"] .rail-pipe li { padding: 0.45rem 2rem 0.45rem 0; }
.rail-pipe li::before { content: counter(pipe); position: absolute; inset-inline-start: 0; top: 0.45rem; width: 1.25rem; height: 1.25rem; display: grid; place-items: center; font: 600 0.62rem/1 'IBM Plex Sans', system-ui, sans-serif; font-feature-settings: 'tnum'; border: 1px solid var(--rule-deep); border-radius: 1px; color: var(--ink-muted); background: var(--paper); }
.rail-pipe li::after { content: ''; position: absolute; inset-inline-start: 0.6rem; top: calc(0.45rem + 1.25rem); bottom: -0.45rem; width: 1px; background: var(--rule); }
.rail-pipe li:last-child::after { display: none; }
.rail-pipe li.pipe-branch { counter-increment: none; display: flex; align-items: center; gap: 0.6rem; padding: 0.65rem 0; font: 600 0.56rem/1.3 'IBM Plex Sans', system-ui, sans-serif; letter-spacing: 0.13em; text-transform: uppercase; color: var(--state-gov); white-space: nowrap; }
.rail-pipe li.pipe-branch::before, .rail-pipe li.pipe-branch::after { content: ''; position: static; display: block; flex: 1; width: auto; height: 1px; min-width: 0.75rem; border: 0; background: oklch(0.30 0.08 260 / 0.35); }
.rail-pipe li.is-here { color: var(--ink); font-weight: 600; }
.rail-pipe li.is-here::before { background: var(--brand); border-color: var(--brand); color: var(--brand-on); }
.rail-pipe li.is-here .pipe-you { display: inline-block; font: 600 0.56rem/1 'IBM Plex Sans', system-ui, sans-serif; letter-spacing: 0.14em; text-transform: uppercase; color: var(--brand); border: 1px solid var(--brand); border-radius: 999px; padding: 0.15rem 0.45rem; margin-inline-start: 0.4rem; vertical-align: 0.1em; }
.rail-pipe li .pipe-you { display: none; }
.rail-note { margin-top: 1.25rem; padding: 0.85rem 1rem; border: 1px dashed var(--rule-deep); font-size: 0.75rem; line-height: 1.5; color: var(--ink-muted); background: var(--paper-warm); }
.stat-strip { display: grid; grid-template-columns: repeat(auto-fit, minmax(120px, 1fr)); border: 1px solid var(--rule); background: var(--paper); margin-bottom: 1.75rem; }
.stat { padding: 1rem 1.25rem 0.9rem; border-inline-start: 1px solid var(--rule); }
.stat:first-child { border-inline-start: 0; }
.stat-num { display: block; font-size: clamp(1.5rem, 2vw, 2rem); font-weight: 600; font-feature-settings: 'tnum'; letter-spacing: -0.02em; line-height: 1.1; color: var(--ink); }
.stat-num.is-live { color: var(--state-pass); }
.stat-num.is-pend { color: var(--state-gov); }
.stat-label { display: block; margin-top: 0.3rem; font: 600 0.625rem/1.3 'IBM Plex Sans', system-ui, sans-serif; letter-spacing: 0.14em; text-transform: uppercase; color: var(--ink-faint); }
.rule-row.is-archived { opacity: 0.45; }
.rule-row.is-archived:hover { opacity: 0.8; }
.rule-modal { border: 1px solid var(--rule-deep); border-radius: 2px; padding: 0; width: min(920px, calc(100vw - 2rem)); max-height: min(88vh, 1000px); background: var(--paper); color: var(--ink); box-shadow: 0 40px 80px -24px oklch(0.15 0.04 152 / 0.45); }
.rule-modal::backdrop { background: oklch(0.2 0.05 152 / 0.55); }
.rule-modal[open] { animation: mw-modal-in 300ms cubic-bezier(0.2, 0.9, 0.25, 1) both; }
@keyframes mw-modal-in { from { opacity: 0; transform: translateY(14px) scale(0.985); } to { opacity: 1; transform: translateY(0) scale(1); } }
@media (prefers-reduced-motion: reduce) { .rule-modal[open] { animation: none; } }
.rule-modal-head { position: sticky; top: 0; z-index: 2; display: flex; align-items: center; gap: 1rem; padding: 1.1rem clamp(1.25rem, 3vw, 2rem); background: var(--brand-deep); color: var(--brand-on); }
.rule-modal-title { font-size: 1.05rem; font-weight: 600; letter-spacing: -0.01em; }
.rule-modal-sub { font-size: 0.75rem; color: var(--brand-on-fa); margin-top: 0.15rem; }
.rule-modal-close { margin-inline-start: auto; display: grid; place-items: center; width: 2.1rem; height: 2.1rem; background: transparent; border: 1px solid oklch(0.97 0.012 60 / 0.35); border-radius: 2px; color: var(--brand-on); cursor: pointer; transition: background-color 120ms ease, border-color 120ms ease; }
.rule-modal-close:hover { background: oklch(1 0 0 / 0.1); border-color: var(--brand-on); }
.rule-modal-body { padding: clamp(1.5rem, 3vw, 2.25rem); overflow-y: auto; max-height: calc(min(88vh, 1000px) - 4.4rem); }

/* ═══════════════════════════════════════════════════════════════════════
   _rule_form.html — condition/rule builder (formerly a 164-line page <style>)
   ═══════════════════════════════════════════════════════════════════════ */
#ruleForm [hidden] { display: none !important; }
.rf-form { display: flex; flex-direction: column; gap: 1.6rem; }
.rf-q { font-size: 0.95rem; font-weight: 600; letter-spacing: -0.01em; color: var(--ink); margin-bottom: 0.2rem; }
.rf-hint { font-size: 0.78rem; line-height: 1.5; color: var(--ink-muted); }
.rf-sect > .rf-hint { margin-bottom: 0.75rem; }
.rf-types { display: grid; grid-template-columns: 1fr 1fr; gap: 0.75rem; }
@media (max-width: 700px) { .rf-types { grid-template-columns: 1fr; } }
.rf-type { position: relative; display: block; cursor: pointer; border: 1px solid var(--rule-deep); border-radius: 2px; background: var(--paper); padding: 0.95rem 1.05rem; transition: background-color 140ms ease, border-color 140ms ease, box-shadow 140ms ease; }
.rf-type input { position: absolute; opacity: 0; pointer-events: none; }
.rf-type:hover { background: var(--paper-warm); }
.rf-type:has(input:checked) { border-color: var(--brand); box-shadow: inset 0 0 0 1px var(--brand); background: var(--brand-tint); }
.rf-type:has(input:focus-visible) { outline: 2px solid var(--brand); outline-offset: 2px; }
.rf-type-head { display: flex; align-items: center; gap: 0.5rem; font-weight: 600; font-size: 0.9rem; color: var(--ink); }
.rf-type:has(input:checked) .rf-type-head .ico-sm { color: var(--brand); }
.rf-type-badge { margin-inline-start: auto; font-family: 'IBM Plex Mono', ui-monospace, monospace; font-size: 0.6rem; letter-spacing: 0.08em; text-transform: uppercase; color: var(--ink-faint); border: 1px solid var(--rule); border-radius: 1px; padding: 0.15rem 0.4rem; white-space: nowrap; }
.rf-type-sub { display: block; margin-top: 0.4rem; font-size: 0.78rem; line-height: 1.5; color: var(--ink-muted); }
.rf-row { display: flex; flex-wrap: wrap; align-items: flex-start; gap: 0.6rem 1rem; padding: 0.65rem 0.85rem; border: 1px solid var(--rule); background: var(--paper-warm); }
.rf-row + .rf-row { margin-top: 0.5rem; }
.rf-conn { flex: 0 0 3.4rem; padding-top: 0.45rem; font-size: 0.8125rem; font-weight: 600; color: var(--ink-muted); }
.rf-conn select { border: 0; border-bottom: 1px solid var(--rule-deep); background: transparent; padding: 0.35rem 0; font: inherit; font-weight: 600; color: var(--ink-muted); width: 100%; cursor: pointer; }
.rf-conn select:focus { outline: none; border-color: var(--brand); }
.rf-ctl { border: 0; border-bottom: 1px solid var(--rule-deep); background: transparent; padding: 0.35rem 0; font-size: 0.875rem; font-family: inherit; color: var(--ink); }
.rf-ctl:focus { outline: none; border-bottom-color: var(--brand); }
select.rf-ctl { min-width: 130px; cursor: pointer; }
input.rf-ctl { min-width: 150px; }
.rf-remove { flex: 0 0 auto; margin-inline-start: auto; padding-top: 0.45rem; color: var(--ink-faint); background: none; border: 0; cursor: pointer; transition: color 130ms ease; }
.rf-remove:hover { color: var(--state-deny); }
.rf-chips { display: flex; flex-wrap: wrap; gap: 0.35rem; align-items: center; }
.rf-chip { display: inline-flex; align-items: center; gap: 0.35rem; border: 1px solid var(--rule-deep); background: var(--paper); padding: 0.2rem 0.3rem 0.2rem 0.55rem; font-size: 0.75rem; }
html[dir="rtl"] .rf-chip { padding: 0.2rem 0.55rem 0.2rem 0.3rem; }
.rf-chip button { border: 0; background: none; cursor: pointer; color: var(--ink-faint); line-height: 1; padding: 0.1rem; }
.rf-chip button:hover { color: var(--state-deny); }
.rf-checkchip { display: inline-flex; align-items: center; gap: 0.3rem; border: 1px solid var(--rule); padding: 0.25rem 0.5rem; font-size: 0.75rem; cursor: pointer; background: var(--paper); transition: background-color 130ms ease, border-color 130ms ease; }
.rf-checkchip:has(:checked) { background: var(--brand-tint); border-color: var(--brand); }
.rf-checkchip input { accent-color: var(--brand); width: 0.85rem; height: 0.85rem; }
.rf-dec { display: grid; grid-template-columns: repeat(3, 1fr); gap: 0.6rem; }
.rf-dec.rf-dec-4 { grid-template-columns: repeat(2, 1fr); }
@media (max-width: 700px) { .rf-dec, .rf-dec.rf-dec-4 { grid-template-columns: 1fr; } }
.rf-dec label { position: relative; display: block; cursor: pointer; border: 1px solid var(--rule-deep); border-radius: 2px; background: var(--paper); padding: 0.7rem 0.9rem; transition: background-color 140ms ease, border-color 140ms ease, box-shadow 140ms ease; }
.rf-dec input { position: absolute; opacity: 0; pointer-events: none; }
.rf-dec label:hover { background: var(--paper-warm); }
.rf-dec label:has(input:focus-visible) { outline: 2px solid var(--brand); outline-offset: 2px; }
.rf-dec-word { font-weight: 600; font-size: 0.85rem; color: var(--ink); }
.rf-dec-sub { display: block; margin-top: 0.2rem; font-size: 0.7rem; line-height: 1.4; color: var(--ink-muted); }
.rf-dec label[data-tone="deny"]:has(input:checked) { border-color: var(--state-deny); box-shadow: inset 0 0 0 1px var(--state-deny); background: var(--state-deny-tint); }
.rf-dec label[data-tone="deny"]:has(input:checked) .rf-dec-word { color: var(--state-deny); }
.rf-dec label[data-tone="pass"]:has(input:checked) { border-color: var(--state-pass); box-shadow: inset 0 0 0 1px var(--state-pass); background: var(--state-pass-tint); }
.rf-dec label[data-tone="pass"]:has(input:checked) .rf-dec-word { color: var(--state-pass); }
.rf-dec label[data-tone="gov"]:has(input:checked) { border-color: var(--state-gov); box-shadow: inset 0 0 0 1px var(--state-gov); background: var(--state-gov-tint); }
.rf-dec label[data-tone="gov"]:has(input:checked) .rf-dec-word { color: var(--state-gov); }
.rf-dec label[data-tone="ask"]:has(input:checked) { border-color: var(--brand); box-shadow: inset 0 0 0 1px var(--brand); background: var(--brand-tint); }
.rf-dec label[data-tone="ask"]:has(input:checked) .rf-dec-word { color: var(--brand); }
.rf-seg { display: inline-flex; border: 1px solid var(--rule-deep); border-radius: 2px; overflow: hidden; }
.rf-seg label { position: relative; display: inline-flex; align-items: center; gap: 0.4rem; padding: 0.45rem 0.85rem; font-size: 0.8125rem; cursor: pointer; color: var(--ink-muted); background: var(--paper); transition: background-color 140ms ease, color 140ms ease; }
.rf-seg label + label { border-inline-start: 1px solid var(--rule-deep); }
.rf-seg input { position: absolute; opacity: 0; pointer-events: none; }
.rf-seg label:has(input:checked) { background: var(--brand); color: var(--brand-on); font-weight: 600; }
.rf-seg label:has(input:focus-visible) { outline: 2px solid var(--brand); outline-offset: 2px; z-index: 1; }
.rf-summary { border: 1px solid var(--rule-deep); background: var(--paper-sunk); padding: 0.85rem 1.05rem; }
.rf-sum-k { display: block; font-family: 'IBM Plex Mono', ui-monospace, monospace; font-size: 0.6rem; letter-spacing: 0.12em; text-transform: uppercase; color: var(--ink-faint); margin-bottom: 0.3rem; }
.rf-sum-txt { font-size: 0.875rem; line-height: 1.6; color: var(--ink); }
.rf-sum-txt .rf-sum-pending { color: var(--ink-muted); font-style: italic; }
.rf-adv { border: 1px solid var(--rule); }
.rf-adv summary { display: flex; align-items: center; gap: 0.5rem; padding: 0.7rem 0.95rem; cursor: pointer; list-style: none; font-size: 0.8125rem; font-weight: 600; color: var(--ink-muted); transition: background-color 130ms ease; }
.rf-adv summary::-webkit-details-marker { display: none; }
.rf-adv summary:hover { background: var(--paper-warm); }
.rf-adv summary .rf-adv-chev { margin-inline-start: auto; transition: transform 160ms ease; }
.rf-adv[open] summary .rf-adv-chev { transform: rotate(180deg); }
@media (prefers-reduced-motion: reduce) { .rf-adv summary .rf-adv-chev { transition: none; } }
.rf-adv-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 1.25rem 2rem; padding: 0.35rem 0.95rem 1.1rem; }
@media (max-width: 700px) { .rf-adv-grid { grid-template-columns: 1fr; } }
.rf-adv-grid .rf-span2 { grid-column: 1 / -1; }
.rf-err { font-size: 0.8125rem; color: var(--state-deny); }
.rf-jsonbar { display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap; gap: 0.75rem; margin-top: 0.75rem; }

/* ── CSP hardening — tail of unique static inline styles ────────────────── */
.mw-measure-18ch { max-width: 18ch; }
.mw-measure-20ch { max-width: 20ch; }
.mw-measure-28ch { max-width: 28ch; }
.mw-measure-40ch { max-width: 40ch; }
.mw-measure-56ch { max-width: 56ch; }
.mw-measure-72ch { max-width: 72ch; }
.mw-measure-80ch { max-width: 80ch; }
.mw-measure-30ch-med { max-width: 30ch; font-weight: 500; }
.mw-measure-44rem { max-width: 44rem; }
.mw-measure-240px { max-width: 240px; }
.mw-measure-280px { max-width: 280px; }
.mw-measure-none  { max-width: none; }
.mw-minw-16rem { min-width: 16rem; }
.mw-minw-125rem { min-width: 1.25rem; }
.mw-minw-110 { min-width: 110px; }
.mw-minw-150 { min-width: 150px; }
.mw-minw-240 { min-width: 240px; }
.mw-clamp-90-120 { min-width: 90px; max-width: 120px; }

.mw-lh-15 { line-height: 1.5; }
.mw-lh-19 { line-height: 1.9; }
.mw-list-disc  { list-style: disc inside; line-height: 1.9; max-width: 76ch; }
.mw-list-decimal { list-style: decimal inside; line-height: 1.9; max-width: 76ch; }
.mw-cols2-decimal { columns: 2; column-gap: 3rem; list-style: decimal inside; line-height: 2; }

.mw-fs-sm-56 { font-size: 0.8125rem; max-width: 56ch; }
.mw-fs-875 { font-size: 0.875rem; }
.mw-fs-875-note { font-size: 0.875rem; margin-top: 0.35rem; line-height: 1.5; }
.mw-fs-1-05-bold { font-size: 1.05rem; font-weight: 600; }
.mw-fs-1-0625 { font-size: 1.0625rem; }
.mw-fs-tiny-dim { font-size: 0.4em; opacity: 0.6; }
.mw-hero-xl { font-size: clamp(3.5rem, 7vw, 5.5rem); line-height: 1; letter-spacing: -0.04em; }
.mw-hero-lg { font-size: clamp(2.5rem, 5vw, 4rem); max-width: 16ch; }
.mw-hero-md { font-size: clamp(1.75rem, 2.6vw, 2.25rem); }

.mw-ink-strong-sp { color: var(--ink); font-weight: 600; }
.mw-brand-500 { color: var(--brand); font-weight: 500; }
.mw-state-pass { color: var(--state-pass); }
.mw-deny-hidden { color: var(--state-deny); display: none; }
.mw-pass-hidden { color: var(--state-pass); display: none; }

.mw-opacity-70 { opacity: 0.7; }
.mw-opacity-85 { opacity: 0.85; }
.mw-iconbtn { opacity: 0.7; border: none; background: transparent; cursor: pointer; padding: 0; }
.mw-wrap-any { overflow-wrap: anywhere; }

.mw-pad-block-hero { padding-block: clamp(4rem, 10vh, 8rem); }
.mw-pad-1520 { padding: 1.25rem 1.5rem; }
.mw-pad-top { padding: 1rem 0 0; }
.mw-relative-z1 { position: relative; z-index: 1; }
.mw-abs { position: absolute; }
.mw-sticky-panel { position: sticky; top: 1rem; max-height: calc(100vh - 2rem); overflow-y: auto; }
.mw-scroll-anchor { scroll-margin-top: 92px; }

.mw-ico-085 { width: 0.85em; height: 0.85em; stroke-width: 1.6; }
.mw-flag-box { width: 22px; height: 26px; }

.mw-border-collapse { border-collapse: collapse; }
.mw-th-ink { border-bottom: 1px solid var(--ink); text-align: start; }
.mw-bottom-rule-thin { border-bottom: 1px solid var(--rule); }
.mw-blk-rule { border-inline-start: 3px solid var(--rule-deep); padding-inline-start: 1rem; }
.mw-blk-rule-sm { border-inline-start: 3px solid var(--rule-deep); padding-inline-start: 0.75rem; overflow-wrap: anywhere; }
.mw-blk-pass { border-inline-start: 3px solid var(--state-pass); padding-inline-start: 0.75rem; color: var(--ink); }
.mw-hairline-hidden { display: none; border-inline-start: 3px solid var(--rule); }
.mw-callout-warm { background: var(--paper-warm); border: 1px solid var(--rule); }
.mw-row-flex { border: 1px solid var(--rule); display: flex; align-items: center; gap: 0.75rem; }
.mw-textarea-mono { border: 1px solid var(--rule); resize: vertical; font-family: 'IBM Plex Mono', ui-monospace, monospace; }
.mw-btn-deny-off { background: var(--state-deny); color: white; border-color: var(--state-deny); opacity: 0.5; }
.mw-chip-deny { background: var(--state-deny-tint); color: var(--state-deny); border: 1px solid var(--state-deny); }
.mw-notice-deny-inline { background: var(--state-deny-tint, #fef2f2); border-inline-start: 3px solid var(--state-deny); padding: 0.625rem 1rem; border-radius: 6px; margin: 0.75rem 0; color: var(--ink); font-size: 0.875rem; }
.mw-chip-deny-out { background: transparent; color: var(--state-deny); border-color: var(--state-deny); }
.mw-chip-gov-out { background: transparent; color: var(--state-gov); border-color: var(--state-gov); }
.mw-chip-pass-fill { background: var(--state-pass); border-color: var(--state-pass); }
.mw-gov-tint { border: 1px solid var(--rule); background: var(--state-gov-tint); }
.mw-gov-tint-full { border: 1px solid var(--rule); background: var(--state-gov-tint); color: var(--state-gov); }
.mw-gov-tint-solid { border: 1px solid var(--state-gov-tint); background: var(--state-gov-tint); color: var(--state-gov); }
.mw-arrow-start { color: var(--brand); font-size: 1.25em; line-height: 0; vertical-align: -0.1em; margin-inline-start: 0.1em; }
.mw-arrow-end { color: var(--brand); font-size: 1.25em; line-height: 0; vertical-align: -0.1em; margin-inline-end: 0.1em; }
.mw-cols-iam { grid-template-columns: 6rem minmax(0,2fr) minmax(0,3fr) 7rem 8rem; column-gap: 1.25rem; }
.mw-cols-autofill16 { grid-template-columns: repeat(auto-fill, minmax(16rem, 1fr)); }

/* ── _loading_overlay.html — full-screen loading overlay (was inline) ───── */
.mw-loading-overlay {
  position: fixed; inset: 0;
  background: oklch(0.18 0.012 155 / 0.55);
  display: none; align-items: center; justify-content: center;
  z-index: var(--z-toast, 50); opacity: 0;
  transition: opacity 220ms ease;
}
.mw-loading-card {
  background: var(--paper); color: var(--ink);
  padding: 2rem 2.5rem; border-radius: 8px; text-align: center;
  max-width: 24rem; box-shadow: 0 24px 64px -12px rgba(0,0,0,0.35);
  display: flex; flex-direction: column; align-items: center; gap: 1.25rem;
}
.mwLoadingSpinner {
  width: 52px; height: 52px; border-radius: 50%;
  border: 4px solid rgba(0,0,0,0.08);
  border-top-color: var(--brand);
  animation: mwLoadingSpin 0.8s linear infinite;
}

/* ── _flash.html — flash banner tones (bucketed pass/deny) ─────────────── */
.mw-flash {
  padding: 0.625rem 1rem; border-radius: 6px; margin-bottom: 1.25rem;
  color: var(--ink); font-size: 0.875rem; line-height: 1.5;
  border-inline-start: 3px solid var(--rule);
}
.mw-flash.is-pass { background: var(--state-pass-tint, #ecfdf5); border-inline-start-color: var(--state-pass); }
.mw-flash.is-deny { background: var(--state-deny-tint, #fef2f2); border-inline-start-color: var(--state-deny); }

/* ── interview.html — "thinking" pulse dot (was inline) ────────────────── */
.mw-think-dot {
  display: inline-block; width: 0.75rem; height: 0.75rem; border-radius: 50%;
  background: var(--brand);
  animation: mw_pulse 0.9s ease-in-out infinite alternate;
}
