/*
 * money map — design tokens (matador foundation)
 * ------------------------------------------------
 * The single source of truth for the visual system. Semantic CSS custom
 * properties ONLY — components reference these, never raw hex/hsl. Per the
 * matador dual-mode rule every token is defined for BOTH light (:root) and
 * premium-dark (.dark); neither is an afterthought.
 *
 * Identity (locked): Space Grotesk display · Instrument Serif marketing ·
 * matador red accent · tinted neutrals (never pure black/white). Neither face
 * is shipped — see the Typography block below for what actually renders and
 * why.
 *
 * Colours are authored as space-separated HSL channels so they compose with
 * hsl(var(--token) / <alpha>) for tints and translucency.
 */

:root {
  /* ---- Brand accent (matador red) ---------------------------------- */
  --mm-accent: 357 78% 52%;
  --mm-accent-hover: 357 74% 46%;
  --mm-accent-active: 357 72% 41%;
  --mm-accent-foreground: 0 0% 100%;

  /* ---- Neutrals — warm, tinted off-whites (never #fff) -------------- */
  --mm-bg: 40 33% 98%;
  --mm-surface: 40 24% 96%;
  --mm-surface-raised: 0 0% 100%;
  --mm-border: 40 12% 88%;
  --mm-border-strong: 40 10% 80%;

  /* ---- Ink — tinted near-black (never #000) ------------------------- */
  --mm-text: 240 10% 12%;
  --mm-text-muted: 240 6% 38%;
  --mm-text-subtle: 240 5% 44%; /* AA-safe (>=4.5:1) on --mm-bg at 14px */

  /* ---- Feedback ---------------------------------------------------- */
  --mm-success: 152 42% 38%;
  --mm-warning: 34 88% 34%;   /* L=34% → 4.7:1 on --mm-bg (AA ✓); was 44% @ 3.0:1 */
  --mm-danger: 357 68% 48%;

  /* ---- AA-safe text variants — dedicated foreground tokens for text/labels.
     The shared fill tokens above are calibrated for backgrounds (fills, borders,
     dots). Using them as text on light surfaces: green 3.87:1, amber 4.7:1, red
     4.24:1 vs near-white (amber now meets AA; green + red still do not). These
     darker variants exceed AA more comfortably for small labels. ----------- */
  --mm-success-text: 152 55% 26%;   /* 6.1:1 on near-white */
  --mm-warning-text: 34 75% 28%;    /* 6.7:1 on near-white; badge label on tint: 5.9:1 */
  --mm-accent-text: 357 78% 38%;    /* 6.9:1 on near-white */

  /* --- Data-series ramp -----------------------------------------------------
     Separate from the status ramp on purpose. Charts previously drew with
     --mm-success / --mm-warning / --mm-danger, which is wrong twice over: it
     paints a neutral fact (a variance is under plan) in the colour reserved for
     "something is wrong", and on a page that also carries a real warning the two
     meanings collide.

     It was also unreadable. Run against the dataviz validator, the colours the
     charts were using scored deuteranopia dE 1.5 between "over plan" and "under
     plan" -- indistinguishable -- and 13.2 with full colour vision, below the
     hard floor of 15. In a financial app the sign is the entire point.

     These steps are computed, not chosen: every one passes the lightness band,
     chroma floor, CVD separation, normal-vision floor, and contrast checks in
     BOTH modes. Re-run before changing any of them:
       node <dataviz>/scripts/validate_palette.js "<hexes>" --mode light
     and see docs/data-series-palette.md for the recorded report.

     Assign slots in fixed order, never cycled, and never reuse a status colour
     as a series colour. */

  --mm-series-1: 357 62% 53%;
  --mm-series-2: 198 100% 33%;
  --mm-series-3: 43 89% 38%;
  --mm-series-4: 175 100% 30%;
  --mm-series-5: 270 39% 55%;
  --mm-series-6: 81 100% 27%;

  /* Diverging poles: slots 1 and 2, scored at dE 29.2 normal / 15.5 protan. */
  --mm-diverge-pos: var(--mm-series-1);
  --mm-diverge-neg: var(--mm-series-2);

  /* ---- Focus ring -------------------------------------------------- */
  --mm-ring: 357 78% 52%;

  /* ---- Elevation — shadows as tints, not flat black ---------------- */
  --mm-shadow-sm: 0 1px 2px hsl(240 12% 20% / 0.06);
  --mm-shadow-md: 0 4px 16px -4px hsl(240 12% 20% / 0.10);
  --mm-shadow-lg: 0 12px 40px -8px hsl(240 14% 18% / 0.16);

  color-scheme: light;
}

