/* Quantum shared theme — single source of truth for design tokens.
   These were copy-pasted into a :root{} block on every page; now they live here.
   Link this BEFORE each page's own <style> so page rules can still override.
   ponytail: P1 only centralizes tokens. Pages still carry their own body/button/table
   rules and legacy radius values until P2 normalizes them onto --r-* / --t-*. */

/* P4: one display face (Fraunces) for headings + hero numbers only. @import lives
   here so all 17 pages get it via the single theme.css link. display=swap → text
   shows in the Georgia fallback until the font loads (no invisible text).
   ponytail: CDN load, self-host the woff2 if offline/privacy ever matters. */
@import url('https://fonts.googleapis.com/css2?family=Fraunces:opsz,wght@9..144,600..700&display=swap');

:root{
  /* palette */
  --ink:#1c1a17;
  --paper:#f4efe6;
  --line:#d8cfbe;
  --accent:#2f6f4f;
  --muted:#7a7264;

  /* accent scale + tints (P5 elevate — richer greens for depth, hovers, soft fills) */
  --accent-700:#255a40;
  --accent-600:#2f6f4f;
  --accent-400:#57906f;
  --accent-soft:#e7f0ea;      /* pale green fill for active/selected states */
  --gold:#b98a3c;             /* warm secondary accent — matches the parchment */

  /* elevation — soft, warm-tinted shadows (not flat black) for real depth (P5) */
  --shadow-1:0 1px 2px rgba(40,32,20,.05), 0 1px 1px rgba(40,32,20,.04);
  --shadow-2:0 2px 6px rgba(40,32,20,.06), 0 4px 14px rgba(40,32,20,.05);
  --shadow-3:0 6px 18px rgba(40,32,20,.10), 0 14px 34px rgba(40,32,20,.08);
  --ring:0 0 0 3px color-mix(in srgb, var(--accent) 22%, transparent);

  /* display face — headings + hero numbers (P4). Georgia is the instant fallback. */
  --font-display:'Fraunces',Georgia,'Times New Roman',serif;

  /* radius scale — tokens for every value in use, so tokenizing pages is lossless.
     (buttons use --r-sm). Snap the whole app rounder/squarer by editing here.) */
  --r-sm:6px;    /* small controls, chips        (absorbs stray 4/5px) */
  --r-md:8px;    /* buttons-ish, small boxes     (absorbs stray 7px) */
  --r-lg:10px;   /* cards, panels, toolbars      (absorbs stray 9px) */
  --r-xl:12px;   /* larger cards */
  --r-2xl:14px;  /* hero cards, login card */
  --r-pill:20px; /* badges, status pills */

  /* type scale */
  --t-label:12px;
  --t-body:15px;
  --t-h2:20px;

  /* motion — promoted from the login page so the whole app can use one vocabulary */
  --modal-open-dur:250ms;
  --modal-scale:0.96;
  --modal-ease:cubic-bezier(0.22,1,0.36,1);
  --shake-distance:6px;
  --shake-overshoot:4px;
  --shake-dur-a:80ms;
  --shake-dur-b:60ms;
  --shake-ease:cubic-bezier(0.22,1,0.36,1);
  --revert-hold:3000ms;
  --revert-dur:280ms;
}

/* ── Buttons — one canonical set (P2). Was redefined on every page with small
   drift (padding 6-8px, radius 6/7/8, one raw #2f6f4f, some missing font-weight).
   Works for both <button> and <a class="btn">. Variants: sec/ghost (outline),
   danger (red), warn (red outline), sm (compact). ──────────────────────────── */
.btn{display:inline-block;padding:7px 14px;border:0;border-radius:var(--r-sm);
  background:linear-gradient(180deg,var(--accent-400),var(--accent-600));color:#fff;font:inherit;font-size:13px;font-weight:600;
  line-height:1.4;text-align:center;text-decoration:none;cursor:pointer;
  box-shadow:var(--shadow-1), inset 0 1px 0 rgba(255,255,255,.15);
  transition:transform .12s var(--modal-ease), box-shadow .12s ease, background .15s ease}
