/* ============================================================================
   typography/tokens.css — the single authoritative typography token layer.

   §23 names this apps/web/src/styles/typography/tokens.css. That tree holds no
   application source (0 modules), so the real location is lib/typography/ and
   the mapping is recorded in docs/design/TYPOGRAPHY-SYSTEM.md.

   WHY THIS FILE EXISTS, AND WHY IT IS NOT "ANOTHER OVERRIDE LAYER"

   The audit measured three competing definitions for every size token:

       --f-sm : 12px
              | calc(var(--fbody) * 0.88 * var(--mult-sub,1))     -> 11.44px
              | max(12px, round(calc(var(--fbody) * 0.88 ...), 1px))
       --f-xs : 11px | calc(var(--fbody) * 0.80 ...) | max(11px, round(...))
       --f-rd : 13px | calc(var(--fbody) * 0.94)     | max(13px, round(...))
       --f-lg , --f-xl , --f-num : the same three-way split

   Whichever stylesheet loaded last decided the value, which is how 11.5px,
   12.5px and 14.56px reached the screen.

   This file does NOT fight the cascade. Custom properties are resolved by
   value, not by specificity: a rule that already says `font-size: var(--f-sm)`
   — even `!important`, even from an unscoped selector — simply computes a
   whole pixel once this file defines --f-sm once. So 368 !important winners
   keep winning, and start computing correct sizes. No new !important is added
   here. Not one declaration in this file is !important.

   What this file cannot fix is a LITERAL fractional size written into a rule
   (`font-size: 12.5px`). Those are corrected at source; they are listed in
   docs/design/TYPOGRAPHY-CONFLICTS.md §A5.

   NOTHING HERE TOUCHES ACCOUNTING. No value, figure, posting or report number
   depends on a typography token.
   ========================================================================== */

:root {
  /* ---- families ---------------------------------------------------------
     Two families, as the contract allows. The stacks end in a real system
     fallback so a failed font load degrades to something readable rather
     than to a default serif. */
  --font-ui:       'Inter Tight', Inter, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, system-ui, sans-serif;
  --font-report:   var(--font-ui);
  --font-document: var(--font-ui);
  --font-code:     'IBM Plex Mono', ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  --font-numeric:  var(--font-ui);

  /* legacy aliases still referenced across lib/*.css and inline styles, so
     they resolve to the contract families instead of to a stray stack */
  --fmono: var(--font-code);
  --fnum:  var(--font-numeric);

  /* ---- size scale — whole pixels only (§5) ------------------------------ */
  /* no --text-2xs. §6 puts the floor at 11px for anything a user reads,
     and the chart module was the only caller. */
  --text-xs:  11px;
  --text-sm:  12px;
  --text-md:  13px;
  --text-lg:  14px;
  --text-xl:  16px;
  --text-2xl: 20px;
  --text-3xl: 24px;

  /* ---- the legacy size tokens, consolidated to ONE definition each -------
     These names are used by hundreds of existing rules. Redefining them here
     is what removes the fractional sizes without editing those rules. The
     values match the scale above, and each is the whole-pixel intent of the
     multiplier it replaces (0.80*13=10.4 -> 11px; 0.88*13=11.44 -> 12px;
     0.94*13=12.22 -> 13px; 1.08*13=14.04 -> 14px; 1.24*13=16.12 -> 16px). */
  --f-2xs: var(--text-xs);   /* was 0.72*13 = 9.36px; the floor is 11px */
  --f-xs:  var(--text-xs);
  --f-sm:  var(--text-sm);
  --f-md:  var(--text-md);
  --f-rd:  var(--text-md);
  --f-lg:  var(--text-lg);
  --f-xl:  var(--text-xl);
  --f-2xl: var(--text-2xl);
  --f-num: var(--text-3xl);

  /* ---- line heights ------------------------------------------------------ */
  --leading-tight:   1.2;
  --leading-control: 1.25;
  --leading-body:    1.45;
  --leading-table:   1.35;
  --leading-relaxed: 1.6;

  /* ---- weights — only the four the contract allows ---------------------- */
  --weight-regular:  400;
  --weight-medium:   500;
  --weight-semibold: 600;
  --weight-bold:     700;

  /* ---- numeric rendering, in one place ---------------------------------- */
  --numeric-variant: tabular-nums lining-nums;
  --numeric-features: "tnum" 1, "lnum" 1;
}

