/* ============================================================================
 * theme.css - the RiseLynk shared light/dark theme token layer.
 *
 * WHAT THIS IS
 *   One canonical, dependency-free stylesheet that owns the PALETTE half of the
 *   design tokens for every single-file app (field, office, portal, dispatch,
 *   control-plane, toolbox, help). It carries the same custom-property NAMES the
 *   apps already consume (--bg, --card, --ink, --green, --rust, ...), but now
 *   defines them in TWO palettes:
 *     :root                      -> LIGHT values (the document default)
 *     :root[data-theme="dark"]   -> DARK overrides (the RiseLynk site palette)
 *   theme.js (loaded alongside) resolves the user's preference ('auto'|'light'|
 *   'dark', default 'auto' = follow the OS) and stamps data-theme onto <html>.
 *   Because every app's own rules already say var(--bg)/var(--card)/... the two
 *   palettes flow through the existing CSS with no per-rule edits.
 *
 * HOW IT LOADS (same mechanism as ui.css / format.js)
 *   In <head>, BEFORE the app's inline <style>, and AFTER a tiny synchronous
 *   anti-flash snippet that stamps data-theme before first paint:
 *     <script>(function(){try{var t=localStorage.getItem('riselynk-theme')||'auto';
 *       var d=t==='dark'||(t!=='light'&&matchMedia('(prefers-color-scheme:dark)').matches);
 *       document.documentElement.setAttribute('data-theme',d?'dark':'light');
 *       document.documentElement.setAttribute('data-theme-pref',t);}catch(e){
 *       document.documentElement.setAttribute('data-theme','dark');}})();</script>
 *     <link rel="stylesheet" href="/apps/shared/theme.css">
 *     <script src="/apps/shared/theme.js"></script>
 *   No build step. Served as a file and precached by the field/toolbox service
 *   workers, exactly like ui.css / format.js.
 *
 * WHERE THE VALUES COME FROM (provenance)
 *   DARK = the live RiseLynk site palette (originally apps/landing/index.html :root,
 *   now website/site + engine; the "new site" the founder asked the apps to match). The apps' own dark values
 *   were byte-near the site's already; a few (--ink e8efe9->e7efea, --dim
 *   93a89d->a9b8b1, --green-deep 085041->0c4f41, --faint 8a9d91->869a90) are
 *   snapped to the site value so the apps and the marketing site read identical.
 *   (--faint 869a90 is exactly what the apps' runtime a11y shim already injected,
 *   so dark rendering is unchanged.) The state accents (rust/indigo/carry/danger/
 *   safe and their -deep/-bg pair backgrounds) are NOT on the site, so their dark
 *   values are carried from the apps unchanged.
 *
 *   LIGHT = derived here from the same brand hues (the site ships no light mode).
 *   Derivation rules, stated so they can be audited:
 *     - Surfaces invert but stay green-tinted, never flat gray: bg is a soft
 *       green-white, card is pure white so it lifts, card2 a faint green hover.
 *     - Text darkens to a near-black green-black (--ink) with --dim/--faint
 *       tuned to clear WCAG AA (>=4.5:1) on --card (see theme_static.test.mjs).
 *     - --line-strong darkens enough to hold >=3:1 (WCAG 1.4.11) on the light bg.
 *     - --green is the DEEPEST brand green that still keeps dark button text
 *       (#062018, the site's on-green text) at AA on a green fill, because
 *       .btn.primary across the apps is `background:var(--green);color:#062018`.
 *       That one constraint fixes it; a darker green would fail those buttons.
 *     - The "-deep"/"-bg" accent tokens are FILL backgrounds carrying light text
 *       (badges/pills: bg=*-deep/-bg, text=base). In dark that is dark-fill +
 *       light-text; in light it inverts to light-tint fill + dark text, so each
 *       pair flips together and both modes stay legible.
 *     - --page (help pages' deep body bg, darker than --bg) inverts to a light
 *       page slightly darker than --bg so cards still lift.
 *
 * WHAT STAYS LOCAL (deliberately NOT themed this pass)
 *   Per-app motion tokens (--ring, --glass, --card-grad, --ease-*) and hard-coded
 *   decorative gradients/glows keep their local (dark-tuned) values - flipping
 *   translucent gradients mechanically is unsafe and these are non-load-bearing
 *   over the themed surfaces. Fonts/radii below are theme-invariant and defined once.
 *
 *   UPDATE 2026-08-26 (MOBILE-PLAN Part 2 §2.4 Decision 2): elevation is no longer
 *   in that list. "Depth keeps its local dark-tuned values" was safe for gradients
 *   and wrong for shadows - light mode shipped with a dark-mode shadow ramp, which
 *   is the one genuine authoring hole the plan identified. --shadow-sm/md/lg now
 *   live here with a real per-mode ramp. See ELEVATION below.
 *
 * SELF-HOSTED TYPE (2026-08-26, plan §2.3)
 *   --font-display named 'Barlow' since this file was written and NOTHING resolved
 *   it: the woff2 files sat only in the retired landing archive, and the token had
 *   zero consumers, so every app rendered the OS system font. The three faces now
 *   live beside this file in apps/shared/fonts/ and are declared below. URLs are
 *   RELATIVE to this stylesheet, so they resolve identically on the web
 *   (/apps/shared/fonts/...) and inside the packaged Capacitor bundle, and the
 *   field service worker precaches all three - an offline-first app that fetches
 *   its typeface from the network has no typography in a basement.
 * ========================================================================== */

