/* ─────────────────────────────────────────────────────────────────────────────
   TYPEFACES — self-hosted, latin subset, variable weight.

   Before this, seven of the nine signed-in pages loaded no webfont at all and
   rendered in the visitor's OS default, so the product looked like a different
   thing on every machine and had no typographic identity. The two faces that
   WERE nominally the brand -- Clash Display and Satoshi, imported at the top of
   css/shared.css from api.fontshare.com -- had never loaded even once: that host
   is in neither the style-src nor the font-src directive of _headers, so the CSP
   dropped them silently with nothing in the console to notice.

   Self-hosted rather than linked from Google because about.html promises
   "No ads, no analytics, no tracking" and a Google Fonts link hands every
   visitor's IP to Google on every page view. 'self' is already allowed by the
   CSP, so these can never be blocked the way Fontshare was.
   ───────────────────────────────────────────────────────────────────────────── */
@font-face {
  font-family: 'Plus Jakarta Sans';
  src: url('../assets/fonts/plus-jakarta-sans-latin-var.woff2') format('woff2-variations'),
       url('../assets/fonts/plus-jakarta-sans-latin-var.woff2') format('woff2');
  font-weight: 200 800;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'JetBrains Mono';
  src: url('../assets/fonts/jetbrains-mono-latin-var.woff2') format('woff2-variations'),
       url('../assets/fonts/jetbrains-mono-latin-var.woff2') format('woff2');
  font-weight: 400 700;
  font-style: normal;
  font-display: swap;
}

:root {
  --font-sans: 'Plus Jakarta Sans', ui-sans-serif, system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;
  --font-mono: 'JetBrains Mono', ui-monospace, SFMono-Regular, Menlo, monospace;
}

/* Set once here so every page inherits instead of each declaring its own stack.
   learn / play / module / quiz / profile each used to declare a different one. */
html { font-family: var(--font-sans); }

/* Money products are read as numbers first. Line up every digit. */
.tabular, [data-tabular], .mono { font-variant-numeric: tabular-nums; }
.mono { font-family: var(--font-mono); }

/* ============================================================
   JagInsights — semantic design tokens (single source of truth)
   Loaded from every authenticated page BEFORE app-shell-header.css
   so theme-aware components (adaptive navbar, buttons, etc.) can
   reference these without each page needing its own copy.
   ============================================================ */
/* ─────────────────────────────────────────────────────────────────────────────
   SCALES

   Counted across the CSS actually loaded by the signed-in pages before this
   existed: 72 distinct font-size values, 34 distinct spacing values, 33 distinct
   border-radius values. That is not a system, it is accumulation -- and the
   symptom was that h2 rendered only 1.23x the size of body text, so headings
   read as bold paragraphs and nothing on a page was scannable.

   Type is a 1.25 ratio on a 17px base. Spacing is 8 steps. Radius is 4 -- the
   old spread was dominated by 18-22px on literally every surface, which is a
   large part of why the product read as generic.
   ───────────────────────────────────────────────────────────────────────────── */
:root {
  --fs-xs:   13px;
  --fs-sm:   15px;
  --fs-base: 17px;
  --fs-lg:   21px;
  --fs-xl:   26px;
  --fs-2xl:  clamp(28px, 2.6vw, 33px);
  --fs-3xl:  clamp(33px, 3.4vw, 41px);
  --fs-4xl:  clamp(40px, 4.6vw, 51px);

  /* Layout frame. Before these existed the header was full-bleed
     (padding from the viewport edge) while every page body was a centred column
     of some unrelated width -- 1080 on dashboard, 1180 on budget-tools, 780 on
     settings, 748 on the module reader. At 1512px that put the logo 212px to the
     left of everything beneath it, which is why the chrome and the content read
     as two products bolted together. Both reference these now.

     --shell-h was 68px hardcoded in fourteen places across seven files, including
     four calc(100vh - 68px) page heights, a dropdown pinned at top:112px and a
     sticky panel at top:148px. Changing the header height meant finding all of
     them; now it means changing one line. */
  --shell-h:    68px;
  --page-max:   1440px;
  --page-inset: clamp(20px, 4vw, 56px);

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

  --r-sm: 6px; --r-md: 10px; --r-lg: 16px; --r-pill: 999px;
}

/* Body default. Components still set their own size; this governs only text
   nothing else has claimed. */
body { font-size: var(--fs-base); }

/* Heading baseline.

   css/tailwind.css ships a preflight rule -- h1,h2,h3,h4,h5,h6{font-size:inherit;
   font-weight:inherit} -- so any heading not explicitly styled rendered at body
   size with no margin, on all six Tailwind pages. tokens.css loads AFTER
   tailwind.css on every page, so this restores a sane default; anything with its
   own class rule still wins on specificity and is unaffected. */
h1, h2, h3, h4, h5, h6 {
  font-family: var(--font-sans);
  line-height: 1.18;
  text-wrap: balance;
}
h1 { font-size: var(--fs-3xl); font-weight: 800; letter-spacing: -0.022em; }
h2 { font-size: var(--fs-xl);  font-weight: 780; letter-spacing: -0.016em; }
h3 { font-size: var(--fs-lg);  font-weight: 750; letter-spacing: -0.01em; }
h4 { font-size: var(--fs-base); font-weight: 700; }
h5, h6 { font-size: var(--fs-sm); font-weight: 700; }

:root {
  /* Dark-theme defaults — apply when data-theme="dark" or absent. */
  --bg-page:        #070d1c;
  --bg-surface:     #0e1730;
  --bg-elevated:    #16213f;
  --border-line:    #1f2c4d;
  --text-primary:   #e8eefc;
  --text-secondary: #8b95b3;
  --text-muted:     #5b6585;
  --accent-cyan:    #22d3ee;
  --accent-gold:    #fbbf24;
  --status-success: #34d399;
  --status-danger:  #f87171;
  --shadow-card:    0 10px 30px rgba(0, 0, 0, 0.45);
}

html[data-theme="light"] {
  --bg-page:        #f1f6fc;
  --bg-surface:     #ffffff;
  --bg-elevated:    #e9eff7;
  --border-line:    #dfe6f0;
  --text-primary:   #0f172a;
  --text-secondary: #475569;
  --text-muted:     #94a3b8;
  /* Darker accents than dark-mode so they hit AA contrast on white. */
  --accent-cyan:    #0891b2;
  --accent-gold:    #d97706;
  --status-success: #059669;
  --status-danger:  #dc2626;
  --shadow-card:    0 1px 3px rgba(15, 23, 42, 0.06);
}

/* ============================================================
   iOS Safari zoom-on-focus fix (site-wide floor).
   Mobile Safari force-zooms the page whenever a focused
   input/select/textarea computes to less than 16px. Every text
   control on this site is styled 13-15px, so raise them to the
   16px floor on touch/mobile only -- desktop is untouched.
   Buttons, checkboxes, radios and range sliders never trigger
   the zoom, so they are excluded and keep their exact layout.
   ============================================================ */
@media (max-width: 767px), (hover: none) and (pointer: coarse) {
  input:not([type="button"]):not([type="submit"]):not([type="reset"]):not([type="checkbox"]):not([type="radio"]):not([type="range"]):not([type="color"]):not([type="image"]),
  select,
  textarea {
    font-size: 16px !important;
  }
}