.dark {
  /* ---- Brand accent — lifted for contrast on dark ------------------ */
  --mm-accent: 357 82% 62%;
  --mm-accent-hover: 357 84% 68%;
  --mm-accent-active: 357 80% 58%;
  --mm-accent-foreground: 357 40% 8%;

  /* ---- Neutrals — tinted near-black surfaces (never #000) ---------- */
  --mm-bg: 240 8% 6%;
  --mm-surface: 240 7% 9%;
  --mm-surface-raised: 240 7% 12%;
  --mm-border: 240 6% 18%;
  --mm-border-strong: 240 6% 26%;

  /* ---- Ink --------------------------------------------------------- */
  --mm-text: 0 0% 98%;
  --mm-text-muted: 240 5% 78%;    /* bumped from 68% — must sit above subtle; 78% vs 70% = distinct tier */
  --mm-text-subtle: 240 5% 70%;   /* tertiary tier; 70% < 78% so darker/less contrast on dark bg */

  /* ---- Feedback ---------------------------------------------------- */
  --mm-success: 152 46% 54%;
  --mm-warning: 34 90% 60%;

  /* Data-series ramp, dark steps -- validated against the dark surface,
     not derived by flipping the light ones. */
  --mm-series-1: 356 68% 58%;
  --mm-series-2: 201 70% 44%;
  --mm-series-3: 43 82% 40%;
  --mm-series-4: 174 84% 33%;
  --mm-series-5: 268 40% 57%;
  --mm-series-6: 80 64% 37%;
  --mm-danger: 357 78% 64%;

  /* ---- AA-safe text variants for dark surfaces --------------------- */
  --mm-success-text: 152 46% 54%;   /* same as fill — already 7.4:1 on dark */
  --mm-warning-text: 34 90% 68%;    /* 5.9:1 on dark card surface */
  --mm-accent-text: 357 82% 76%;    /* 7.3:1 on dark card surface (was 4.24:1) */

  --mm-ring: 357 82% 62%;

  --mm-shadow-sm: 0 1px 2px hsl(0 0% 0% / 0.40);
  --mm-shadow-md: 0 4px 16px -4px hsl(0 0% 0% / 0.50);
  --mm-shadow-lg: 0 12px 40px -8px hsl(0 0% 0% / 0.60);

  color-scheme: dark;
}

:root {
  /* ---- Typography --------------------------------------------------
   * No @font-face here and no webfont link in base.html, so on most machines
   * the second name in each stack is what renders. base.html used to link
   * fonts.googleapis.com; style-src is 'self' 'nonce-…' and font-src is 'self',
   * so the browser refused the stylesheet and the faces never loaded — three
   * review rounds saw the fallback and read it as the design, which is a fair
   * verdict on how deliberate the fallbacks are.
   *
   * The named faces still lead each stack: a reader who has them installed gets
   * them, and shipping the files from static/ and declaring @font-face below is
   * all it would take to give everyone else the same, within the policy as it
   * stands.
   */
  --mm-font-display: "Space Grotesk", ui-sans-serif, system-ui, "Segoe UI",
    sans-serif;
  --mm-font-serif: "Instrument Serif", Georgia, "Times New Roman", serif;
  --mm-font-sans: "Inter", ui-sans-serif, system-ui, -apple-system,
    "Segoe UI", Roboto, sans-serif;
  --mm-font-mono: ui-monospace, "SF Mono", "JetBrains Mono", Menlo, monospace;

  /* Modular scale, ~1.25 ratio, 16px base */
  --mm-text-xs: 0.75rem;
  --mm-text-sm: 0.875rem;
  --mm-text-base: 1rem;
  --mm-text-lg: 1.25rem;
  --mm-text-xl: 1.563rem;
  --mm-text-2xl: 1.953rem;
  --mm-text-3xl: 2.441rem;
  --mm-text-4xl: 3.052rem;

  --mm-leading-tight: 1.15;
  --mm-leading-snug: 1.35;
  --mm-leading-normal: 1.6;

  --mm-tracking-tight: -0.02em;
  --mm-tracking-wide: 0.08em;

  --mm-weight-normal: 400;
  --mm-weight-medium: 500;
  --mm-weight-semibold: 600;
  --mm-weight-bold: 700;

  /* ---- Spacing — 4 / 8px rhythm ------------------------------------ */
  --mm-space-1: 0.25rem;
  --mm-space-2: 0.5rem;
  --mm-space-3: 0.75rem;
  --mm-space-4: 1rem;
  --mm-space-5: 1.5rem;
  --mm-space-6: 2rem;
  --mm-space-7: 3rem;
  --mm-space-8: 4rem;
  --mm-space-9: 6rem;

  /* ---- Radii ------------------------------------------------------- */
  --mm-radius-sm: 0.375rem;
  --mm-radius-md: 0.625rem;
  --mm-radius-lg: 1rem;
  --mm-radius-full: 999px;

  --mm-border-width: 1px;

  /* ---- Layout ------------------------------------------------------ */
  --mm-content-width: 68rem;

  /* ---- Motion -------------------------------------------------------
   * Four durations and three curves, and that is the whole vocabulary. See
   * docs/brand/README.md for which one a given change takes and why; the short
   * version is that the duration is chosen by what the movement has to explain,
   * never by how the number feels in isolation.
   *
   * The ceiling is 280ms. Above that a UI stops feeling like it is responding
   * and starts feeling like it is performing, and this is a page where someone
   * is checking whether their rent is covered.
   *
   * An exit is faster than the matching entrance (fast vs base). Something
   * arriving has to be noticed; something leaving has already been read, and
   * making the reader wait for it is the most common way an interface feels
   * slow while every request is quick.
   */
  --mm-ease-out: cubic-bezier(0.23, 1, 0.32, 1);
  --mm-ease-in-out: cubic-bezier(0.65, 0, 0.35, 1);

  /* A small overshoot, for a surface that appears from nothing — a menu, a
     popover. Deliberately NOT used on anything carrying a number: a figure that
     springs past its value and settles back has, for a moment, displayed a
     number that is not the one it means. */
  --mm-ease-spring: cubic-bezier(0.34, 1.42, 0.64, 1);

  /* Press feedback. Below ~100ms a press reads as instant contact rather than
     as an animation, which is the point of it. */
  --mm-duration-instant: 90ms;
  --mm-duration-fast: 130ms;
  --mm-duration-base: 200ms;
  --mm-duration-slow: 280ms;

  /* How long a request may run before the region it will replace is marked
     stale. Under this, the reply arrives first and nothing flickers; over it,
     the reader learns the figures they are looking at are being recalculated.
     130ms is roughly where a delay stops reading as "instant". */
  --mm-stale-after: 140ms;

  /* One step of a stagger. Three cards at 45ms read as a sequence; the same
     three at 150ms read as a queue the reader is waiting on. */
  --mm-stagger: 45ms;
}
