/* Theme-agnostic scales. Colors live in themes/*.css (semantic names only). */

/* Self-hosted fonts (latin subset, variable weight, SIL OFL 1.1: fonts/OFL.txt). URLs are relative to the
   stylesheet, so an app that serves /ui/ui.css must also serve /ui/fonts/* (cross-origin: with CORS). */
@font-face { font-family: "Space Grotesk"; font-style: normal; font-weight: 300 700; font-display: swap;
  src: url("fonts/space-grotesk.woff2") format("woff2"); }
@font-face { font-family: "JetBrains Mono"; font-style: normal; font-weight: 100 800; font-display: swap;
  src: url("fonts/jetbrains-mono.woff2") format("woff2"); }
@font-face { font-family: "Newsreader"; font-style: normal; font-weight: 200 800; font-display: swap;
  src: url("fonts/newsreader.woff2") format("woff2"); }
@font-face { font-family: "Newsreader"; font-style: italic; font-weight: 200 800; font-display: swap;
  src: url("fonts/newsreader-italic.woff2") format("woff2"); }

:root {
  --font-mono: "JetBrains Mono", ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  --font-sans: system-ui, -apple-system, "Segoe UI", sans-serif;
  --font-serif: "Newsreader", Georgia, serif;

  /* legacy size names (kept for existing consumers) */
  --text-xs: 11px; --text-sm: 12px; --text-md: 14px; --text-lg: 18px; --text-xl: 28px;

  /* Type scale for new work: meta 11 (mono labels, dates) / small 13 (row metadata) / body 15 /
     lead 17 (serif notes, card titles) / title 24 / display (one focal number per screen). */
  --fs-meta: 11px; --fs-small: 13px; --fs-body: 15px; --fs-lead: 17px; --fs-title: 24px;
  --fs-display: clamp(56px, 17vw, 72px);

  --space-1: 4px; --space-2: 8px; --space-3: 12px;
  --space-4: 16px; --space-5: 24px; --space-6: 32px; --space-7: 48px;

  /* Radii: only these (check.sh flags literal border-radius values). */
  --radius-sm: 4px; --radius: 8px; --radius-lg: 12px; --radius-xl: 20px; --radius-pill: 999px;

  --touch: 44px;   /* minimum tap target */
  --row-h: 52px;   /* list row */
}

/* Layout + text primitives (cf. RyuFlex / RyuPad / RyuText). Use these instead of ad-hoc flex/margin CSS. */
.ui-flex { display: flex; gap: var(--gap, var(--space-2)); align-items: var(--align, center); }
.ui-stack { display: flex; flex-direction: column; gap: var(--gap, var(--space-3)); }
.ui-grid { display: grid; gap: var(--gap, var(--space-3)); grid-template-columns: repeat(auto-fit, minmax(var(--min, 220px), 1fr)); }
.ui-pad { padding: var(--pad, var(--space-4)); }
.ui-spacer { flex: 1; }
.ui-h1 { font: 600 var(--text-xl)/1.2 var(--font-sans); margin: 0; }
.ui-h2 { font: 600 var(--text-lg)/1.3 var(--font-sans); margin: 0; }
.ui-label { font-size: var(--text-xs); text-transform: uppercase; letter-spacing: .08em; color: var(--muted); }

