/* ITZA Tab - design system: tokens, themes, base.
 *
 * A receipt keeper that must not look like accounting software. The hero
 * content is PHOTOGRAPHS OF RECEIPTS - off-white, crumpled, visually noisy.
 * On a light near-white chrome they read as scanning artefacts; on deep
 * neutrals they read as objects, specimens, things you own. So the default
 * theme is a deep navy-neutral, and premium here means restraint and depth,
 * not decoration (spec 8.2).
 *
 * TOKEN ARCHITECTURE IS THE HOUSE STANDARD, VERBATIM IN NAME AND ROLE. The
 * names were paid for in measurement and device bugs; components lifted
 * from the app this was ported from keep working because
 * --ink/--paper/--muted/--rule/--accent/--surface mean the same thing here.
 * Only the VALUES are Tab's own.
 *
 * ONE ACCENT, RESERVED. The house pattern spends --gold on verification and provenance
 * and on nothing else. In Tab that is the subject of the product, so the
 * same discipline costs more to break, not less: --gold marks the seal, the
 * proof, the provenance moment - never ordinary chrome. Chrome actions ride
 * --accent, which is the wordmark's own dark-context blue, so the one
 * screen-wide constant (the blue-and-gold mark, spec 8.1) has nothing to
 * fight with.
 *
 * NO WEB FONTS FROM ANY REMOTE ORIGIN. The three woff2 files ship inside
 * our own upload (../fonts/) and are precached by the service worker; the
 * stacks below fall back to what is already on the device.
 *
 * CONTRAST, MEASURED (WCAG 2.1 relative luminance), against each theme's
 * OWN reading surfaces - the pane paper AND the lifted card surface,
 * because body text sits on both. Floor: 4.5:1 for body-size text, 3:1 for
 * large-UI-only tokens. Do not re-derive these; if you change a value,
 * re-measure and re-record it here.
 *
 *   DEEP (default)  paper #14181f  surface #1b212b
 *     --ink    #e9e7e2  14.40:1 paper  13.08:1 surface
 *     --muted  #9aa4b2   7.06:1 paper   6.41:1 surface
 *     --blue   #6fb3ff   8.11:1 paper   7.37:1 surface
 *     --blue-bright #8ec6ff  9.89:1  (large UI and focus only)
 *     --navy   #aac4e4   9.94:1 paper   9.03:1 surface
 *     --gold   #f5c711  11.07:1 paper  10.05:1 surface (passes as text here)
 *     --gold-ink = --gold on this theme
 *     --accent #4d9bff with --accent-ink #081524: 6.52:1 on the fill
 *     --danger #ff8a80   7.79:1 paper   7.08:1 surface
 *
 *   PAPER (light)   paper #faf9f6  surface #ffffff
 *     --ink    #171a1f  16.57:1 paper  17.44:1 surface
 *     --muted  #666d79   4.95:1 paper   5.21:1 surface
 *     --blue   #0b6ad4   4.95:1 paper   5.22:1 surface
 *     --blue-bright #0c7ffb  3.66:1  (large UI and focus ONLY - below 4.5)
 *     --navy   #1c3a5e  10.98:1 paper  11.56:1 surface
 *     --gold   #f5c711   1.53:1  NEVER TEXT on this theme - marks, edges
 *              and fills behind dark ink only. Gold TEXT uses --gold-ink.
 *     --gold-ink #7a5c00  5.94:1 paper   6.25:1 surface
 *     --accent #1c3a5e with --accent-ink #ffffff: 11.56:1 on the fill
 *     --danger #c62828   5.34:1 paper   5.62:1 surface
 *
 *   DARK (true dark)  paper #0d0f13  surface #161a20
 *     --ink    #e8e6e1  15.38:1 paper  14.00:1 surface
 *     --muted  #9aa1ad   7.38:1 paper   6.71:1 surface
 *     --blue   #6fb3ff   8.74:1 paper   7.96:1 surface
 *     --blue-bright #8ec6ff 10.66:1  (large UI and focus only)
 *     --navy   #a9c6e8  10.90:1 paper   9.92:1 surface
 *     --gold   #f5c711  11.93:1 paper  10.86:1 surface (passes as text here)
 *     --accent #4d9bff with --accent-ink #081524: 6.52:1 on the fill
 *     --danger #ff8a80   8.40:1 paper   7.65:1 surface
 *
 *   HC (high contrast)  paper #ffffff  surface #ffffff
 *     --ink    #000000  21.00:1
 *     --muted  #3a3a3a  11.37:1
 *     --blue   #0033cc   8.95:1
 *     --navy   #000000  21.00:1
 *     --gold   #a06f00   4.40:1  (large UI and the mark; text uses --gold-ink)
 *     --gold-ink #6b4e00  7.74:1
 *     --accent #000000 with --accent-ink #ffffff: 21.00:1
 *     --danger #8c0000   9.93:1
 *
 *   INK PLACED ON A GOLD FILL (--on-gold, for the rare gold-filled
 *   control such as the undo toast action):
 *     #3a2b04 on the #f5c711 fill: 8.55:1 (deep, paper, dark)
 *     #000000 on the #a06f00 fill: 4.77:1 (hc)
 *
 *   THE WORDMARK (house standard, spec 8.1; all large-UI, floor 3:1):
 *     #4d9bff ITZA on deep 6.31:1, on dark 6.80:1
 *     #0c7ffb ITZA on paper 3.66:1 - large UI only, never body text
 *     #f5c711 product word on deep 11.07:1
 *     #ad8009 product word (solid fallback) on paper 3.40:1 - large only
 *     #a06f00 product word on hc 4.40:1
 *     #ffffff on the #c62828 danger fill: 5.62:1 (button labels)
 */