/* Two weights and one mono, deliberately: a system, not a swatch page (plan §2.3).
   font-display:swap so a cold cache paints text immediately in the fallback. */
@font-face { font-family: 'Barlow'; font-weight: 600; font-style: normal;
             font-display: swap; src: url('fonts/barlow-600.woff2') format('woff2'); }
@font-face { font-family: 'Barlow'; font-weight: 800; font-style: normal;
             font-display: swap; src: url('fonts/barlow-800.woff2') format('woff2'); }
@font-face { font-family: 'IBM Plex Mono'; font-weight: 500; font-style: normal;
             font-display: swap; src: url('fonts/plex-mono-500.woff2') format('woff2'); }

:root {
  /* -- typography + radii (theme-invariant; mirror the site's names/values) -- */
  --font-display: 'Barlow', -apple-system, 'Segoe UI', sans-serif;
  --font-mono: 'IBM Plex Mono', ui-monospace, 'Cascadia Mono', monospace;
  --r-sm: 10px; --r-md: 14px; --r-lg: 18px;

  /* ---- canonical scale tokens (plan §2.4 Decision 1) --------------------
     theme.css is the single token home. ui.css keeps its --rl-* names as
     one-line aliases onto these, so its 60 internal component references keep
     working and no token has two values. Radius: --r-sm/md/lg were already
     live (16 uses across apps/ + website/) so they keep their names and values;
     xs/xl/pill are ported from ui.css's richer scale.
     --r-xl is NOT a literal port: ui.css's --rl-radius-xl is 14px, which is
     already --r-md here, so copying it across would put xl BELOW lg and invert
     the ramp. It extends this scale's own progression (10/14/18) instead. */
  --r-xs: 6px; --r-xl: 24px; --r-pill: 999px;

  /* spacing - ported from --rl-space-* */
  --space-0: 0;    --space-1: 2px;  --space-2: 4px;  --space-3: 6px;
  --space-4: 8px;  --space-5: 10px; --space-6: 12px; --space-7: 14px;
  --space-8: 16px; --space-9: 18px; --space-10: 20px; --space-12: 26px;

  /* type scale - ported from --rl-text-* */
  --text-2xs: 10px; --text-xs: 11px; --text-sm: 12px; --text-md: 13px;
  --text-base: 14px; --text-lg: 16px; --text-xl: 17px;

  /* Touch targets. AUTHORED here, not moved: the plan's §2.4/§2.5 say ui.css
     already defines --tap and it does not - the apps carry bare `min-height:44px`
     literals instead. --tap is the WCAG 2.5.5 floor the office and portal use;
     --tap-glove is the field floor, because a gloved fingertip is a much larger
     and much less precise contact patch than a bare one (plan §2.5 FIELD). */
  --tap: 44px;
  --tap-glove: 56px;

  /* ---- ELEVATION, light ramp (plan §2.4 Decision 2) ---------------------
     Shadow is tinted with the --ink hue (22,34,27) rather than pure black, for
     the same reason the light surfaces are green-tinted and never flat gray.
     Light needs LOWER alpha and a tighter spread than dark: on a white card a
     dark-mode shadow reads as dirt, not as lift. */
  --shadow-sm: 0 1px 2px rgba(22, 34, 27, .06), 0 1px 1px rgba(22, 34, 27, .04);
  --shadow-md: 0 4px 14px rgba(22, 34, 27, .10), 0 2px 4px rgba(22, 34, 27, .06);
  --shadow-lg: 0 16px 48px rgba(22, 34, 27, .16), 0 4px 12px rgba(22, 34, 27, .08);

  /* ================= LIGHT palette (document default) ================= */
  /* surfaces */
  --bg: #eef2ef;
  --bg2: #e3eae5;
  --card: #ffffff;
  --card2: #eaf1ed;
  --surface-modal: #ffffff;
  /* lines / borders */
  --line: #d5ded9;
  --line-strong: #6f8177;
  /* text */
  --ink: #16221b;
  --dim: #45564d;
  --faint: #57685f;
  /* brand green (--green is the deepest that keeps #062018 button text at AA) */
  --green: #13976e;
  --green-deep: #0a5f4a;
  --green-soft: #d6f0e6;
  /* state accents (base = text/icon, -deep/-bg = fill background) */
  --rust: #9d4718;
  --rust-deep: #f8e3d6;
  --indigo: #4a44a6;
  --indigo-deep: #e2e0f8;
  --carry: #7a5f00;
  --carry-bg: #f8f0cc;
  --danger: #a82c24;
  --danger-deep: #fbe2de;
  --safe: #177a3d;
  /* Console/log foreground on --page. These are NOT --danger / --green: a log line
     sits on --page, not on a card, and both accents fall under 4.5:1 there in light
     mode. Measured against light --page #e6ece8: --log-err 5.75:1, --log-ok 6.38:1. */
  --log-err: #a82c24;
  --log-ok: #0a5f4a;
  /* help pages' deep page bg (behind cards) */
  --page: #e6ece8;
}