.btn:not(.sec):not(.ghost):not(.warn):not(:disabled):hover{background:linear-gradient(180deg,var(--accent-600),var(--accent-700));box-shadow:var(--shadow-2), inset 0 1px 0 rgba(255,255,255,.15);transform:translateY(-1px)}
.btn:not(:disabled):active{transform:translateY(0);box-shadow:var(--shadow-1)}
.btn:disabled{opacity:.5;cursor:not-allowed}
.btn.sec,.btn.ghost{background:#fff;color:var(--accent);border:1px solid var(--line);box-shadow:var(--shadow-1)}
.btn.sec:not(:disabled):hover,.btn.ghost:not(:disabled):hover{border-color:var(--accent);background:var(--accent-soft)}
.btn.danger{background:linear-gradient(180deg,#c33a32,#b3261e);color:#fff;border:0}
.btn.warn{background:#fff;color:#b3261e;border:1px solid #e3b7b3}
.btn.warn:not(:disabled):hover{background:#fbeeed}
.btn.sm{padding:4px 9px;font-size:12px}

/* ── Shared polish (P5 elevate) — applies app-wide, doesn't collide with per-page rules ── */
/* keyboard focus ring — accessible + consistent across every control */
a:focus-visible,button:focus-visible,input:focus-visible,select:focus-visible,textarea:focus-visible,[tabindex]:focus-visible{
  outline:none;box-shadow:var(--ring);border-radius:var(--r-sm)}
/* text selection + caret in the brand green */
::selection{background:color-mix(in srgb,var(--accent) 24%,transparent);color:var(--ink)}
:root{caret-color:var(--accent)}
/* parchment-tinted scrollbars */
*{scrollbar-width:thin;scrollbar-color:#c9bfad transparent}
*::-webkit-scrollbar{width:11px;height:11px}
*::-webkit-scrollbar-thumb{background:#cebfa6;border:3px solid transparent;border-radius:20px;background-clip:content-box}
*::-webkit-scrollbar-thumb:hover{background:#b9a889;background-clip:content-box}
*::-webkit-scrollbar-track{background:transparent}
/* smoother interactions on the common interactive bits (no layout change) */
.btn,.tab,.chip,.pill,.qgbtn,.tk-th{transition:background .15s ease,color .15s ease,border-color .15s ease,box-shadow .15s ease,transform .12s ease}

/* ── Tables — tabular figures so number columns stop wobbling as digits change
   (P3). Only affects digits; letters render unchanged, so app-wide is safe. ── */
th,td{font-variant-numeric:tabular-nums}

/* ── Display face (P4) — headings + dashboard hero numbers. Pages set their own
   font-size/letter-spacing on h1/h2; only the family comes from here, so it wins
   over body's system sans without disturbing per-page sizing. Table figures stay
   sans (tabular alignment above). ─────────────────────────────────────────── */
h1,h2,.tile .v{font-family:var(--font-display)}
/* refined heading optics — Fraunces looks best a touch tighter with a hair of ink contrast */
h1,h2{letter-spacing:-.012em}
h2{color:var(--ink)}
/* baseline card elevation — pages that set their own box-shadow still win; flat cards gain depth */
.card{box-shadow:var(--shadow-1)}

/* Shared page entrance gate — pages that load /assets/reveal.js add .js-reveal (sync, in <head>)
   so their <main> children are hidden pre-paint, then staggered in. Dormant unless that class
   is set, so pages without reveal.js are unaffected. */
.js-reveal main>*{opacity:0}

/* Hide number-input spinner arrows app-wide (loaded on every page) */
input[type=number]::-webkit-inner-spin-button,
input[type=number]::-webkit-outer-spin-button{-webkit-appearance:none;margin:0}
input[type=number]{-moz-appearance:textfield;appearance:textfield}
