/* movetheneedle.studio — shared design tokens.
   One source of truth for the landing (landing.css) and the funnel (styles.css).
   Load this BEFORE either stylesheet.

   Two layers:
     1. Landing primitives. Moved verbatim out of landing.css, which owned them
        alone until the funnel was migrated onto the same system.
     2. Funnel semantics. The names styles.css already consumes, re-expressed as
        derivations of the primitives so they follow the theme with no second
        set of literals to keep in sync.

   Themes resolve in this order: an explicit data-theme attribute wins, then the
   OS preference, then light. The pre-paint script in theme.js sets the
   attribute before first paint so there is no flash. */

/* ---------- 1. landing primitives ---------- */
:root{
  color-scheme: light dark;
  --bg:#eceff3; --bg-2:#e0e5ec; --card:#f7f9fc;
  --ink:#12151b; --ink-soft:#3d4552; --muted:#69727f;
  --line:rgba(18,21,27,.12); --line-strong:rgba(18,21,27,.24);
  --accent:#2438d6; --accent-text:#2331be; --accent-deep:#1a237f;
  --grid:rgba(18,21,27,.05);
  --shadow:0 1px 0 rgba(18,21,27,.04), 0 22px 44px -34px rgba(20,30,60,.45);
  --pos:#1f7a53; --neg:#8a4b46;
  --sans:"Archivo", ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif;
  --mono:"Spline Sans Mono", ui-monospace, "SFMono-Regular", Menlo, monospace;
  --edge:clamp(20px,5vw,64px);
  /* carousel per-mode accents fall back to ultramarine until landing.js sets them */
  --intent-accent:var(--accent); --intent-deep:var(--accent-deep); --cta-accent:var(--accent);
}
@media (prefers-color-scheme: dark){
  :root{
    --bg:#0e1218; --bg-2:#141a23; --card:#161d27;
    --ink:#e9edf3; --ink-soft:#aab4c2; --muted:#6e7889;
    --line:rgba(233,237,243,.13); --line-strong:rgba(233,237,243,.24);
    --accent:#5b74ff; --accent-text:#93a8ff; --accent-deep:#b9c7ff;
    --grid:rgba(233,237,243,.05);
    --shadow:0 1px 0 rgba(0,0,0,.35), 0 26px 48px -34px rgba(0,0,0,.85);
    --pos:#4bb487; --neg:#d98d86;
  }
}
:root[data-theme="light"]{
  --bg:#eceff3;--bg-2:#e0e5ec;--card:#f7f9fc;--ink:#12151b;--ink-soft:#3d4552;--muted:#69727f;
  --line:rgba(18,21,27,.12);--line-strong:rgba(18,21,27,.24);
  --accent:#2438d6;--accent-text:#2331be;--accent-deep:#1a237f;--grid:rgba(18,21,27,.05);
  --shadow:0 1px 0 rgba(18,21,27,.04), 0 22px 44px -34px rgba(20,30,60,.45);--pos:#1f7a53;--neg:#8a4b46;
}
:root[data-theme="dark"]{
  --bg:#0e1218;--bg-2:#141a23;--card:#161d27;--ink:#e9edf3;--ink-soft:#aab4c2;--muted:#6e7889;
  --line:rgba(233,237,243,.13);--line-strong:rgba(233,237,243,.24);
  --accent:#5b74ff;--accent-text:#93a8ff;--accent-deep:#b9c7ff;--grid:rgba(233,237,243,.05);
  --shadow:0 1px 0 rgba(0,0,0,.35), 0 26px 48px -34px rgba(0,0,0,.85);--pos:#4bb487;--neg:#d98d86;
}

/* ---------- 2. funnel semantics ---------- */
/* Every one of these is derived, so a theme change moves them all and there is
   no second palette to maintain. The funnel used to define these as literals in
   a dark-only :root block at the top of styles.css. */
:root{
  /* Recessed page behind the workspace shell. */
  --bg-deep: var(--bg-2);

  /* A third text tier below --muted, for provenance and captions. */
  --faint: color-mix(in srgb, var(--muted) 76%, var(--bg));

  /* Paper is deliberately NOT theme-derived.
     The report renders as a printed document laid on the page, and that
     letterhead identity is the approved look in both themes. It is also what
     keeps every already-published report artifact rendering as it was
     reviewed: the ink literals throughout styles.css are all set against this
     exact surface, so moving it would silently restyle live report links. */
  --paper:#f1eee6;
  --paper-ink:#16171e;

  /* Fill and the text that sits on it. White on the accent in both themes is
     what the landing already does for .button-light. */
  --accent-ink:#fff;
  --accent-soft: color-mix(in srgb, var(--accent) 10%, transparent);

  /* Low-contrast wash over the page surface: checked states, hovers, inputs.
     Reads as a lift on light and as a lift on dark, from one declaration. */
  --raise: color-mix(in srgb, var(--ink) 4%, transparent);
  --raise-strong: color-mix(in srgb, var(--ink) 7%, transparent);

  /* Shadow colour channel, as bare RGB so each site keeps its own alpha:
     rgb(var(--shade) / .18). Distinct from --shadow, which is a complete
     box-shadow list for the one card style that takes it wholesale. Putting
     that list in a colour slot is invalid and computes the shadow away. */
  --shade: 40 44 65;
}
@media (prefers-color-scheme: dark){ :root{ --shade: 0 0 0; } }
:root[data-theme="light"]{ --shade: 40 44 65; }
:root[data-theme="dark"]{ --shade: 0 0 0; }