/* Matches davidJ (personal site): warm near-black, bone text, gold accent, rust for errors. */
:root, [data-theme="davidj"] {
  --font-sans: "Space Grotesk", system-ui, sans-serif;
  --font-serif: "Newsreader", Georgia, serif;
  --bg: #14131a;
  --surface: #1c1b25;
  --surface-2: #17161e;
  --surface-3: #24232e;   /* the one raised surface on a screen (focus card, sheet) */
  --line: #2a2933;
  --line-2: #3b3a45;
  --text: #e8e3d8;
  --text-2: #a8a39a;
  --muted: #8a8680;       /* 5.1:1 on --bg (was #7c7971, 4.25:1) */
  --accent: #d4a955;      /* gold: the single primary action or current focus only */
  --ok: #8fb573;          /* deltas / under budget only */
  --bad: #cc6a62;         /* deltas / over budget only; 5.1:1 on --bg */
  --warn: #d4a955;
  --info: #7fa7c4;
  --on-accent: #14131a;
  --purple: #a58bb8;
  --pink: #f2a7bb;        /* celebration / streak accent, used sparingly */
  /* categorical: 8 muted hues for categories and chart series, no semantic meaning */
  --cat-1: #7fa7c4; --cat-2: #c48f6a; --cat-3: #6fae9f; --cat-4: #b48fc0;
  --cat-5: #a9b46a; --cat-6: #d08c9c; --cat-7: #8c95cf; --cat-8: #c2a77d;
  /* diverging: below <- neutral -> above (e.g. vs budget, vs usual) */
  --div-neg-2: #8fb573; --div-neg-1: #5f7a52; --div-mid: #2a2933; --div-pos-1: #8a4c48; --div-pos-2: #cc6a62;
  /* legacy aliases (tokyo-night era names) */
  --blue: var(--accent); --green: var(--ok); --red: var(--bad); --yellow: var(--warn);
}
/* Terminal density sits on a deeper black. */
:root[data-density="terminal"], [data-theme="davidj"][data-density="terminal"] { --bg: #0f0e13; --surface-2: #14131a; }

/* Calm neutral dark: near-black ink, one restrained accent, low saturation status colors. */
[data-theme="ink"] {
  --bg: #111214;
  --surface: #191b1e;
  --surface-2: #151618;
  --line: #26292d;
  --line-2: #363a40;
  --text: #e4e5e7;
  --text-2: #b3b6bb;
  --muted: #7a7f87;
  --accent: #d9a85b;
  --ok: #8fb573;
  --bad: #d0675f;
  --warn: #d9a85b;
  --info: #7fa7c4;
  --on-accent: #111214;
  --surface-3: #202327; --pink: #e8a3b6;
  --cat-1: #7fa7c4; --cat-2: #c48f6a; --cat-3: #6fae9f; --cat-4: #b48fc0;
  --cat-5: #a9b46a; --cat-6: #d08c9c; --cat-7: #8c95cf; --cat-8: #c2a77d;
  --div-neg-2: #8fb573; --div-neg-1: #5f7a52; --div-mid: #26292d; --div-pos-1: #8a4c48; --div-pos-2: #d0675f;
}

/* Warm light: paper background, ink text, one deep accent. */
[data-theme="paper"] {
  --bg: #f5f2ea;
  --surface: #fbf9f3;
  --surface-2: #efebe0;
  --line: #ddd7c8;
  --line-2: #c3bba7;
  --text: #1f1d18;
  --text-2: #4a463c;
  --muted: #837d6d;
  --accent: #2f5d50;
  --ok: #3f7a3a;
  --bad: #b23a2e;
  --warn: #a8741a;
  --info: #2c5f86;
  --on-accent: #fbf9f3;
  --surface-3: #ffffff; --pink: #b8506e;
  --cat-1: #3d6f94; --cat-2: #9a5a34; --cat-3: #2f7a6c; --cat-4: #7d528c;
  --cat-5: #6b7530; --cat-6: #a34d63; --cat-7: #4c58a0; --cat-8: #85683b;
  --div-neg-2: #3f7a3a; --div-neg-1: #9cbb94; --div-mid: #ddd7c8; --div-pos-1: #d9a59e; --div-pos-2: #b23a2e;
}

/* Tokyo Night Dark. Semantic names; legacy names kept as aliases. */
[data-theme="tokyo-night"] {
  --bg: #1a1b26;
  --surface: #24283b;
  --surface-2: #1f2335;
  --line: #2f3549;
  --line-2: #414868;
  --text: #c0caf5;
  --text-2: #a9b1d6;
  --muted: #565f89;
  --accent: #7aa2f7;
  --ok: #9ece6a;
  --bad: #f7768e;
  --warn: #e0af68;
  --info: #7dcfff;
  --on-accent: #1a1b26;
  /* legacy aliases */
  --blue: var(--accent); --purple: #bb9af7; --green: var(--ok);
  --red: var(--bad); --yellow: var(--warn);
  --surface-3: #292e42; --pink: #f4a6c0;
  --cat-1: #7aa2f7; --cat-2: #ff9e64; --cat-3: #73daca; --cat-4: #bb9af7;
  --cat-5: #9ece6a; --cat-6: #f7768e; --cat-7: #7dcfff; --cat-8: #e0af68;
  --div-neg-2: #9ece6a; --div-neg-1: #5a7a3e; --div-mid: #2f3549; --div-pos-1: #9a4a5a; --div-pos-2: #f7768e;
}

/* Shared components. Only semantic tokens; swap a theme file to restyle everything.
   Prefixed ui- so repos can migrate from local .btn/.card one at a time. */
.ui-page { background: var(--bg); color: var(--text); font: var(--text-md)/1.5 var(--font-sans); margin: 0; }
.ui-mono { font-family: var(--font-mono); }
.ui-muted { color: var(--muted); }

/* buttons */
.ui-btn { appearance: none; font: inherit; font-size: var(--text-sm); cursor: pointer;
  padding: var(--space-2) var(--space-4); border-radius: var(--radius);
  border: 1px solid var(--line-2); background: var(--surface); color: var(--text); }
.ui-btn:hover { border-color: var(--accent); }
.ui-btn:disabled { opacity: .5; cursor: default; }
.ui-btn--primary { background: var(--accent); border-color: var(--accent); color: var(--on-accent); }
.ui-btn--ghost { background: transparent; }
.ui-btn--danger { border-color: var(--bad); color: var(--bad); background: transparent; }
.ui-btn--sm { padding: var(--space-1) var(--space-3); font-size: var(--text-xs); }

/* card + stat */
.ui-card { background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius-lg);
  padding: var(--space-4); }