/* The product's voice: Fraunces, self-hosted from this same origin - no
   font CDN, no external stylesheet. Variable weight, latin subset. */
@font-face {
  font-family: 'Fraunces';
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url('../fonts/fraunces-latin.woff2') format('woff2');
}
@font-face {
  font-family: 'Fraunces';
  font-style: italic;
  font-weight: 100 900;
  font-display: swap;
  src: url('../fonts/fraunces-latin-italic.woff2') format('woff2');
}
/* The WORDMARK's face (owner, 2026-09-06): the logo is Roboto - brand,
   not prose. Self-hosted like every face here; variable weight, latin
   subset, used by the brand line alone. */
@font-face {
  font-family: 'Roboto';
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url('../fonts/roboto-latin.woff2') format('woff2');
}
/* The UI face: the chrome - bars, buttons, labels, amounts - speaks the
   product's own voice, not whatever the device defaults to. No italic:
   UI never speaks in it. */
@font-face {
  font-family: 'Instrument Sans';
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url('../fonts/instrument-sans-latin.woff2') format('woff2');
}

:root {
  /* ---- The PAPER default: the light room. Tab greets on the family's
     editorial paper (spec 8.4: the house surface, with dark as a TOGGLE) -
     the deep specimen tray shipped as the door once and read as a crypto
     product (owner, 2026-08-26). It remains one tap away in Look. ---- */
  --ink: #171a1f;
  --paper: #faf9f6;
  --surface: #ffffff;
  --navy: #1c3a5e;
  --gold: #f5c711;         /* THE RESERVED ACCENT: verification, provenance,
                              the seal - and nothing else */
  --gold-ink: #7a5c00;     /* gold that is ALSO legal as text on near-white */
  --on-gold: #3a2b04;      /* ink placed ON a gold fill */
  --rule: #e3e0d8;         /* hairlines */
  --muted: var(--navy);    /* metadata and timestamps wear navy, never
                              grey (owner, 2026-09-03) - each theme's own
                              navy, so dark rooms keep their light ink */
  --blue: #0b6ad4;         /* links and actions as text - 5.0:1 */
  --blue-bright: #0c7ffb;  /* large UI and focus rings only */
  --danger: #c62828;
  --danger-fill: #c62828;
  --ok: #2e7d32;
  --danger-ink: #ffffff;

  --accent: #1c3a5e;       /* chrome actions: navy, beside the mark quietly */
  --accent-ink: #ffffff;
  --frost: rgba(250, 249, 246, 0.82);   /* translucent bars over content */
  /* The one piece of decoration: a quiet navy band for the first-run art
     disc and the lock screen. Navy on purpose - it can sit beside the
     blue-and-gold mark on every theme without arguing with it. */
  --hero-art: linear-gradient(160deg, #0b2a4a 0%, #14508c 55%, #2e7dc4 100%);

  /* Two shadows only, navy-tinted on the light surface (spec 8.2); the
     deep themes carry true dark shadows because navy tint is invisible
     there. */
  --shadow-card: 0 1px 2px rgba(11, 42, 74, 0.06), 0 8px 24px rgba(11, 42, 74, 0.08);
  --shadow-float: 0 2px 6px rgba(11, 42, 74, 0.14), 0 12px 32px rgba(11, 42, 74, 0.18);

  /* ---- Type. Three faces, same roles as the house pattern. --body-size and
     --measure are in REM ON PURPOSE: the text-size setting scales the
     root, so characters-per-line stays constant at every size. 42rem is
     ~65 characters - the classic reading measure; 34rem shipped once
     upstream and read as visibly cramped. ---- */
  --serif-display: 'Fraunces', 'Hoefler Text', 'Baskerville Old Face', Baskerville,
    'Times New Roman', serif;
  --serif-body: 'Fraunces', 'Iowan Old Style', 'Palatino Linotype', Palatino, Charter,
    'Bitstream Charter', 'Source Serif Pro', serif;
  --sans: 'Instrument Sans', system-ui, -apple-system, 'Segoe UI', Roboto,
    Helvetica, Arial, sans-serif;
  --measure: 42rem;
  --body-size: 1.25rem;
  --leading: 1.65;

  /* ---- Shape and motion, verbatim from spec 8.2. ---- */
  --r-sm: 8px;
  --r-md: 12px;
  --r-lg: 16px;
  --r-full: 999px;

  --m-tap: 90ms;           /* response to touch under 100ms, always */
  --m-quick: 160ms;
  --m-enter: 280ms;
  --m-exit: 240ms;
  --ease-enter: cubic-bezier(0.32, 0.72, 0, 1);
  --ease-exit: cubic-bezier(0.4, 0, 1, 1);

  /* ---- Layout tokens that solve real device bugs (spec 8.2 / 14).
     Use the tokens; do not reinvent the measurements. ---- */
  --safe-t: env(safe-area-inset-top, 0px);
  --safe-b: env(safe-area-inset-bottom, 0px);
  --safe-l: env(safe-area-inset-left, 0px);
  --safe-r: env(safe-area-inset-right, 0px);
  --kb: 0px;               /* keyboard inset, written by nav.js */
  --bar-h: 62px;           /* the floating dock */
  --dock: calc(var(--bar-h) + var(--safe-b) + 20px);
}

/* The default theme also answers to its NAME, so Settings can write
   data-theme='paper' explicitly and land on exactly the boot palette;
   deep keeps its name as the chosen specimen-tray look. */
html[data-theme='deep'] {
  --ink: #e9e7e2;
  --paper: #14181f;
  --surface: #1b212b;
  --navy: #aac4e4;
  --gold: #f5c711;
  --gold-ink: #f5c711;
  --on-gold: #3a2b04;
  --rule: #2a3140;
  --muted: var(--navy);
  --blue: #6fb3ff;
  --blue-bright: #8ec6ff;
  --danger: #ff8a80;
  --danger-fill: #c62828;
  --ok: #81c995;
  --danger-ink: #ffffff;
  --accent: #4d9bff;
  --accent-ink: #081524;
  --frost: rgba(20, 24, 31, 0.82);
  --hero-art: linear-gradient(160deg, #0b1524 0%, #163252 55%, #1d4a7a 100%);
  --shadow-card: 0 1px 2px rgba(0, 0, 0, 0.35), 0 8px 24px rgba(0, 0, 0, 0.35);
  --shadow-float: 0 2px 6px rgba(0, 0, 0, 0.45), 0 12px 32px rgba(0, 0, 0, 0.5);
}

/* PAPER: the light room. Warm near-white, navy structure, and the gold
   DEEPENS wherever it must be read (--gold-ink) because brand gold on
   near-white is illegible - same rule the wordmark obeys. */
html[data-theme='paper'] {
  --ink: #171a1f;
  --paper: #faf9f6;
  --surface: #ffffff;
  --navy: #1c3a5e;
  --gold: #f5c711;
  --gold-ink: #7a5c00;
  --on-gold: #3a2b04;
  --rule: #e3e0d8;
  --muted: var(--navy);
  --blue: #0b6ad4;
  --blue-bright: #0c7ffb;
  --danger: #c62828;
  --danger-fill: #c62828;
  --ok: #2e7d32;
  --danger-ink: #ffffff;
  --accent: #1c3a5e;
  --accent-ink: #ffffff;
  --frost: rgba(250, 249, 246, 0.82);
  --hero-art: linear-gradient(160deg, #0b2a4a 0%, #14508c 55%, #2e7dc4 100%);
  --shadow-card: 0 1px 2px rgba(11, 42, 74, 0.06), 0 8px 24px rgba(11, 42, 74, 0.08);
  --shadow-float: 0 2px 6px rgba(11, 42, 74, 0.14), 0 12px 32px rgba(11, 42, 74, 0.18);
}

/* DARK: true dark, for the people who ask for it by name (the settings
   toggle, spec 8.4). Same hierarchy as deep, lower floor - never an
   inversion, so gold still means exactly one thing. */
html[data-theme='dark'] {
  --ink: #e8e6e1;
  --paper: #0d0f13;
  --surface: #161a20;
  --navy: #a9c6e8;
  --gold: #f5c711;
  --gold-ink: #f5c711;
  --on-gold: #3a2b04;
  --rule: #262b33;
  --muted: var(--navy);
  --blue: #6fb3ff;
  --blue-bright: #8ec6ff;
  --danger: #ff8a80;
  --danger-fill: #c62828;
  --ok: #81c995;
  --danger-ink: #ffffff;
  --accent: #4d9bff;
  --accent-ink: #081524;
  --frost: rgba(13, 15, 19, 0.82);
  --hero-art: linear-gradient(160deg, #081020 0%, #102844 55%, #16406e 100%);
  --shadow-card: 0 1px 2px rgba(0, 0, 0, 0.4), 0 8px 24px rgba(0, 0, 0, 0.5);
  --shadow-float: 0 2px 6px rgba(0, 0, 0, 0.5), 0 12px 32px rgba(0, 0, 0, 0.6);
}

/* HC: pure black on pure white. Flat fills, hard lines, no translucency -
   frost at 0.95 so bars stay bars without ghosting text beneath them. */
html[data-theme='hc'] {
  --ink: #000000;
  --paper: #ffffff;
  --surface: #ffffff;
  --navy: #000000;
  --gold: #a06f00;
  --gold-ink: #6b4e00;
  --on-gold: #000000;
  --rule: #000000;
  --muted: var(--navy);
  --blue: #0033cc;
  --blue-bright: #0033cc;
  --danger: #8c0000;
  --danger-fill: #8c0000;
  --ok: #006400;
  --danger-ink: #ffffff;
  --accent: #000000;
  --accent-ink: #ffffff;
  --frost: rgba(255, 255, 255, 0.95);
  --hero-art: linear-gradient(160deg, #000000 0%, #000000 100%);
  --shadow-card: 0 1px 2px rgba(11, 42, 74, 0.06), 0 8px 24px rgba(11, 42, 74, 0.08);
  --shadow-float: 0 2px 6px rgba(11, 42, 74, 0.14), 0 12px 32px rgba(11, 42, 74, 0.18);
}

/* ---------------------------------------------------------------------
   The root: text scale, measure, motion
   --------------------------------------------------------------------- */

/* THE VIEWPORT GUARD. `clip` clips horizontal overflow WITHOUT creating a
   scroll container, so position:sticky keeps working - and no single
   overflowing row can ever widen the mobile layout viewport and drag
   every fixed overlay off the screen with it (a hard-won rule upstream). */
html, body { overflow-x: hidden; overflow-x: clip; }

/* THE TEXT SCALE: one root multiplier drives every rem in the app, chosen
   on a live sample at first run and mirrored in Settings. NEVER a px
   root - calc(100% * scale) keeps the browser's and the OS's own text
   scaling underneath instead of discarding them. The 200ms ease previews
   a step change as one movement; reduced motion snaps. */
html {
  font-size: calc(100% * var(--text-scale, 1));
  transition: font-size 200ms ease;
  -webkit-text-size-adjust: 100%;
}
html[data-motion='reduce'] { transition: none; }
/* 'off' is the third motion setting (spec 8.4): reduced means reduced,
   off means OFF - it rides every reduce rule below via the shared
   attribute prefix, and nav.js additionally stands View Transitions
   down for both. */
html[data-motion='off'] { transition: none; }

/* Density (the Look pane's narrow/normal/wide): the measure moves, the
   type does not - receipts need the wide room more than prose did. */
html[data-measure='narrow'] { --measure: 34rem; }
html[data-measure='wide'] { --measure: 48rem; }

/* A reader who asked for less motion gets it whether or not the OS
   knows. Both signals kill everything: reduced means reduced. */
html[data-motion='reduce'] *,
html[data-motion='reduce'] *::before,
html[data-motion='reduce'] *::after,
html[data-motion='off'] *,
html[data-motion='off'] *::before,
html[data-motion='off'] *::after {
  animation-duration: 0.001ms !important;
  transition-duration: 0.001ms !important;
}
@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
    scroll-behavior: auto !important;
  }
}

/* ---------------------------------------------------------------------
   Base
   --------------------------------------------------------------------- */

* { box-sizing: border-box; }

html, body {
  margin: 0;
  padding: 0;
  height: 100%;
  overflow: hidden;               /* the document never scrolls; panes do */
  overscroll-behavior: none;      /* no accidental pull-to-refresh on the shell */
  touch-action: manipulation;     /* kills double-tap zoom delay on chrome */
  background: var(--paper);
  color: var(--ink);
  -webkit-font-smoothing: antialiased;
}

body {
  font-family: var(--sans);
  font-size: 1rem;
  line-height: var(--leading);
}

/* ---------------------------------------------------------------------
   Killing the web tells (spec 8.3) - a browser tell is a bug
   --------------------------------------------------------------------- */

* { -webkit-tap-highlight-color: transparent; }   /* no blue flash on tap */

/* Chrome and controls are not selectable and long-press raises OUR menu,
   not the browser's... */
body {
  user-select: none;
  -webkit-user-select: none;
  -webkit-touch-callout: none;
}

/* ...but CONTENT stays selectable, because people copy amounts and
   merchant names - an app you cannot copy a total out of is a cage. */
.selectable, .content,
.rcpt-line, .rcpt-mod,
.rc-merchant, .rc-amt,
.rv-val, .own-name, .month-total, .keybox,
input, textarea, [contenteditable], [contenteditable='plaintext-only'] {
  user-select: text;
  -webkit-user-select: text;
  -webkit-touch-callout: default;
}

/* A phone shows no scrollbar - a thumb needs none and the bar would only
   cover the paper. A POINTER IS NOT A THUMB: without a bar a mouse with
   no wheel cannot move the page at all, so wherever a fine pointer
   lives, a thin bar in the paper's own ink comes back. */
.pane, .sheet, [data-scroll] {
  overscroll-behavior: contain;             /* a panel's scroll stays inside it */
  -webkit-overflow-scrolling: touch;        /* momentum everywhere */
  scrollbar-width: none;
  -ms-overflow-style: none;
}
.pane::-webkit-scrollbar,
.sheet::-webkit-scrollbar,
[data-scroll]::-webkit-scrollbar { display: none; }

@media (hover: hover) and (pointer: fine) {
  .pane, .sheet, [data-scroll] { scrollbar-width: thin; scrollbar-color: var(--rule) transparent; }
  .pane::-webkit-scrollbar,
  .sheet::-webkit-scrollbar,
  [data-scroll]::-webkit-scrollbar { display: block; width: 10px; }
  .pane::-webkit-scrollbar-track,
  .sheet::-webkit-scrollbar-track,
  [data-scroll]::-webkit-scrollbar-track { background: transparent; }
  .pane::-webkit-scrollbar-thumb,
  .sheet::-webkit-scrollbar-thumb,
  [data-scroll]::-webkit-scrollbar-thumb {
    background: var(--rule);
    border: 3px solid transparent;
    background-clip: content-box;
    border-radius: var(--r-full);
  }
}

/* Focus, in two registers. CONTROLS - things you press - keep a visible
   ring: keyboard users navigate by it, and 3:1 against any surface is
   what --blue-bright exists to meet. FIELDS - things you type into -
   show focus with the caret plus a quiet border shift; a ring around a
   text field says "form" where the design should say "your receipt". */
:focus { outline: none; }
:focus-visible { outline: 2px solid var(--blue-bright); outline-offset: 2px; }
input:focus-visible, textarea:focus-visible {
  outline: none;
  border-color: var(--blue);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--blue-bright) 15%, transparent);
}
/* The pane holds the keyboard so arrows can scroll it - it is a surface,
   not a control; a ring around the whole screen would say otherwise. */
.pane:focus, .pane:focus-visible { outline: none; }

/* THE NATIVE DROPDOWN LIST IS THE OS'S, NOT THE THEME'S: a <select>
   popup paints on the OS's own list surface, but the OPTIONS inherit the
   control's themed ink - pale ink on a light OS list is invisible text.
   Options carry their own explicit pair and never inherit. */
select option {
  color: #1b2030;
  background: #ffffff;
}

/* ---------------------------------------------------------------------
   The wordmark - the HOUSE STANDARD (spec 8.1). Copied from the .brand
   block this was ported from, which mirrors the marketing site; the
   product word is the only change. ITZA in corporate blue runs straight
   into Tab in gold, no space. The DEFAULT here is the dark-context pair
   because Tab's default theme is deep; paper flips to the light-context
   pair, exactly the same shift made in the other direction there.
   --------------------------------------------------------------------- */

.brand {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  /* The logo speaks Roboto (owner, 2026-09-06); everything else keeps
     the house voices. */
  font-family: 'Roboto', var(--sans);
  font-size: 1.05rem;
  text-decoration: none;
  letter-spacing: -0.01em;
}

.brand-mark { width: 22px; height: 22px; }
/* The wordmark IS the logo wherever it stands - top bar, sign-in,
   anywhere - so the face rides the mark itself, outranking any
   surface's own voice (owner, 2026-09-06: Roboto). */
.wm { white-space: nowrap; font-family: 'Roboto', var(--sans); }
.wm-itza { color: #0c7ffb; font-weight: 600; }
/* The product word is GOLD - metal, not mustard. A flat gold read as
   brown upstream; real gold is a gradient, deep gold into a bright
   specular band and back, the same play of light the pyramid mark has.
   The solid colour stays as the fallback for engines without
   background-clip: text. On near-white the gold runs DEEP - brand gold
   on paper is illegible; same values, same reasons, as the site. */
.wm-prod { color: #ad8009; font-weight: 800; }
@supports (-webkit-background-clip: text) or (background-clip: text) {
  .wm-prod {
    background-image: linear-gradient(105deg,
      #8a6206 0%, #c99a10 22%, #f9df6d 40%, #f5c711 52%,
      #a67c08 72%, #e0b312 88%, #b98a0a 100%);
    -webkit-background-clip: text;
    background-clip: text;
    color: transparent;
  }
}
/* On the deep and dark grounds ITZA lifts to the dark-context blue and
   the gold brightens back to full brand gold. */
html[data-theme='deep'] .wm-itza,
html[data-theme='dark'] .wm-itza { color: #4d9bff; }
html[data-theme='deep'] .wm-prod,
html[data-theme='dark'] .wm-prod { color: #f5c711; }
@supports (-webkit-background-clip: text) or (background-clip: text) {
  html[data-theme='deep'] .wm-prod,
  html[data-theme='dark'] .wm-prod {
    background-image: linear-gradient(105deg,
      #b98a0a 0%, #f5c711 25%, #ffe98a 42%, #f5c711 55%,
      #c99a10 75%, #ffd83d 90%, #e0b312 100%);
    color: transparent;
  }
}

/* ---------------------------------------------------------------------
   Money is legible (spec 8.1): tabular numerals, right-aligned amounts.
   These cooperate with receipt.css (.rcpt-line/.rcpt-amt already carry
   tabular-nums for the line items); .amt is the same discipline for
   every OTHER figure - totals, month sums, prices in the grid.
   --------------------------------------------------------------------- */

.num { font-variant-numeric: tabular-nums; }
.amt {
  font-family: var(--sans);
  font-variant-numeric: tabular-nums;
  text-align: right;
  white-space: nowrap;
}
/* A figure that has not arrived from the chain renders as '-', never a
   default or a zero; dimmed, so pending is visibly pending rather than
   a real result of nothing. */
.figure { font-family: var(--sans); font-variant-numeric: tabular-nums; }
.figure.pending { color: var(--muted); }

/* ---------------------------------------------------------------------
   Small shared text utilities
   --------------------------------------------------------------------- */

/* Sentences that must be READ on every theme ride softened ink,
anchored
   to the two contrast-defined tokens - --muted is theme flavour and may
   sink; prose may not. The plain --ink line is the fallback for engines
   without color-mix. */
.se-note,
.setNote {
  color: var(--ink);
  /* Navy, never a grey wash (owner, 2026-09-03: every grey font goes
     navy) - the same per-theme token the metadata wears. */
  color: var(--muted);
}
.se-note { font-size: 0.8rem; }
.setNote { font-size: 0.74rem; line-height: 1.5; margin: 0.4rem 0 0.8rem; }

/* Screen-reader-only live region (the calibrator announces its steps). */
.sr-live {
  position: absolute;
  width: 1px; height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
}

/* The font setting (spec 8.4): three named faces, each re-pointing the
   body face token only - display and UI faces hold, so the wordmark and
   chrome never change costume with the reading face. */
html[data-font='sans'] { --serif-body: var(--sans); }
html[data-font='system'] { --serif-body: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; }
