/* ==========================================================================
   ds.css — design system tokens for the premium rebuild.
   Phase 1. ADDITIVE: this file does not touch tokens.css, which 86 pages load.

   Roles, not names. Components must reference these tokens and never a raw
   hex, so a palette change is one edit rather than 86.

   Contrast is measured, not eyeballed (WCAG 2.2 AA, brief 109). The brief's
   suggested primary #16A34A was rejected: it lands at 3.30:1 on white, which
   fails as text AND fails with white text on it. The greens below were picked
   by computing ratios.
   ========================================================================== */

.ds {
  /* ---- Neutrals -------------------------------------------------------
     Not pure grey. Biased a few degrees toward the green accent so the
     surfaces read as chosen rather than inherited. */
  --c-bg:            #ffffff;   /* page ground                              */
  --c-bg-soft:       #f6fdf9;   /* palest mint, section banding             */
  --c-bg-sunk:       #eaf7ef;   /* mint wells, inset areas                  */
  --c-surface:       #ffffff;   /* cards, panels                            */
  --c-surface-2:     #fbfefc;   /* raised-on-soft                           */

  /* Ink is navy, not black: it reads as finance software rather than print,
     and it is what keeps the mint surfaces looking deliberate. */
  --c-ink:           #0f172a;   /* 17.85:1 on white — primary text          */
  --c-ink-2:         #475569;   /*  7.58:1 on white — secondary text        */
  --c-ink-3:         #64748b;   /*  4.76:1 on white — smallest passing text */
  --c-ink-faint:     #94a3b8;   /*  2.9:1 — DECORATIVE ONLY, never text     */

  --c-line:          rgba(15, 23, 42, .08);
  --c-line-2:        rgba(15, 23, 42, .13);
  --c-line-strong:   rgba(15, 23, 42, .20);

  /* ---- Green = structured, validated financial data (brief 137) --------
     Green is an interaction and product colour. It is never the background.

     Every value below was measured, not picked by eye. The vivid greens this
     direction wants (#22c55e at 2.28:1, #16a34a at 3.30:1) cannot legally
     carry white text, so they are kept for non-text accents only and the
     fill is the brightest green that still passes AA with white on it. */
  --c-green:         #15803d;   /* 5.02:1 — fills; white text on it passes  */
  --c-green-hover:   #127035;
  --c-green-press:   #0f5f2d;
  --c-green-text:    #127a3a;   /* 5.43:1 — green text on white             */
  --c-green-bright:  #22c55e;   /* 2.28:1 — NON-TEXT only: rings, orbits    */
  --c-green-mid:     #16a34a;   /* 3.30:1 — NON-TEXT only: dots, bars       */
  --c-green-soft:    #e8f6ee;   /* validated-cell wash                      */
  --c-green-line:    #b7e4c8;
  --c-on-green:      #ffffff;

  /* ---- Semantic, deliberately separate from the accent hue ------------- */
  --c-warn:          #a8620f;
  --c-warn-soft:     #fdf3e3;
  --c-danger:        #b3253f;
  --c-danger-soft:   #fdecef;
  --c-on-danger:     #ffffff;

  /* ---- Type (brief 8) — one family, hierarchy from weight and tracking -- */
  --font-sans: "Inter", ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif;
  --font-mono: "JetBrains Mono", ui-monospace, SFMono-Regular, Menlo, monospace;

  --fs-display: clamp(40px, 6vw, 72px);   /* hero, capped at 72 per brief   */
  --fs-h1:      clamp(34px, 4.8vw, 56px);
  --fs-h2:      clamp(26px, 3.2vw, 38px);
  --fs-h3:      20px;
  --fs-body-l:  18px;
  --fs-body:    16px;
  --fs-label:   13px;
  --fs-caption: 12px;

  --fw-regular: 450;   /* brief 8: prefer 450-650 over bolding everything   */
  --fw-medium:  500;
  --fw-semi:    600;
  --fw-strong:  650;

  --tr-display: -.03em;   /* tight tracking on display sizes                */
  --tr-head:    -.02em;
  --tr-body:     0;
  --tr-caps:     .14em;

  --lh-display: 1.04;
  --lh-head:    1.15;
  --lh-body:    1.6;

  /* ---- Spacing (brief 10) — a real scale, no arbitrary values ---------- */
  --s-1: 4px;   --s-2: 8px;   --s-3: 12px;  --s-4: 16px;  --s-5: 24px;
  --s-6: 32px;  --s-7: 48px;  --s-8: 64px;  --s-9: 96px;  --s-10: 128px;

  --wrap:       1280px;   /* brief 10: 1240-1320 desktop content width      */
  --wrap-pad:   clamp(16px, 4vw, 32px);

  /* ---- Radii (brief 11) — not everything is a pill --------------------- */
  --r-control: 10px;
  --r-button:  12px;
  --r-card:    18px;
  --r-panel:   28px;
  --r-pill:    999px;   /* reserved for chips and badges only              */

  /* ---- Elevation (brief 12) — most containers use border, not shadow --- */
  --e-control: 0 1px 2px rgba(15, 23, 42, .05);
  --e-card:    0 1px 2px rgba(15, 23, 42, .04), 0 8px 24px -16px rgba(15, 23, 42, .18);
  --e-float:   0 2px 4px rgba(15, 23, 42, .04), 0 18px 40px -20px rgba(15, 23, 42, .24);
  --e-modal:   0 24px 60px -24px rgba(15, 23, 42, .32);
  --e-green:   0 6px 18px -8px rgba(21, 128, 61, .40);

  /* ---- Motion (brief 130) ---------------------------------------------- */
  --t-fast:   180ms;
  --t-normal: 280ms;
  --t-slow:   560ms;
  --ease-out:   cubic-bezier(.2, .8, .2, 1);     /* settle                  */
  --ease-inout: cubic-bezier(.4, 0, .2, 1);      /* panels, nav, accordions */
  --ease-pop:   cubic-bezier(.34, 1.56, .64, 1); /* small physical objects  */

  color: var(--c-ink);
  background: var(--c-bg);
  font-family: var(--font-sans);
  font-size: var(--fs-body);
  line-height: var(--lh-body);
  -webkit-font-smoothing: antialiased;
}