.ui-stat { background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius);
  padding: var(--space-3) var(--space-4); }
.ui-stat__label { color: var(--muted); font-size: var(--text-xs); text-transform: uppercase; letter-spacing: .08em; }
.ui-stat__value { font: 600 var(--text-xl)/1.2 var(--font-mono); }

/* pill (one component; color via modifier) */
.ui-pill { display: inline-block; padding: 1px var(--space-2); border-radius: var(--radius-pill);
  font-size: var(--text-xs); border: 1px solid var(--line-2); color: var(--text-2); }
.ui-pill--ok { color: var(--ok); border-color: var(--ok); }
.ui-pill--bad { color: var(--bad); border-color: var(--bad); }
.ui-pill--warn { color: var(--warn); border-color: var(--warn); }
.ui-pill--info { color: var(--info); border-color: var(--info); }

/* topbar + tabs */
.ui-topbar { display: flex; align-items: center; gap: var(--space-4); padding: var(--space-3) var(--space-5);
  background: var(--surface-2); border-bottom: 1px solid var(--line); }
.ui-tabs { display: flex; gap: var(--space-1); border-bottom: 1px solid var(--line); }
.ui-tab { padding: var(--space-2) var(--space-4); color: var(--muted); cursor: pointer;
  border-bottom: 2px solid transparent; background: none; border-top: 0; border-inline: 0; font: inherit; }
.ui-tab[aria-selected="true"] { color: var(--text); border-bottom-color: var(--accent); }

/* table */
.ui-table { width: 100%; border-collapse: collapse; font-size: var(--text-sm); }
.ui-table th { text-align: left; color: var(--muted); font-weight: 500; padding: var(--space-2) var(--space-3);
  border-bottom: 1px solid var(--line-2); }