/* ================= DARK palette (the RiseLynk site) ================= */
:root[data-theme="dark"] {
  /* surfaces */
  --bg: #0f1412;
  --bg2: #131b18;
  --card: #1a2420;
  --card2: #21302a;
  --surface-modal: #141d19;
  /* lines / borders */
  --line: #2c3d35;
  --line-strong: #7a8d82;
  /* text */
  --ink: #e7efea;
  --dim: #a9b8b1;
  --faint: #869a90;
  /* brand green */
  --green: #5dcaa5;
  --green-deep: #0c4f41;
  --green-soft: #9fe1cb;
  /* state accents */
  --rust: #f0997b;
  --rust-deep: #712b13;
  --indigo: #afa9ec;
  --indigo-deep: #3c3489;
  --carry: #eab308;
  --carry-bg: #3a2f08;
  --danger: #f87171;
  --danger-deep: #4a1613;
  --safe: #4ade80;
  /* Console/log foreground on --page. Dark keeps the values the ops log always had,
     which were only ever wrong once the surface under them turned light. Measured
     against the old hardcoded #0b100e they shipped on: --log-err 9.36:1, --log-ok
     11.38:1; dark --page #0a0d0c is marginally darker, so both go up slightly. */
  --log-err: #f0a0a0;
  --log-ok: #8fd6b5;
  /* help pages' deep page bg */
  --page: #0a0d0c;

  /* ELEVATION, dark ramp - the values ui.css has always shipped, unchanged, so
     dark rendering is byte-identical to before this token moved home. */
  --shadow-sm: 0 1px 2px rgba(0, 0, 0, .25);
  --shadow-md: 0 4px 14px rgba(0, 0, 0, .35);
  --shadow-lg: 0 16px 48px rgba(0, 0, 0, .5);
}

/* ----------------------------------------------------------------------------
 * Theme toggle - the shared tri-state control (Auto / Light / Dark).
 * Every app drops the same markup:
 *   <div class="rl-theme-toggle" role="group" aria-label="Theme" data-theme-toggle>
 *     <button type="button" data-theme-set="auto"  onclick="Theme.setTheme('auto')">Auto</button>
 *     <button type="button" data-theme-set="light" onclick="Theme.setTheme('light')">Light</button>
 *     <button type="button" data-theme-set="dark"  onclick="Theme.setTheme('dark')">Dark</button>
 *   </div>
 * theme.js keeps the active button flagged (.rl-theme-on + aria-pressed) as the
 * theme changes, so the styling here is app-agnostic and token-driven.
 * -------------------------------------------------------------------------- */
.rl-theme-toggle {
  display: inline-flex; gap: 6px; flex-wrap: wrap;
}
.rl-theme-toggle [data-theme-set] {
  flex: 1; min-width: 62px;
  border: 1px solid var(--line-strong); background: var(--card2); color: var(--ink);
  border-radius: 10px; padding: 8px 12px;
  font: 600 13px inherit; cursor: pointer; text-align: center;
}
.rl-theme-toggle [data-theme-set]:hover { border-color: var(--green); }
.rl-theme-toggle [data-theme-set]:focus-visible { outline: 2px solid var(--green); outline-offset: 2px; }
.rl-theme-toggle [data-theme-set].rl-theme-on {
  background: var(--green-deep); border-color: var(--green-deep); color: var(--green-soft);
}