/* Spring constants for JS-driven motion (brief 131). Kept beside the CSS
   tokens so the two systems cannot drift apart.
     UI      — stiffness 420, damping 32
     Physical— stiffness 260, damping 26  (cards, documents, 3D objects) */

/* ---- Type helpers ------------------------------------------------------ */
.ds .t-display { font-size: var(--fs-display); font-weight: var(--fw-strong);
  letter-spacing: var(--tr-display); line-height: var(--lh-display); text-wrap: balance; }
.ds .t-h2 { font-size: var(--fs-h2); font-weight: var(--fw-strong);
  letter-spacing: var(--tr-head); line-height: var(--lh-head); text-wrap: balance; }
.ds .t-h3 { font-size: var(--fs-h3); font-weight: var(--fw-semi);
  letter-spacing: var(--tr-head); }
.ds .t-body-l { font-size: var(--fs-body-l); color: var(--c-ink-2); }
.ds .t-label { font-size: var(--fs-label); font-weight: var(--fw-semi); }
.ds .t-caps { font-size: var(--fs-caption); font-weight: var(--fw-strong);
  letter-spacing: var(--tr-caps); text-transform: uppercase; color: var(--c-ink-3); }
.ds .t-num { font-variant-numeric: tabular-nums; }

/* ---- Layout ------------------------------------------------------------ */
.ds .wrap { max-width: var(--wrap); margin-inline: auto; padding-inline: var(--wrap-pad); }

/* ---- Focus (brief 112): never removed, always replaced ----------------- */
.ds :focus-visible {
  outline: 2px solid var(--c-green);
  outline-offset: 3px;
  border-radius: var(--r-control);
}

/* ---- Reduced motion (brief 111) ---------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  .ds *, .ds *::before, .ds *::after {
    animation-duration: .001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .001ms !important;
    scroll-behavior: auto !important;
  }
}