.ui-table td { padding: var(--space-2) var(--space-3); border-bottom: 1px solid var(--line); }

/* form */
.ui-input { font: inherit; padding: var(--space-2) var(--space-3); border-radius: var(--radius);
  border: 1px solid var(--line-2); background: var(--surface-2); color: var(--text); }
.ui-input:focus { outline: 2px solid var(--accent); outline-offset: -1px; }

/* modal, toast, spinner (one shadow, one keyframes) */
.ui-modal { position: fixed; inset: 0; display: grid; place-items: center; background: rgb(0 0 0 / .5); }
.ui-modal__box { background: var(--surface); border: 1px solid var(--line-2); border-radius: var(--radius-lg);
  padding: var(--space-5); box-shadow: 0 24px 60px -20px rgb(0 0 0 / .6); max-width: min(90vw, 480px); }
.ui-toast { position: fixed; right: var(--space-4); bottom: var(--space-4); padding: var(--space-3) var(--space-4);
  background: var(--surface); border: 1px solid var(--line-2); border-radius: var(--radius); }
.ui-spinner { width: 16px; height: 16px; border-radius: 50%; border: 2px solid var(--line-2);
  border-top-color: var(--accent); animation: ui-spin .8s linear infinite; }
@keyframes ui-spin { to { transform: rotate(360deg); } }

/* =====================================================================================
   v2 base (additive; nothing above changed). Flat lists on hairlines, one focal number,
   sans numerals with tabular figures, mono only for small metadata. Densities:
   default ("ledger"), [data-density="terminal"] (mono, square, tight) and
   [data-density="simple"] (big, rounded, few numbers). Set data-density on <html>.
   ===================================================================================== */

/* app shell: put on <body> (does not touch .ui-page users) */
.ui-app { margin: 0; background: var(--bg); color: var(--text); font: var(--fs-body)/1.5 var(--font-sans);
  font-variant-numeric: tabular-nums lining-nums; -webkit-font-smoothing: antialiased; accent-color: var(--accent); }
.ui-app a { color: inherit; }
.ui-app :focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/* type */
.ui-num { font-family: var(--font-sans); font-variant-numeric: tabular-nums lining-nums; }
.ui-eyebrow { font: 500 var(--fs-meta)/1.4 var(--font-mono); letter-spacing: .12em; text-transform: uppercase;
  color: var(--text-2); }
.ui-meta { font: var(--fs-meta)/1.4 var(--font-mono); color: var(--muted); }
.ui-note { margin: 0; font: italic var(--fs-lead)/1.4 var(--font-serif); color: var(--text-2); }
.ui-title { margin: 0; font: 500 var(--fs-title)/1.15 var(--font-sans); letter-spacing: -.01em; }
.ui-pos { color: var(--ok); } .ui-neg { color: var(--bad); }   /* deltas only, never balances */

/* the one focal number per screen: <div class="ui-display">$78<span class="ui-display__unit">/day</span></div> */
.ui-display { display: flex; align-items: baseline; gap: .1em; margin: 0; font: 500 var(--fs-display)/.95 var(--font-sans);
  letter-spacing: -.03em; font-variant-numeric: tabular-nums lining-nums; color: var(--text); }
.ui-display__unit { font-size: .38em; letter-spacing: 0; color: var(--text-2); }
.ui-display.ui-pos, .ui-panel__v.ui-pos, .ui-tile__v.ui-pos { color: var(--ok); }
.ui-display.ui-neg, .ui-panel__v.ui-neg, .ui-tile__v.ui-neg { color: var(--bad); }

/* section header: label left, total or link right */
.ui-sechead { display: flex; justify-content: space-between; align-items: baseline; gap: var(--space-3);
  padding-bottom: var(--space-2); font: 500 var(--fs-meta)/1.4 var(--font-mono); letter-spacing: .12em;
  text-transform: uppercase; color: var(--text-2); }
