/* ============================================================================
   nxa-instrument.css — the NXA Instrument UI, canonical token layer
   ----------------------------------------------------------------------------
   Source of truth:  shared/design/nxa-instrument.css
   Governed by:      docs/knowledge/decisions/
                     DEC_2026-08-22_nxa-meridia-interface-brand-architecture.md
                     DEC_2026-09-21_nxa-instrument-shared-token-layer.md
   Brand values:     verified against https://www.impactnexia.com, 2026-09-21
                     (computed styles, not eyeballed)

   Copies live in each app's static directory and are GENERATED.
   Edit this file, then run: scripts/sync_design_tokens.sh
   Check for drift with:      scripts/sync_design_tokens.sh --check
   ========================================================================== */

/* IBM Plex, self-hosted.
   The workspace CSP is `style-src 'self'` and stays that way: this tool
   handles confidential client documents, and a Google Fonts request on
   every page view is both a blocked stylesheet and a privacy leak.
   SIL Open Font License 1.1. Generated — see scripts/sync_design_tokens.sh. */

@font-face {
  font-family: 'IBM Plex Mono';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url(fonts/IBMPlexMono-400-latin-ext.woff2) format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
  font-family: 'IBM Plex Mono';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url(fonts/IBMPlexMono-400-latin.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: 'IBM Plex Mono';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url(fonts/IBMPlexMono-500-latin-ext.woff2) format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
  font-family: 'IBM Plex Mono';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url(fonts/IBMPlexMono-500-latin.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: 'IBM Plex Mono';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url(fonts/IBMPlexMono-600-latin-ext.woff2) format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
  font-family: 'IBM Plex Mono';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url(fonts/IBMPlexMono-600-latin.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: 'IBM Plex Sans';
  font-style: normal;
  font-weight: 400;
  font-stretch: 100%;
  font-display: swap;
  src: url(fonts/IBMPlexSans-400-latin-ext.woff2) format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
  font-family: 'IBM Plex Sans';
  font-style: normal;
  font-weight: 400;
  font-stretch: 100%;
  font-display: swap;
  src: url(fonts/IBMPlexSans-400-latin.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: 'IBM Plex Sans';
  font-style: normal;
  font-weight: 500;
  font-stretch: 100%;
  font-display: swap;
  src: url(fonts/IBMPlexSans-500-latin-ext.woff2) format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
  font-family: 'IBM Plex Sans';
  font-style: normal;
  font-weight: 500;
  font-stretch: 100%;
  font-display: swap;
  src: url(fonts/IBMPlexSans-500-latin.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: 'IBM Plex Sans';
  font-style: normal;
  font-weight: 600;
  font-stretch: 100%;
  font-display: swap;
  src: url(fonts/IBMPlexSans-600-latin-ext.woff2) format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
  font-family: 'IBM Plex Sans';
  font-style: normal;
  font-weight: 600;
  font-stretch: 100%;
  font-display: swap;
  src: url(fonts/IBMPlexSans-600-latin.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

:root {
  /* ── type ───────────────────────────────────────────────────────────────
     Mono is the dominant voice: headings, labels, identifiers, metadata and
     every measurement. Sans carries running prose only. Long body copy in
     mono is prohibited by DEC_2026-08-22. */
  --nxa-sans: "IBM Plex Sans", system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  --nxa-mono: "IBM Plex Mono", ui-monospace, SFMono-Regular, Menlo, monospace;

  /* ── ground and surfaces (warm stone) ──────────────────────────────── */
  --nxa-ground:       #EFEAE0;
  --nxa-surface:      #F7F4EE;
  --nxa-surface-2:    #EAE5DA;
  --nxa-surface-3:    #E6E1D3;

  /* ── ink ───────────────────────────────────────────────────────────── */
  --nxa-ink:          #14181C;
  --nxa-ink-2:        #565B54;
  --nxa-ink-3:        #8B8677;
  --nxa-ink-inv:      #EFEAE0;

  /* ── rules (hairline discipline; borders are structure, not decoration) */
  --nxa-rule:         #E0DACB;
  --nxa-rule-strong:  #C2BDAF;

  /* ── brand ─────────────────────────────────────────────────────────── */
  --nxa-brand:        #1F4F4A;
  --nxa-brand-deep:   #163B37;
  --nxa-brand-soft:   #DCE9E6;
  --nxa-mint:         #8FD0C6;   /* carries the accent on dark grounds */
  --nxa-near-black:   #1D2227;
  --nxa-near-black-2: #2E353C;
  --nxa-on-dark:      #C2BDAF;
  --nxa-on-dark-hi:   #EFEAE0;

  /* The mark's tracking is load-bearing, not decorative. The plate's left
     padding adds exactly one letter-space back to cancel the trailing space
     CSS appends after the final "A" (.94em − .8em = .14em in the authored
     source). Keep the two in lockstep: retuning the tracking alone silently
     breaks the optical centring. Use the token in both places — never a
     literal. Confirmed against the authored CSS by the Impact Nexia site
     session, 2026-09-22. */
  --nxa-mark-tracking: .14em;

  /* ── provenance ─────────────────────────────────────────────────────
     THREE VISUAL FAMILIES, NINE STATUSES. The families are a reading aid,
     never the source of truth: the exact `Field.Status` must be rendered as
     text beside every fact and carried in the read model.

       established  CLIENT_CONFIRMED, DOCUMENT_EXTRACTED, EXPERT_APPROVED,
                    EXTERNALLY_SUPPORTED (distinct mark variant, same family)
       proposed     ENGINE_PROPOSED — alone, and never any other status
       unresolved   TO_BE_ESTABLISHED, NOT_AVAILABLE, NOT_APPLICABLE
       superseded   not a family: a revision treatment, excluded from current
                    views by default and linked to the revision that replaced it

     The hard rule, stated in `supporting/impact_engine/package/field.py`:
     "the engine's suggestion and the client's fact must never render alike."
     ENGINE_PROPOSED therefore never shares a mark, weight or colour with an
     established fact. Collapsing it into a system-produced family is the
     specific error corrected by EV_2026-09-21_imm-nxa-order-audit.

     Exact mark geometry is frozen in Phase 0A of TASK_ORDER_IMM_UI_2026-09-21.
     Never used decoratively. */
  --nxa-prov-established:      #14181C;   /* on record; the project's position */
  --nxa-prov-proposed:         #8A5E20;   /* engine suggests; nobody agreed    */
  --nxa-prov-proposed-soft:    #F1E7D4;
  --nxa-prov-unresolved:       #9C9788;   /* unknown, not found, N/A           */
  --nxa-prov-superseded:       #9C9788;   /* replaced by a later revision      */

  /* ── status ─────────────────────────────────────────────────────────
     Semantic, and deliberately not the brand hue, so "good" never reads
     as "branded" and the accent never reads as a judgement. */
  --nxa-good:  #2F6B4F;  --nxa-good-soft:  #E0EDE4;
  --nxa-watch: #8A5E20;  --nxa-watch-soft: #F4EAD6;
  --nxa-stop:  #9B3B2C;  --nxa-stop-soft:  #F6E3DE;
  --nxa-info:  #2B5B70;  --nxa-info-soft:  #DFEAEF;

  /* ── ecosystem encoding (Science) ───────────────────────────────────
     One definition platform-wide so a mangrove is the same colour in the
     console, a report and a chart. */
  --nxa-eco-seagrass: #1F4F4A;
  --nxa-eco-mangrove: #2F6B4F;
  --nxa-eco-sebkha:   #8A5E20;
  --nxa-eco-forest:   #2E5A33;
  --nxa-eco-dryland:  #8B6A3E;

  /* ── geometry and elevation ─────────────────────────────────────────
     Restrained radii per DEC. Elevation is spent on the one thing that
     leaves the page plane, never stamped on every block. */
  --nxa-r:      2px;
  --nxa-r-lg:   3px;
  --nxa-shadow:      0 1px 2px rgba(20, 24, 28, .05);
  --nxa-shadow-lift: 0 8px 28px rgba(20, 24, 28, .10);
}

/* ── dark ground ───────────────────────────────────────────────────────
   OPT-IN ONLY, via [data-nxa-theme="dark"]. Deliberately NOT wired to
   prefers-color-scheme: the Science pages still carry hard-coded light
   colours outside this token layer, so an automatic flip would render one
   theme's text on the other theme's ground. Surfaces opt in once they are
   fully tokenised. */
[data-nxa-theme="dark"] {
  --nxa-ground:       #1D2227;
  --nxa-surface:      #242A30;
  --nxa-surface-2:    #1A1F24;
  --nxa-surface-3:    #2E353C;

  --nxa-ink:          #EFEAE0;
  --nxa-ink-2:        #A8ACA4;
  --nxa-ink-3:        #83887F;
  --nxa-ink-inv:      #14181C;

  --nxa-rule:         #313840;
  --nxa-rule-strong:  #454D56;

  --nxa-brand:        #8FD0C6;
  --nxa-brand-deep:   #6FB8AD;
  --nxa-brand-soft:   #1B3532;

  --nxa-prov-established:   #EFEAE0;
  --nxa-prov-proposed:      #D2A765;
  --nxa-prov-proposed-soft: #2E2718;
  --nxa-prov-unresolved:    #74786F;
  --nxa-prov-superseded:    #74786F;

  --nxa-good:  #6FB98C;  --nxa-good-soft:  #1B3326;
  --nxa-watch: #D2A765;  --nxa-watch-soft: #2E2718;
  --nxa-stop:  #D98A78;  --nxa-stop-soft:  #34211C;
  --nxa-info:  #7FB2C6;  --nxa-info-soft:  #172A32;
}

/* ============================================================================
   Primitives — the minimum shared vocabulary. Not a component framework;
   each app keeps its own layout.
   ========================================================================== */

.nxa-mono  { font-family: var(--nxa-mono); }
.nxa-sans  { font-family: var(--nxa-sans); }
.nxa-num   { font-variant-numeric: tabular-nums; }

.nxa-label {
  font-family: var(--nxa-mono);
  font-size: 10px;
  letter-spacing: .12em;
  text-transform: uppercase;
  font-weight: 500;
  color: var(--nxa-ink-3);
}

/* provenance marks — shape carries the meaning, so the distinction survives
   greyscale, print and colour-vision deficiency. A mark never appears without
   its status text: the family narrows, the status states. */
.nxa-pm { display: inline-block; width: 7px; height: 7px; flex: none; border-radius: 1px; transform: translateY(-1px); }
.nxa-pm--established { background: var(--nxa-prov-established); }
.nxa-pm--external    { background: linear-gradient(90deg, var(--nxa-prov-established) 50%, transparent 50%);
                       box-shadow: inset 0 0 0 1.5px var(--nxa-prov-established); }
.nxa-pm--proposed    { border: 1.5px dashed var(--nxa-prov-proposed); }
.nxa-pm--unresolved  { width: 7px; height: 1.5px; border-radius: 0; background: var(--nxa-prov-unresolved); transform: translateY(-3px); }

.nxa-proposed   { color: var(--nxa-prov-proposed); }
.nxa-unresolved { color: var(--nxa-prov-unresolved); }
.nxa-superseded { color: var(--nxa-prov-superseded); text-decoration: line-through; }

/* the exact status, always rendered beside the mark — never the mark alone */
.nxa-status { font-family: var(--nxa-mono); font-size: 10px; letter-spacing: .06em; color: var(--nxa-ink-3); }

/* ── the NXA plate ─────────────────────────────────────────────────────
   The authoritative mark is typeset, not an asset. Geometry read from the
   live impactnexia.com CSS, 2026-09-21; the .14em compensation and the
   .05em cap-height shift (top .5em / bottom .45em) are both deliberate.
   The plate is proportioned to the word — never a fixed square, never
   radiused. See DEC_2026-09-22_imm-ui-open-questions-resolved.md. */
.nxa-mark {
  display: inline-block;
  border-radius: 0;
  line-height: 1;
  font-family: var(--nxa-mono);
  font-weight: 700;
  letter-spacing: var(--nxa-mark-tracking);
  background: var(--nxa-brand);
  color: var(--nxa-ground);
  padding: .5em .8em .45em calc(.8em + var(--nxa-mark-tracking));
}
/* #1F4F4A on #1D2227 does not hold contrast, so dark chrome inverts the
   plate to mint. A deliberate adaptation, not drift. */
.nxa-mark--on-dark { background: var(--nxa-mint); color: var(--nxa-near-black); }

/* wide content never scrolls the page sideways */
.nxa-scroll-x { overflow-x: auto; }

:where(a, button, [tabindex]):focus-visible {
  outline: 2px solid var(--nxa-brand);
  outline-offset: 2px;
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: .001ms !important; transition-duration: .001ms !important; }
}
