/*
 * PaperSense — Design tokens
 * ==========================
 * Source of truth: reference/lumora_source_prompt.md (Lumora spec, verbatim) +
 * DESIGN_CONVERSION_MAP.md (changes C-01…C-13). Every value in this file is
 * either copied verbatim from the spec or is a documented PaperSense addition
 * (semantic data colors, C-03). NO raw hex/rgba may appear outside this file
 * (ARCHITECTURE.md §3 "Tokens only").
 *
 * NOTE on breakpoints: CSS custom properties cannot be used inside @media
 * conditions (`@media (max-width: var(--bp-sm))` is not valid CSS), so the
 * breakpoint tokens below are documentation / JS reference only. base.css and
 * js/core/adaptive-grid.js hardcode the literal pixel values — kept in sync
 * with --bp-* by hand.
 */

:root {
  /* ---------------------------------------------------------------------
   * 1. Fixed palette (Lumora spec, verbatim — "Fixed palette & tokens")
   * ------------------------------------------------------------------- */
  --background: #ffffff;
  --foreground: #111111;
  --ink: #0a0a0a;               /* black cards / pills / overlays */
  --on-ink: #ffffff;            /* solid text/icon color on --ink surfaces (same hex as --background, distinct role) */
  --muted: #8d8d8d;
  --subtle: #b6b6b6;
  --line: #e6e5e2;              /* hairline borders */
  --surface: #f1f0ee;
  --surface-2: #e3e2df;
  --accent: #b15f2c;
  --accent-from: #cf8047;
  --accent-to: #97501f;
  --hero-from: #ecebe9;
  --hero-to: #c9c9c9;           /* hero section background (v1 Landing) */
  --paper: #f6f1e6;             /* v2 Landing: warm near-white page field (UI design review 2026-09-27) */
  --paper-2: #efe6d3;           /* v2 Landing: a shade deeper — the 3D object's plinth, the Markets strip */

  /* ---------------------------------------------------------------------
   * 2. Opacity ramps of the above (verbatim rgba() values transcribed from
   *    the spec's component recipes — every rgba(17,17,17,X) / rgba(255,255,
   *    255,X) / rgba(230,229,226,X) / rgba(241,240,238,X) that appears in
   *    reference/lumora_source_prompt.md, named by role + alpha%).
   * ------------------------------------------------------------------- */
  /* --foreground (17,17,17) on light surfaces */
  --foreground-a70: rgba(17, 17, 17, 0.7);
  --foreground-a60: rgba(17, 17, 17, 0.6);
  --foreground-a55: rgba(17, 17, 17, 0.55);
  --foreground-a50: rgba(17, 17, 17, 0.5);
  --foreground-a45: rgba(17, 17, 17, 0.45);
  --foreground-a40: rgba(17, 17, 17, 0.4);
  --foreground-a35: rgba(17, 17, 17, 0.35);
  --foreground-a30: rgba(17, 17, 17, 0.3);
  --foreground-a20: rgba(17, 17, 17, 0.2);
  --foreground-a14: rgba(17, 17, 17, 0.14); /* the Landing hero's outline CTA border (approved concept) */
  --foreground-a10: rgba(17, 17, 17, 0.1);

  /* white (255,255,255) on dark / --ink surfaces */
  --on-ink-a90: rgba(255, 255, 255, 0.9);
  --on-ink-a80: rgba(255, 255, 255, 0.8);
  --on-ink-a70: rgba(255, 255, 255, 0.7);
  --on-ink-a60: rgba(255, 255, 255, 0.6);
  --on-ink-a55: rgba(255, 255, 255, 0.55);
  --on-ink-a45: rgba(255, 255, 255, 0.45);
  --on-ink-a40: rgba(255, 255, 255, 0.4);
  --on-ink-a35: rgba(255, 255, 255, 0.35);
  --on-ink-a30: rgba(255, 255, 255, 0.3);
  --on-ink-a25: rgba(255, 255, 255, 0.25);
  --on-ink-a15: rgba(255, 255, 255, 0.15);
  --on-ink-a10: rgba(255, 255, 255, 0.1);
  --on-ink-a05: rgba(255, 255, 255, 0.05);

  /* --line (230,229,226) */
  --line-a80: rgba(230, 229, 226, 0.8);
  --line-a70: rgba(230, 229, 226, 0.7);

  /* --surface (241,240,238) */
  --surface-a70: rgba(241, 240, 238, 0.7);
  --surface-a60: rgba(241, 240, 238, 0.6);
  --surface-a50: rgba(241, 240, 238, 0.5);

  /* ---------------------------------------------------------------------
   * 3. Semantic data colors (DESIGN_CONVERSION_MAP C-03 / ARCHITECTURE §8)
   * ------------------------------------------------------------------- */
  /*
   * VALIDATION — dataviz skill, scripts/validate_palette.js.
   * This machine has no Node.js (BUGS_FOLDER ENV-04), so the validator was
   * run in-browser as an ES module (ships a browser entry point for exactly
   * this) against a scratch harness, not the Node CLI. Method: validate()
   * ran with { mode: "light", pairs: "all" } — "all" because these tokens
   * can sit adjacent anywhere (table cells, flag chips, legends), not just
   * in a fixed stack/bar order — against both real surfaces, #ffffff and
   * #f1f0ee. contrast() ran per-color against both surfaces for the WCAG
   * checks. Scope split per color-formula.md: the five BASE tokens (marks —
   * icons, dots, arrows, chip fills) went through the full categorical
   * battery (lightness band, chroma floor, CVD separation, normal-vision
   * floor, contrast); the five -text variants are "a lone status/text
   * color" (explicitly out of the categorical validator's scope per the
   * skill's own docs) and were checked with WCAG text contrast only.
   *
   * Results, all-pairs incl. --accent #b15f2c, surfaces #ffffff & #f1f0ee:
   *   Lightness band   PASS  all 5 within OKLCH L 0.43–0.77
   *   Chroma floor     PASS  all 5 >= 0.10 (neutral excluded — see below)
   *   CVD separation   worst pair --up<->accent  ΔE 6.1 deutan  (floor
   *                     band 6–8, legal only with mandatory secondary
   *                     encoding — which ARCHITECTURE §8 already requires:
   *                     "always pair color with a sign or arrow ▲▼").
   *                     Every other pair clears the 8.0 target, incl. the
   *                     one the design brief specifically flagged:
   *                     --down<->accent ΔE 14.5 deutan (was ΔE 3.9 with an
   *                     earlier candidate — burnt-orange-reads-as-down,
   *                     fixed by moving --down to a darker, more crimson
   *                     red: L 0.432, H 17.3° vs accent's L 0.573, H 49.7°).
   *   Normal-vision floor (>=15, full-color readers) — worst pair
   *                     --warn<->accent ΔE 14.1 (0.9 short of 15; every
   *                     other pair clears it, incl. --down<->accent at
   *                     16.4). Documented shortfall, not silently dropped:
   *                     mitigated the same way the dataviz skill's own
   *                     reference palette documents its sub-15 status-vs-
   *                     series pairs (red-vs-critical, yellow-vs-warning,
   *                     both ΔE 4.8 there) — icon + label, never hue alone.
   *                     PaperSense's flag/badge chips always carry a text
   *                     label (i18n), which is exactly that mitigation.
   *   Contrast vs surface  --up/--down/--info/--neutral >= 3:1 on both
   *                     surfaces. --warn = 3.07:1 on #ffffff (pass) / 2.70:1
   *                     on #f1f0ee ("relief" band — again the same
   *                     documented pattern as the skill's reference
   *                     "warning"/"serious" statuses, mitigated by the
   *                     always-present icon + label).
   *   --neutral (#6e6d68) is intentionally achromatic (OKLCH C 0.008, under
   *                     the 0.10 chroma floor) — "no significant change" is
   *                     conveyed by the ABSENCE of hue, the same documented
   *                     exemption the method grants ordinal/sequential
   *                     ramps ("FAIL by design, not a real failure"). Its
   *                     distinctness from the four hued tokens is structural
   *                     (achromatic vs chromatic), not hue-based, so it does
   *                     not need to clear the hue-separation checks.
   *   Text variants (-text suffix): WCAG contrast only, all pass >= 4.5:1
   *                     on both surfaces (5.78:1–10.56:1 — full results
   *                     below each token).
   */
  --up: #0f8a52;              /* green  — OKLCH L .559 C .132 H 156.0° */
  --up-text: #0b6b3f;          /* 6.58:1 on #fff · 5.78:1 on #f1f0ee */
  --down: #93172f;            /* crimson-red — OKLCH L .432 C .157 H 17.3° */
  --down-text: #7d1228;        /* 10.56:1 on #fff · 9.27:1 on #f1f0ee */
  --neutral: #6e6d68;          /* warm gray, achromatic by design */
  --neutral-text: #57564f;     /* 7.37:1 on #fff · 6.47:1 on #f1f0ee */
  --warn: #a4941f;             /* gold-olive — OKLCH L .661 C .129 H 101.0° */
  --warn-text: #5c4a00;         /* 8.63:1 on #fff · 7.57:1 on #f1f0ee */
  --info: #2860ad;             /* blue — OKLCH L .494 C .136 H 257.3° */
  --info-text: #1c4d86;         /* 8.55:1 on #fff · 7.51:1 on #f1f0ee */

  /* ---------------------------------------------------------------------
   * 4. Radii, sizing, layout (verbatim)
   * ------------------------------------------------------------------- */
  --radius-pill: 9999px;
  --radius-card: 2rem;
  --radius-card-sm: 1.25rem;
  --radius-control: 0.875rem;
  --text-watermark: 13rem;
  --container-shell: 88rem;

  /* ---------------------------------------------------------------------
   * 5. Typography (verbatim)
   * ------------------------------------------------------------------- */
  --font-sans: 'Onest', sans-serif;
  --weight-regular: 400;
  --weight-medium: 500;
  --weight-semibold: 600;
  --weight-bold: 700;
  /* Small text never renders under 11px (QA-A-12, J12 "text legible"): the App's root font-size bottoms out at
     14px, where 0.75rem is 10.5px and 0.6875rem 9.6px. Use these instead of a bare 0.75rem / 0.6875rem for any
     visible text: they read exactly 12px / 11px from a 16px root up, and stop at 11px below it. */
  --text-xs: max(11px, 0.75rem);
  --text-2xs: max(11px, 0.6875rem);

  /* ---------------------------------------------------------------------
   * 6. Breakpoints (spec verbatim — reference only, see note at top of file)
   * ------------------------------------------------------------------- */
  --bp-sm: 640px;
  --bp-md: 768px;
  --bp-lg: 1024px;
  --bp-grid-1920: 1920px;
  --bp-grid-1440: 1440px;
  --bp-grid-1024: 1024px;
  --bp-grid-640: 640px;
  --adaptive-grid-base: 1920;
  --adaptive-grid-coef: 0.6666;
  --adaptive-grid-font-base: 16;

  /* ---------------------------------------------------------------------
   * 7. Reveal / hover easing curves, as custom properties (spec's react-
   *    spring → CSS approximations). The real entrance/hover motion is
   *    driven by js/core/spring.js's rAF integrator using the tension/
   *    friction pairs in §8 below; these cubic-bezier curves are the
   *    spec-given equivalents, used for plain CSS transitions (simple
   *    hover/focus states not driven by the JS spring) and as the
   *    reduced-motion-safe fallback shape.
   * ------------------------------------------------------------------- */
  --ease-out-cubic: cubic-bezier(0.215, 0.61, 0.355, 1);   /* line reveals, 900ms */
  --ease-out-quart: cubic-bezier(0.165, 0.84, 0.44, 1);    /* word reveals, 700ms */
  --curve-panel-a: cubic-bezier(0.22, 1, 0.36, 1);          /* {210,26} / {220,30} ~0.7s */
  --curve-panel-b: cubic-bezier(0.16, 1, 0.3, 1);           /* {200,24} / {180,26} ~0.8s */
  --curve-hover: cubic-bezier(0.2, 0.8, 0.2, 1);            /* {320,18} hovers ~0.35s */

  --duration-lines: 900ms;
  --duration-words: 700ms;
  --duration-panel: 700ms;
  --duration-hover: 350ms;
  --duration-nav-item: 500ms;    /* NavMenu item stagger transition */

  --stagger-line: 120ms;         /* hero H1 lineStagger */
  --stagger-line-footer: 100ms;  /* footer CTA lineStagger */
  --stagger-word: 35ms;          /* word reveal stagger */
  --stagger-nav-item: 45ms;      /* NavMenu item index*45+80ms */
  --nav-item-base-delay: 80ms;

  /* ---------------------------------------------------------------------
   * 8. Spring configs {tension, friction} — spec's exact numbers, verbatim,
   *    stored as space-separated "tension friction" pairs. spring.js's
   *    integrator takes these as numeric arguments; components.js / ui.js /
   *    header.js / nav-menu.js / search-modal.js hardcode the same numbers
   *    at each call site (kept in lockstep with this table by hand — CSS
   *    custom properties are not parsed back into JS spring() calls).
   * ------------------------------------------------------------------- */
  --spring-header: 210 26;              /* header entrance */
  --spring-hover: 320 18;               /* logo / menu / badges / pills hover */
  --spring-nav-item: 320 22;            /* nav-item & link lifts */
  --spring-social-icon: 320 16;         /* about "find us online" icons */
  --spring-partner: 320 20;             /* "Trusted by" / Markets now items */
  --spring-create-tile: 300 18;         /* CreateBand tile hover */
  --spring-service-row: 240 26;         /* service row fill-on-hover */
  --spring-service-arrow: 300 18;       /* service row trailing arrow */
  --spring-portfolio-card: 260 22;      /* portfolio card hover lift */
  --spring-portfolio-badge: 280 18;     /* portfolio card corner badge */
  --spring-portfolio-reveal: 180 26;    /* portfolio card entrance */
  --spring-reveal-standard: 200 24;     /* create/partners/heroCard/stats-item reveal */
  --spring-stats-panel: 180 26;         /* stats black panel entrance */
  --spring-hero-carousel: 300 28;       /* HeroCard carousel swap */
  --spring-nav-overlay: 280 32;         /* NavMenu overlay fade */
  --spring-modal: 260 30;               /* Search modal (RequestModal geometry) */
  --spring-loader-exit: 220 30;         /* PageLoader slide-up exit */
  --spring-loader-fade: 260 26;         /* PageLoader content fade */
  --spring-watermark: 120 30;           /* hero watermark reveal */

  /* ---------------------------------------------------------------------
   * 9. Z-index scale (verbatim)
   * ------------------------------------------------------------------- */
  --z-loader: 120;
  --z-nav-overlay: 115;
  --z-modal: 110;
  --z-skip-link: 60;
  --z-header: 50;
  --z-popover: 55;              /* info-popover / quality-slots tooltip / flag-chip tooltip — above the sticky header, below modals */

  /* ---------------------------------------------------------------------
   * 10. App shell (v3, decision #27) — the sticky App nav row, hairline
   *     included: 60px, 68px from 1024px. A view that pins something under
   *     the header uses `top: var(--app-header-h)`; the freshness line under
   *     the row is NOT part of it (it scrolls away).
   * ------------------------------------------------------------------- */
  --app-header-h: 60px;

  /* ---------------------------------------------------------------------
   * 11. Newsprint — the Landing's front page ("The Evening Close") and, from 2026-10-09, the Landing's footer.
   *     Moved here from the top of css/landing.css (the designer's spec §2.3 puts them in tokens.css; open item
   *     "move the newsprint tokens to tokens.css"). The App never uses them.
   *
   *   --newsprint #e6e0d2 is cooler and darker than --paper #f6f1e6 (1.17:1): the paper reads as an object through
   *     its edge and shadow, not its tone.
   *   --newsprint-ink #2a2823 = 11.2:1 on --newsprint (13.1:1 on --paper).
   *   --newsprint-ink-a70 (the ink at 70%, over --newsprint) = 4.84:1: the lightest secondary text that still
   *     clears AA on the sheet. Never go lighter for text; rules and decoration may.
   *   The stamp and any small accent text use --accent-to #97501f = 4.58:1 on --newsprint (NOT --accent, 3.5:1,
   *     which fails AA for small text).
   * ------------------------------------------------------------------- */
  --font-serif: 'Newsreader', ui-serif, Georgia, serif;
  --font-gothic: 'League Gothic', Impact, 'Arial Narrow', sans-serif; /* the classic US newspaper headline gothic */
  --font-fraktur: 'UnifrakturMaguntia', 'Old English Text MT', serif; /* nameplate only; subset to its glyphs (index.html) */

  --newsprint: #e6e0d2;
  --newsprint-ink: #2a2823;
  --newsprint-ink-a70: color-mix(in srgb, var(--newsprint-ink) 70%, transparent);
  --newsprint-screen: #d9d3c4; /* the halftone field */
  --newsprint-stamp: var(--accent-to);
  --newsprint-rule-soft: color-mix(in srgb, var(--newsprint-ink) 32%, transparent);
  --newsprint-vignette: rgba(80, 60, 20, 0.1);
  --newsprint-fold-shade: rgba(0, 0, 0, 0.1);
  --newsprint-fold-light: rgba(255, 255, 255, 0.38);
  --newsprint-fold-dark: rgba(60, 45, 15, 0.24);
  --shadow-paper-contact: 0 2px 3px rgba(40, 30, 10, 0.18);
  --shadow-paper-ambient: 0 40px 60px -24px rgba(40, 30, 10, 0.5);
  --shadow-paper-lift: 0 60px 80px -30px rgba(40, 30, 10, 0.55);
  --reader-backdrop: color-mix(in srgb, var(--foreground) 30%, transparent);
  /* One static turbulence tile for the newsprint grain (an image, not a live filter). */
  --np-grain: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='220' height='220'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1.9 -.75'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
}
@media (min-width: 1024px) {
  :root {
    --app-header-h: 68px;
  }
}

/* ---------------------------------------------------------------------
 * 12. Hebrew (v4 Release B, design/v4/UX_SPEC.md §8, COPY_DECK §15).
 *     Onest, Newsreader and League Gothic have no Hebrew glyphs. Under :lang(he) (js/core/i18n.js sets <html lang>) the Hebrew
 *     faces come FIRST in each stack, so one family draws both the Hebrew and the Latin of a line (tickers, figures, S&P 500):
 *       --font-sans    Heebo               UI, labels and figures
 *       --font-serif   Frank Ruhl Libre    running text and headlines
 *       --font-gothic  Frank Ruhl Libre    the newsprint headlines (League Gothic is Latin-only)
 *     The Fraktur nameplate ("The Evening Close") stays Latin and keeps --font-fraktur. English pages are untouched.
 * ------------------------------------------------------------------- */
:root:lang(he) {
  --font-sans: 'Heebo', 'Onest', sans-serif;
  --font-serif: 'Frank Ruhl Libre', 'Newsreader', ui-serif, Georgia, serif;
  --font-gothic: 'Frank Ruhl Libre', 'League Gothic', Impact, 'Arial Narrow', sans-serif;
}