/* Caution. Not derivable: amber has to be darkened on light and lightened on
   dark to hold its contrast, so it needs a real value per theme. */
:root{ --warn:#8a6a1f; }
@media (prefers-color-scheme: dark){ :root{ --warn:#e9bd70; } }
:root[data-theme="light"]{ --warn:#8a6a1f; }
:root[data-theme="dark"]{ --warn:#e9bd70; }

/* ---------- 3. scales ---------- */
/* The type, space and radius steps the funnel actually uses, named once. The
   values are the measured inventory of styles.css, not an idealized ratio:
   consolidation means one declaration per step, not a new scale to migrate
   onto. font-size longhand consumes these; `font:` shorthands keep literals
   (a shorthand cannot take a var() for its size slot alone) and are the
   remaining migration debt, listed in docs/brand/movetheneedle.md. */
:root{
  --fs-nano: 9.5px;    /* axis ticks, the smallest chart lettering */
  --fs-micro: 10.5px;  /* uppercase micro-labels inside dense components */
  --fs-tag: 11px;      /* chips and status tags */
  --fs-caption: 11.5px;/* card captions, KPI tile labels */
  --fs-note: 12.5px;   /* annotations, provenance, kickers */
  --fs-fine: 13.5px;   /* fine print, secondary notes */
  --fs-body-2: 14.5px; /* secondary body copy */
  --fs-ui: 15px;       /* controls and dense UI copy */
  --fs-body: 16px;     /* body copy inside components */
  --fs-lead: 17px;     /* page body size, matches the landing */
  --sp-1: 4px; --sp-2: 8px; --sp-3: 12px; --sp-4: 16px; --sp-5: 24px; --sp-6: 32px;
  /* Weight ladder. Archivo is loaded as THREE static faces (400/500/700) and
     there is no variable font, so every requested weight from 550 upward
     resolves to the same rendered face. Measured in the browser rather than
     inferred: at 100px, 400 renders 780.5px wide, 500 renders 702.7px, and
     550, 600, 650, 700, 750, 760, 800 and 850 ALL render 829.5px. The CSS used
     to claim ten steps and paint three. These are the three that exist; adding
     a fourth means shipping another woff2, which is a weight-of-page decision,
     not a stylesheet one. */
  --fw-regular: 400; --fw-medium: 500; --fw-bold: 700;

  --r-1: 6px; --r-2: 8px; --r-3: 10px; --r-4: 12px; --r-5: 14px; --r-pill: 999px;
}

/* ---------- 4. chart aliases ---------- */
/* The SVG that functions/_lib/charts.mjs emits names --s1..--s4, --rule-2,
   --ghost, --ink-3, --good and --crit. Nothing declared them, so every chart in
   the private report drew as a black rectangle: an undefined custom property in
   a `fill` falls back to the initial value, which is black. They are declared
   here, derived from the tokens above rather than restated as literals, so a
   theme change moves them all — the same rule the funnel semantics follow.

   --s1..--s4 are a SEQUENTIAL ramp of the one brand accent, NOT four
   categorical hues. Series that have to be told apart are drawn as small
   multiples (one chart each) instead of overlaid, so the ramp only ever encodes
   magnitude — funnel stages, composition parts — where a single hue at
   decreasing strength is the honest encoding, and where the marks additionally
   carry direct labels. The status pair stays reserved for good/bad and is never
   reused as another series step.

   Everything here derives from --accent, --bg, --muted and --line-strong, all
   of which the report's paper scope redeclares (styles.css), so the ramp
   re-derives against paper inside a report and against the page elsewhere,
   in both themes, with no second palette to maintain. */
:root{
  --s1: var(--accent);
  --s2: color-mix(in srgb, var(--accent) 62%, var(--bg));
  --s3: color-mix(in srgb, var(--accent) 40%, var(--bg));
  --s4: color-mix(in srgb, var(--accent) 24%, var(--bg));
  --rule-2: var(--line-strong);
  --ghost: color-mix(in srgb, var(--accent) 12%, transparent);
  --ink-3: var(--muted);
  --good: var(--pos);
  --crit: var(--neg);
}