/* ---------------------------------------------------------------------------
   Never let the browser invent a weight or an italic. The Inter Tight file is
   a VARIABLE font carrying real 400-700 (measured: advance widths differ per
   weight and are unchanged with font-synthesis:none), so nothing needs faking
   and faking would only blur it.
   ------------------------------------------------------------------------ */
html {
  font-synthesis-weight: none;
  font-synthesis-style: none;
  font-synthesis-small-caps: none;
}

/* ---------------------------------------------------------------------------
   Figures. One class, used wherever a number must align in a column, so the
   treatment is not re-typed as an inline style each time. `.gl-bf` is the
   brought-forward amount in the General Ledger account header, which used to
   be set in IBM Plex Mono inline (see TYPOGRAPHY-CONFLICTS.md, RPT-01).
   ------------------------------------------------------------------------ */
.jb-figure,
.gl-bf {
  font-family: var(--font-numeric);
  font-variant-numeric: var(--numeric-variant);
  font-feature-settings: var(--numeric-features);
}

/* ---------------------------------------------------------------------------
   Identifiers. IBM Plex Mono belongs here and nowhere else: account codes,
   journal ids, invoice numbers, payment-voucher and tax references, matter
   ids shown as formal identifiers, system document references.
   ------------------------------------------------------------------------ */
.jb-identifier {
  font-family: var(--font-code);
  font-variant-numeric: lining-nums;
  font-feature-settings: "lnum" 1;
}

/* ---------------------------------------------------------------------------
   THE ONE SCOPED BRIDGE, AND WHY IT IS NOT AN !important LAYER

   renderBatch() in lib/journal-entry.js writes two inline styles:

       <input ... oninput="onDateEdit(...)"  style="...font-family:var(--fmono)">
       <input ... oninput="onRefEdit(...)"   style="...font-family:var(--fmono)">

   The reference is a genuine identifier and belongs in mono. The DATE does
   not: §3 forbids monospace on dates outright.

   renderBatch is on the protected-accounting fingerprint list, so it is not
   edited for a typography defect -- the fingerprint must come back identical.
   An inline style also out-ranks any ordinary rule, so the usual fix would be
   an !important override, which §14 rules out.

   Neither is needed. The inline style does not name a font; it names a
   TOKEN. Redefining that token on the element makes the inline style resolve
   to the right family, with no !important, no MutationObserver and no edit to
   a protected function. This is the only rule of its kind in the system; if a
   second one is ever needed, it belongs here beside it, documented the same
   way, not scattered into a new stylesheet.
   ------------------------------------------------------------------------ */
#view-batch .sw-head input[oninput^="onDateEdit"] {
  --fmono: var(--font-ui);
}

/* The same situation once more, and for the same reason. renderLedger() in
   lib/general-ledger.js draws each posting row as

       <td class="mono" ...>2026-01-04</td>   <- the DATE
       <td class="mono" ...>JE000097</td>     <- the journal id

   The journal id is an identifier and belongs in mono. The date does not, and
   §3 says so outright. renderLedger is on the protected fingerprint list, so
   the markup is left alone; the identical cell in glReportHTML(), which is not
   protected, was corrected at source instead.

   Redefining --font-code on the first cell makes the identifier rule
   (`font-family: var(--font-code) !important`) resolve to the interface face
   for that one cell. No !important is added, nothing is observed, and the
   protected function's fingerprint is unchanged. */
#view-ledger .drill-row > td.mono:first-child {
  --font-code: var(--font-ui);
  font-variant-numeric: normal;
}
