@import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700;800&family=IBM+Plex+Mono:wght@400;500;600;700&display=swap');
:root{
  --bg:#eef1f7;--surface:#fff;--s2:#f7f8fb;--s3:#eef0f5;--border:#e5e8f0;--border-strong:#c3cadb;--grid:#c3cadb;
  --r-xs:6px;--r-sm:9px;--r-md:12px;--r-lg:16px;--r-xl:22px;--r-pill:999px;
  --sh:0 1px 2px rgba(21,29,58,.05),0 1px 1px rgba(21,29,58,.04);
  --sh-md:0 6px 20px -6px rgba(21,29,58,.14);
  --sh-lg:0 20px 48px -12px rgba(21,29,58,.22);
  --focus-ring:0 0 0 3px rgba(58,97,247,.16);
  --accent:#3a61f7;--accent-dk:#2543c9;--alt:#eef2ff;--purple:#8b5cf6;--purple-lt:#f4f1ff;
  --mgrblue:#0369a1;--mgrblue-lt:#f0f9ff;
  /* Contrast pass (Aug 2026): the six semantic hues below were darkened
     just enough to clear WCAG AA (~4.6:1) for text/badge use against
     --bg and --surface, since this is an all-day dashboard and the old
     values sat at 2.9–3.9:1 (fine for large numerals, too low for the
     small captions/labels/pills that use them). Same hue, same tint
     backgrounds (glt/alt2/tlt/rlt/pink-lt unchanged) — only the
     foreground got deeper. If a spot specifically wants the older,
     brighter shade purely as a decorative fill/icon (not text), the
     previous values were: teal #0d9488, green #0ea968, amber #d97706,
     red #e0392f, pink #db2777. */
  --teal:#0b7a70;--teal-dk:#0f766e;--tlt:#f0fdfa;
  --green:#0a7c4d;--glt:#ecfdf5;--amber:#a35a05;--alt2:#fffbeb;
  --red:#d0291f;--rlt:#fef2f2;--pink:#cc226e;--pink-lt:#fdf2f8;
  --text:#12172b;--t2:#3c4360;--muted:#646b8d;
  --mono:'IBM Plex Mono',monospace;--sans:'Inter',system-ui,sans-serif;
  /* Shared spacing scale — layout/design pass (Aug 2026): gives every
     component a common rhythm to pull from instead of one-off pixel
     values, so density can be tuned app-wide from one place. */
  --sp-1:4px;--sp-2:8px;--sp-3:12px;--sp-4:16px;--sp-5:24px;--sp-6:32px;--sp-7:44px;
  /* Shared brand header gradient - same stops as .hero/.ledger-header,
     used anywhere a dark brand-blue banner is needed (modal headers,
     dialog chrome) so those surfaces stay on-brand instead of each
     hand-rolling a slightly-different navy/blue gradient. */
  --grad-header:linear-gradient(135deg,#141b3d,var(--accent-dk) 65%,var(--accent));
}
/* ── Dark mode — Aug 2026 ────────────────────────────────────────────
   Overrides the same custom-property names on :root (root = <html>),
   so every existing rule that already reads var(--bg)/var(--surface)/
   var(--text)/etc. picks this up automatically — no component CSS
   needs to change. Toggled by setting data-theme="dark" on <html>
   (see the early inline script in index.html's <head>, and the
   Appearance card in Tools / js/ui-extras.js's setThemePref()).
   Semantic accents (accent/teal/green/amber/red/etc.) are bumped a
   shade lighter than their light-mode values so they keep enough
   contrast against the dark surfaces; -lt "tint" backgrounds go dark
   instead of pale so badges/callouts don't turn into bright squares. */
:root[data-theme="dark"]{
  --bg:#0e1320;--surface:#161c2c;--s2:#1b2233;--s3:#212940;--border:#2a3349;--border-strong:#38415c;--grid:#495781;
  --sh:0 1px 2px rgba(0,0,0,.4),0 1px 1px rgba(0,0,0,.3);
  --sh-md:0 6px 20px -6px rgba(0,0,0,.5);
  --sh-lg:0 20px 48px -12px rgba(0,0,0,.6);
  --focus-ring:0 0 0 3px rgba(91,130,255,.28);
  --accent:#5b82ff;--accent-dk:#3a61f7;--alt:#1a2144;--purple:#a78bfa;--purple-lt:#211a3a;
  --mgrblue:#38bdf8;--mgrblue-lt:#0c2230;
  --teal:#2dd4bf;--teal-dk:#5eead4;--tlt:#0e2624;
  --green:#34d399;--glt:#0f2a20;--amber:#fbbf24;--alt2:#2a2110;
  --red:#f87171;--rlt:#2a1414;--pink:#f472b6;--pink-lt:#2a1522;
  --text:#e8ebf5;--t2:#c1c7de;--muted:#8892ae;
}
*{margin:0;padding:0;box-sizing:border-box;}
html{scroll-behavior:smooth;overflow-x:hidden;overflow-y:auto;width:100%;}
body{background:var(--bg);color:var(--text);font-family:var(--sans);min-height:100vh;font-size:14px;-webkit-tap-highlight-color:transparent;-webkit-text-size-adjust:100%;overflow-x:hidden;overflow-y:auto;width:100%;max-width:100vw;position:relative;-webkit-font-smoothing:antialiased;}

/* ── Consistent form controls app-wide ──────────────────────────────
   Bare <input>/<select>/<textarea> elements (e.g. the ledger add-form
   and filter bar in js/ledger-page.js) previously fell back to raw
   browser chrome with no shared styling. Kept at low specificity so
   any existing more-specific rule (.fg input, .mgr-inp, etc.) still
   wins where a component wants its own treatment. */
.page input:not([type=checkbox]):not([type=radio]),
.page select,
.page textarea{
  font-family:var(--sans);font-size:13px;color:var(--text);
  background:var(--surface);border:1px solid var(--border);
  border-radius:var(--r-xs);padding:8px 11px;outline:none;
  transition:border-color .15s,box-shadow .15s;
}
.page input:focus,.page select:focus,.page textarea:focus{
  border-color:var(--accent);box-shadow:var(--focus-ring);
}
.page input::placeholder{color:var(--muted);opacity:.85;}