.ui-sechead a, .ui-sechead button { font: var(--fs-small)/1.4 var(--font-sans); letter-spacing: 0; text-transform: none;
  color: var(--text-2); text-decoration: none; background: none; border: 0; padding: 0; cursor: pointer; }
.ui-sechead a:hover, .ui-sechead button:hover { color: var(--text); }
.ui-sechead :is(a, button) { padding: 12px 0; margin: -12px 0; }   /* 44px hit area, same visual height */

/* list of rows on hairlines: label left, amount right */
.ui-list { display: flex; flex-direction: column; margin: 0; padding: 0; list-style: none; }
.ui-row { display: flex; justify-content: space-between; align-items: center; gap: var(--space-3);
  min-height: var(--row-h); padding: var(--space-2) 0; border-top: 1px solid var(--line); color: var(--text);
  text-decoration: none; font-variant-numeric: tabular-nums lining-nums; }
.ui-list > .ui-row:last-child { border-bottom: 1px solid var(--line); }
a.ui-row, button.ui-row { cursor: pointer; width: 100%; background: none; border-inline: 0; border-bottom: 0; font: inherit; text-align: left; }
a.ui-row:hover .ui-row__title, button.ui-row:hover .ui-row__title { color: var(--accent); }
.ui-row__main { display: flex; flex-direction: column; min-width: 0; flex: 1 1 auto; }
.ui-row__lead { display: flex; align-items: center; gap: var(--space-3); min-width: 0; flex: 1 1 auto; }
.ui-row__title { font-size: var(--fs-body); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ui-row__meta { font-size: var(--fs-small); color: var(--muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ui-row__meta--wrap { white-space: normal; overflow: visible; }
.ui-row__amt { flex: 0 0 auto; font-size: var(--fs-body); text-align: right; white-space: nowrap; }
.ui-row__amt small { display: block; font-size: var(--fs-small); color: var(--muted); }
.ui-row__flag { flex: 0 0 auto; width: 3px; align-self: stretch; margin: var(--space-1) 0; background: var(--accent); }
.ui-row--kv { min-height: var(--touch); }
.ui-row--kv > :first-child { font-size: var(--fs-small); color: var(--text-2); }
.ui-dot { display: inline-block; flex: 0 0 auto; width: 8px; height: 8px; border-radius: var(--radius-pill);
  background: var(--c, var(--muted)); }

/* raised surface: at most one per screen */
.ui-raised { background: var(--surface); border-radius: var(--radius-lg); padding: var(--space-4); }

/* empty state */
.ui-empty { margin: 0; padding: var(--space-4) 0; border-top: 1px solid var(--line);
  font: italic var(--fs-body)/1.45 var(--font-serif); color: var(--muted); }

/* segmented control: buttons/links with aria-pressed|aria-selected|aria-current|.on */
.ui-seg { display: inline-flex; gap: 2px; padding: 2px; max-width: 100%; overflow-x: auto; scrollbar-width: none;
  border: 1px solid var(--line-2); border-radius: var(--radius); background: var(--surface-2); }
.ui-seg::-webkit-scrollbar { display: none; }
.ui-seg > * { appearance: none; flex: 0 0 auto; display: inline-flex; align-items: center; justify-content: center;
  min-height: 32px; padding: 0 var(--space-3); border: 0; border-radius: var(--radius-sm); background: none;
  font: inherit; font-size: var(--fs-small); color: var(--text-2); text-decoration: none; white-space: nowrap; cursor: pointer; }
.ui-seg > :hover { color: var(--text); }
.ui-seg > [aria-pressed="true"], .ui-seg > [aria-selected="true"], .ui-seg > [aria-current], .ui-seg > .on {
  background: var(--surface-3); color: var(--text); }
@media (pointer: coarse) { .ui-seg > * { min-height: 40px; } }

/* buttons: touch-size and quiet variants for .ui-btn */
.ui-btn--lg { min-height: var(--touch); padding: 0 var(--space-4); font-size: var(--fs-small); font-weight: 500; }
.ui-btn--quiet { background: none; border-color: transparent; color: var(--text-2); }
.ui-btn--quiet:hover { color: var(--text); border-color: transparent; }
.ui-btn--solid { background: var(--text); border-color: var(--text); color: var(--bg); }

/* form controls: .ui-controls themes every native input/select/textarea inside it */
.ui-controls { accent-color: var(--accent); color-scheme: dark; }
[data-theme="paper"] .ui-controls, .ui-controls[data-theme="paper"] { color-scheme: light; }
.ui-controls :where(input:not([type="checkbox"], [type="radio"], [type="range"], [type="color"], [type="file"], [type="hidden"]), select, textarea),
.ui-select, .ui-textarea {
  box-sizing: border-box; min-height: var(--touch); padding: 0 var(--space-3); font: inherit; font-size: 16px;
  color: var(--text); background: var(--surface-2); border: 1px solid var(--line-2); border-radius: var(--radius); }
.ui-controls :where(textarea), .ui-textarea { padding: var(--space-2) var(--space-3); min-height: 88px; }
.ui-controls :where(select), .ui-select { appearance: none; padding-right: 32px; background-repeat: no-repeat;
  background-image: linear-gradient(45deg, transparent 50%, var(--text-2) 50%), linear-gradient(135deg, var(--text-2) 50%, transparent 50%);
  background-position: calc(100% - 17px) 52%, calc(100% - 12px) 52%; background-size: 5px 5px; }
.ui-controls :is(input, select, textarea):focus-visible, .ui-select:focus-visible, .ui-textarea:focus-visible {
  outline: 2px solid var(--accent); outline-offset: 1px; }
.ui-controls ::placeholder { color: var(--muted); }
.ui-controls :is(input[type="checkbox"], input[type="radio"]) { width: 18px; height: 18px; margin: 0; }
.ui-check { display: inline-flex; align-items: center; gap: var(--space-2); min-height: var(--touch); cursor: pointer;
  font-size: var(--fs-small); color: var(--text-2); }
.ui-check input { accent-color: var(--accent); width: 18px; height: 18px; margin: 0; }

/* progress / pace bar: style="--v:.4; --m:.1" (fill and marker as 0..1) */
.ui-bar { position: relative; height: 2px; background: var(--line); }
.ui-bar__fill { position: absolute; left: 0; top: 0; bottom: 0; width: min(100%, calc(var(--v, 0) * 100%));
  background: var(--c, var(--text)); }
.ui-bar__mark { position: absolute; top: -5px; width: 2px; height: 12px; left: calc(var(--m, 0) * 100%); background: var(--accent); }
.ui-bar--thick { height: 6px; border-radius: var(--radius-pill); }
.ui-bar--thick .ui-bar__fill { border-radius: var(--radius-pill); }
.ui-bar--over .ui-bar__fill { background: var(--bad); }
/* allocation bar: <div class="ui-stackbar"><span style="--v:3; --c:var(--cat-1)"></span>...</div> */
.ui-stackbar { display: flex; gap: 2px; height: 8px; }
.ui-stackbar > * { flex: var(--v, 1) 1 0; min-width: 2px; background: var(--c, var(--text-2)); border-radius: var(--radius-sm); }

/* sparkline: ui.spark() in ui.js returns an <svg class="ui-spark">; color via currentColor */
.ui-spark { display: block; width: 100%; height: var(--h, 40px); overflow: visible; color: var(--text); }
.ui-spark .ui-spark__ref { stroke: var(--line-2); stroke-dasharray: 3 3; }
.ui-spark .ui-spark__area { fill: currentColor; opacity: .08; }
.ui-spark .ui-spark__dot { fill: var(--accent); }

/* calendar heatmap: 7 columns, cells carry data-l="0..4" */
.ui-heat { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); gap: 3px; }
.ui-heat__h { font: var(--fs-meta)/1 var(--font-mono); color: var(--muted); text-align: center; padding-bottom: var(--space-1); }
.ui-heat__cell { aspect-ratio: 1; border-radius: var(--radius-sm); background: var(--surface); position: relative;
  font: 10px/1 var(--font-mono); color: var(--muted); padding: 3px; box-sizing: border-box; }
.ui-heat__cell[data-l="1"] { background: color-mix(in srgb, var(--text-2) 18%, var(--surface)); }
.ui-heat__cell[data-l="2"] { background: color-mix(in srgb, var(--text-2) 36%, var(--surface)); color: var(--text-2); }
.ui-heat__cell[data-l="3"] { background: color-mix(in srgb, var(--text-2) 58%, var(--surface)); color: var(--bg); }
.ui-heat__cell[data-l="4"] { background: var(--text); color: var(--bg); }
.ui-heat__cell--blank { background: none; }
.ui-heat__cell[aria-current] { outline: 1px solid var(--accent); outline-offset: 1px; }

/* two-column desktop layout (>=1024px); below that the column wrappers vanish into one stack.
   <main class="ui-cols"><div class="ui-cols__main">..</div><div class="ui-cols__side">..</div></main> */
.ui-cols__main, .ui-cols__side { display: contents; }
@media (min-width: 1024px) {
  .ui-cols { max-width: var(--cols-max, 1120px); display: grid; grid-template-columns: minmax(0, 7fr) minmax(0, 5fr);
    column-gap: var(--space-6); align-items: start; }
  .ui-cols > * { grid-column: 1 / -1; }
  .ui-cols .ui-cols__main, .ui-cols .ui-cols__side { display: flex; flex-direction: column; gap: var(--cols-gap, var(--space-5)); min-width: 0; }
  .ui-cols .ui-cols__main { grid-column: 1; }
  .ui-cols .ui-cols__side { grid-column: 2; }
}

/* horizontally scrolling box for wide tables (never the page) */
.ui-scroll { max-width: 100%; overflow-x: auto; -webkit-overflow-scrolling: touch; }

/* ---------- terminal density ---------- */
[data-density="terminal"] { --radius-sm: 0px; --radius: 0px; --radius-lg: 0px; --radius-xl: 0px;
  --row-h: 36px; --fs-display: 40px; --fs-body: 13px; --fs-small: 12px; --fs-title: 17px; }
@media (pointer: coarse) { [data-density="terminal"] { --row-h: var(--touch); } }
:is([data-density="terminal"] .ui-app, .ui-app[data-density="terminal"]) { font-family: var(--font-mono); font-size: 13px; }
[data-density="terminal"] :is(.ui-num, .ui-row__amt, .ui-row__title) { font-family: var(--font-mono); }
[data-density="terminal"] .ui-row { padding: 4px 0; }
[data-density="terminal"] .ui-note { font: var(--fs-small)/1.5 var(--font-mono); font-style: normal; }
[data-density="terminal"] .ui-display { font-family: var(--font-sans); }
.ui-ticker { display: flex; gap: var(--space-4); padding: var(--space-2) var(--space-3); border-bottom: 1px solid var(--line);
  font: var(--fs-meta)/1.5 var(--font-mono); color: var(--text-2); white-space: nowrap; overflow-x: auto; scrollbar-width: none; }
.ui-ticker::-webkit-scrollbar { display: none; }
.ui-ticker b { color: var(--text); font-weight: 500; }
.ui-panels { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); border-bottom: 1px solid var(--line); }
.ui-panels > * { padding: var(--space-3); min-width: 0; }
.ui-panels > * + * { border-left: 1px solid var(--line); }
.ui-panel__k { font: var(--fs-meta)/1.4 var(--font-mono); color: var(--muted); text-transform: uppercase; }
.ui-panel__v { font: 500 40px/1.1 var(--font-sans); font-variant-numeric: tabular-nums lining-nums; letter-spacing: -.02em; }
.ui-panel__s { font: var(--fs-meta)/1.4 var(--font-mono); color: var(--text-2); }
/* dense data table (mono); wrap in .ui-scroll on phones */
.ui-dtable { width: 100%; border-collapse: collapse; font: 12px/1.4 var(--font-mono); font-variant-numeric: tabular-nums; }
.ui-dtable th { text-align: left; font-weight: 400; font-size: 10px; text-transform: uppercase; letter-spacing: .06em;
  color: var(--muted); padding: var(--space-2); border-bottom: 1px solid var(--line); white-space: nowrap; }
.ui-dtable td { padding: var(--space-2); border-bottom: 1px solid var(--surface); white-space: nowrap; }
.ui-dtable .r, .ui-dtable th.r { text-align: right; }
.ui-dtable tbody tr:hover { background: var(--surface-2); }
.ui-dtable tr[aria-selected="true"] { background: var(--surface); box-shadow: inset 2px 0 0 var(--accent); }
.ui-dtable td.trunc { max-width: 22ch; overflow: hidden; text-overflow: ellipsis; }
@media (pointer: coarse) { .ui-dtable td { padding-top: 13px; padding-bottom: 13px; } }
/* depth bar behind a cell: <td class="ui-depth" style="--v:.4; --c:var(--cat-2)"> */
.ui-depth { position: relative; z-index: 0; }
.ui-depth::before { content: ""; position: absolute; z-index: -1; left: 0; top: 3px; bottom: 3px;
  width: min(100%, calc(var(--v, 0) * 100%)); background: color-mix(in srgb, var(--c, var(--text-2)) 22%, transparent); }
.ui-alert { display: flex; gap: var(--space-2); font: 12px/1.6 var(--font-mono); color: var(--text); }
.ui-alert__tag { flex: 0 0 4.5ch; color: var(--c, var(--accent)); }

/* ---------- simple density ---------- */
[data-density="simple"] { --radius: 14px; --radius-lg: 20px; }
.ui-hero { display: flex; flex-direction: column; gap: var(--space-2); padding: 22px; border-radius: var(--radius-xl);
  background: var(--accent); color: var(--on-accent); }
.ui-hero__v { font: 700 clamp(72px, 24vw, 96px)/.9 var(--font-sans); letter-spacing: -.04em; font-variant-numeric: tabular-nums lining-nums; }
.ui-hero__unit { font-size: .3em; letter-spacing: 0; font-weight: 500; }
.ui-hero--over { background: var(--bad); }
.ui-tile { padding: var(--space-4); border-radius: var(--radius-xl); background: var(--surface); min-width: 0; }
.ui-tile__v { font: 700 34px/1.1 var(--font-sans); font-variant-numeric: tabular-nums lining-nums; }
.ui-tile__s { font-size: var(--fs-small); color: var(--text-2); }
/* card stack: ghosts peek above the front card while more are queued (data-more="1") */
.ui-deck { position: relative; padding-top: var(--space-5); }
.ui-deck[data-more="1"]::before, .ui-deck[data-more="1"]::after { content: ""; position: absolute; left: 20px; right: 20px;
  top: 0; height: 80px; border-radius: var(--radius-xl); background: var(--surface); opacity: .5; }
.ui-deck[data-more="1"]::after { left: 10px; right: 10px; top: 10px; opacity: .8; }
.ui-deck__card { position: relative; z-index: 1; display: flex; flex-direction: column; gap: var(--space-3);
  padding: 18px; border-radius: var(--radius-xl); background: var(--surface-3); }
.ui-callout { margin: 0; padding: 14px var(--space-4); border-radius: var(--radius-xl); background: var(--surface);
  font-size: 14px; line-height: 1.45; }
.ui-callout b:first-child { color: var(--pink); }
