/* ═══════════════════════════════════════════════════════════════════
 * TARTAN OS — Apple-grade design tokens (v2)
 *
 * Loaded BEFORE the inline <style> block in index.html so every token
 * is available to every selector. Legacy var names (--blue, --card-bg,
 * --shadow-sm, etc.) are aliased at the bottom of this file so existing
 * CSS keeps rendering without a search-and-replace pass.
 *
 * ── 2026-05-25 FOUNDATION REWRITE ─────────────────────────────
 * The v1 file used iOS-style alpha-white label tokens
 * (rgba(235,235,245,*)) inside a `@media (prefers-color-scheme: dark)`
 * override. Any user with macOS in dark mode rendered every label
 * white-on-white because the dashboard / customer / finance cards
 * are hardcoded `background:#FFFFFF`, not surface tokens. ~4,071 WCAG
 * failures across the app. Audit Part 1 has the breakdown.
 *
 * Fix: switched to alpha-BLACK label tokens (rgba(15,17,26,*)) per
 * Linear/Vercel/Stripe convention. These render correctly on light
 * cards REGARDLESS of OS color scheme. The `@media (prefers-color-
 * scheme: dark)` block is removed entirely — the app is not actually
 * dark-mode aware (hardcoded white backgrounds in 200+ component
 * styles), so the override was doing harm not good. A real dark-mode
 * pass needs the component-level rewrite Audit Part 2 lays out;
 * that's tracked separately.
 *
 * Separate `--label-*-dark` tokens added for the few intentionally-
 * dark components (sidebar nav, CMO brief card) that pair with
 * white-on-dark text.
 *
 * Brand green (#007b4b) is reserved for the logo and customer-facing
 * documents (PDFs, public quote/invoice pages). DO NOT use as a UI
 * state color — use --accent / --success / --danger.
 * ═══════════════════════════════════════════════════════════════════ */

:root {
  /* ── Font stacks ─────────────────────────────────────────────── */
  --font-system: -apple-system, BlinkMacSystemFont, "SF Pro Text", "SF Pro Display", "Inter", "Segoe UI", system-ui, sans-serif;
  --font-display: -apple-system, BlinkMacSystemFont, "SF Pro Display", "Inter", system-ui, sans-serif;
  --font-mono: ui-monospace, "SF Mono", Menlo, monospace;
  /* v3 sweep alias — spec uses --font-sans; map to --font-system so
     either name works in app chrome. --font-mono stays canonical for
     invoice #, SKU, IDs (the only places monospace is allowed). */
  --font-sans: var(--font-system);

  /* ── v4 hardening tokens (2026-05-25) ──
     Named in the v4 spec — each one is the AA-compliant value Dom
     called out. They didn't exist as canonical tokens before; new
     code should reference these directly. Existing inline styles
     using the raw hex are unchanged for backward compat. */
  --brand-cyan:        #0369A1;   /* sky-700, white text reads 4.6:1 */
  --brand-cyan-hover:  #075985;
  --link-on-tint:      #1D4ED8;   /* blue-700, 7.0:1 on #E8EFFD */
  --tint-bg-blue:      #E8EFFD;
  --chip-bg-warmgray:  #4B5563;   /* slate-600, white text reads 8:1 */
  --text-on-cyan-btn:  #FFFFFF;

  /* ── Type scale (premium SaaS density: smaller body, tighter
       tracking at large sizes per SF Pro convention) ─────────── */
  --text-overline:   10px;
  --text-caption:    11px;
  --text-footnote:   12px;
  --text-callout:    13px;
  --text-body:       14px;
  --text-headline:   15px;
  --text-title-3:    18px;
  --text-title-2:    22px;
  --text-title-1:    28px;
  --text-display:    34px;

  --lh-overline:     12px;
  --lh-caption:      14px;
  --lh-footnote:     16px;
  --lh-callout:      18px;
  --lh-body:         20px;
  --lh-headline:     20px;
  --lh-title-3:      24px;
  --lh-title-2:      28px;
  --lh-title-1:      34px;
  --lh-display:      40px;

  --tracking-overline:  0.080em;
  --tracking-caption:   0.020em;
  --tracking-footnote:  0.002em;
  --tracking-callout:   0;
  --tracking-body:      0;
  --tracking-headline: -0.006em;
  --tracking-title-3:  -0.011em;
  --tracking-title-2:  -0.016em;
  --tracking-title-1:  -0.020em;
  --tracking-display:  -0.022em;

  --weight-regular: 400;
  --weight-medium: 500;
  --weight-semibold: 600;
  --weight-bold: 700;

  /* ── Surfaces ────────────────────────────────────────────────── */
  --bg-canvas:      #F7F7F8;   /* page background (was #F2F2F7) */
  --bg-elevated:    #FFFFFF;   /* cards, sheets, modals */
  --bg-sunken:      #F1F1F3;   /* table rows on stripe, input fields */
  --bg-overlay:     rgba(20, 22, 28, 0.48);

  /* ── Borders (split hairline vs emphasis) ────────────────────── */
  --border-hairline: rgba(15, 17, 26, 0.06);
  --border-default:  rgba(15, 17, 26, 0.10);
  --border-strong:   rgba(15, 17, 26, 0.16);
  --border-focus:    #1D4ED8;

  /* ── Light-surface labels — alpha-BLACK, the 92/68/52/36 ramp ─
       The Linear/Vercel/Stripe hierarchy. Each text-class step is
       perceptually equal-distant and every step used for text
       passes WCAG AA on white. Verified by
       tests/test_ui_token_contrast.py. */
  --label-primary:    rgba(15, 17, 26, 0.92);  /* 14.2:1 — body, titles */
  --label-secondary:  rgba(15, 17, 26, 0.68);  /*  6.8:1 — sublines */
  --label-tertiary:   rgba(15, 17, 26, 0.60);  /*  5.2:1 — captions, inactive tabs (spec said .52 → 4.7:1; measured at 3.92:1, bumped to .60 for AA) */
  --label-quaternary: rgba(15, 17, 26, 0.36);  /*  3.1:1 — DECORATIVE ONLY (icons, dividers) */
  --label-disabled:   rgba(15, 17, 26, 0.28);  /*       — disabled controls */

  /* ── Dark-surface labels — for sidebar nav + CMO brief card only.
       Components that paint a dark background MUST reference these
       (or set their own opaque color), NOT the light-surface labels. */
  --label-primary-dark:    rgba(255, 255, 255, 0.96);
  --label-secondary-dark:  rgba(255, 255, 255, 0.72);
  --label-tertiary-dark:   rgba(255, 255, 255, 0.56);
  --label-quaternary-dark: rgba(255, 255, 255, 0.40);

  /* ── Fills (subtle backgrounds for controls + hover states) ──── */
  --fill-primary:    rgba(15, 17, 26, 0.12);
  --fill-secondary:  rgba(15, 17, 26, 0.08);
  --fill-tertiary:   rgba(15, 17, 26, 0.06);
  --fill-quaternary: rgba(15, 17, 26, 0.04);

  /* ── Brand — Tartan green pushed darker for legibility on white ─ */
  --brand:         #0A6A40;            /* 6.8:1 on white */
  --brand-hover:   #085633;
  --brand-pressed: #064328;
  --brand-tint:    #E6F4ED;
  --brand-on:      #FFFFFF;

  /* ── Accent — replaces iOS #007AFF (borderline 4.6:1) ───────── */
  --accent:        #1D4ED8;            /* 6.0:1 on white */
  --accent-hover:  #1A56C5;
  --accent-pressed:#154AAA;
  --accent-tint:   #E8EFFD;
  --accent-on:     #FFFFFF;

  /* ── Status (each ≥4.5:1 on white AND ≥3:1 on their tint) ───── */
  --success:       #117A3D;  --success-tint: #E4F4EA;
  --warning:       #8A5A00;  --warning-tint: #FBEFD3;
  --danger:        #B42318;  --danger-tint:  #FCE7E4;
  --info:          #175CD3;  --info-tint:    #E6EEFB;
  --neutral-tint:  #EEF0F3;

  /* ── iOS systemColors (kept for components that need a vivid
       per-platform color — but UI state should reference --accent,
       --success, --danger, --warning above instead). ────────────── */
  --system-blue:   var(--accent);
  --system-green:  var(--success);
  --system-orange: #FF9500;
  --system-red:    var(--danger);
  --system-purple: #AF52DE;
  --system-pink:   #FF2D55;
  --system-indigo: #5856D6;
  --system-teal:   #5AC8FA;
  --system-yellow: #FFCC00;
  --system-gray:   #8E8E93;
  --system-gray-2: #AEAEB2;
  --system-gray-3: #C7C7CC;
  --system-gray-4: #D1D1D6;
  --system-gray-5: #E5E5EA;
  --system-gray-6: #F2F2F7;

  /* ── Sidebar (intentionally dark — uses *-dark labels) ──────── */
  --sidebar-bg:          #0E1422;
  --sidebar-hover:       #1A2236;
  --sidebar-active:      rgba(31, 102, 229, 0.18);
  --sidebar-text:        rgba(255, 255, 255, 0.72);
  --sidebar-text-active: #FFFFFF;
  --sidebar-icon:        rgba(255, 255, 255, 0.56);
  --sidebar-width:       232px;

  /* ── Radii ───────────────────────────────────────────────────── */
  --radius-control: 10px;
  --radius-card:    14px;
  --radius-modal:   18px;
  --radius-sheet:   22px;
  --radius-pill:    999px;

  /* ── Elevation — soft shadow + 1px ring so cards stay crisp ──── */
  --ring-card:    inset 0 0 0 1px var(--border-hairline);
  --shadow-1: 0 1px 2px rgba(15, 17, 26, 0.04), var(--ring-card);
  --shadow-2: 0 1px 2px rgba(15, 17, 26, 0.04), 0 8px 24px -8px rgba(15, 17, 26, 0.08), var(--ring-card);
  --shadow-3: 0 4px 12px -4px rgba(15, 17, 26, 0.08), 0 24px 48px -12px rgba(15, 17, 26, 0.18), var(--ring-card);
  --shadow-focus: 0 0 0 3px rgba(31, 102, 229, 0.28);

  /* ── Motion (spec-tightened: snappier than v2) ──────────────── */
  --motion-instant:    100ms;
  --motion-fast:       150ms;
  --motion-standard:   200ms;
  --motion-emphasized: 300ms;
  --ease-standard:    cubic-bezier(.4, 0, .2, 1);
  --ease-decelerate:  cubic-bezier(0, 0, .2, 1);
  --ease-accelerate:  cubic-bezier(.4, 0, 1, 1);
  --ease-spring:      cubic-bezier(.34, 1.56, .64, 1);

  /* ── Brand identity (LOGO + customer-facing docs ONLY) ──────── */
  --brand-green:        var(--brand);
  --brand-green-light:  var(--brand-tint);
}

@media (prefers-reduced-motion: reduce) {
  :root {
    --motion-instant:    0ms;
    --motion-fast:       0ms;
    --motion-standard:   0ms;
    --motion-emphasized: 0ms;
  }
}

/* NOTE: the @media (prefers-color-scheme: dark) block from v1 has been
   REMOVED. It was rewriting label tokens to alpha-WHITE values that
   collapsed to white-on-white when applied to the app's hardcoded
   white card backgrounds. The app is not currently dark-mode aware;
   bringing it back requires component-level rewrites (Audit Part 2
   §2.4) that ship dark-card variants in every render function. */

/* ═══════════════════════════════════════════════════════════════════
 * LEGACY ALIASES — preserve every var name the inline <style> block
 * uses so existing CSS keeps rendering without a search-and-replace
 * pass through 47K lines of HTML. New code references the canonical
 * names directly.
 * ═══════════════════════════════════════════════════════════════════ */
:root {
  --content-bg:    var(--bg-canvas);
  --bg-grouped:    var(--bg-canvas);
  --bg-grouped-secondary: var(--bg-elevated);
  --card-bg:       var(--bg-elevated);
  --card-border:   var(--border-default);
  --border-light:  var(--border-hairline);
  --border:        var(--border-default);
  --separator:     var(--border-default);
  --separator-opaque: #C6C6C8;
  --text:          var(--label-primary);
  --text-primary:  var(--label-primary);
  --text-secondary: var(--label-secondary);
  --text-muted:    var(--label-tertiary);
  --text-subtle:   var(--label-tertiary);
  --text-hint:     var(--label-quaternary);
  --blue:          var(--accent);
  --blue-light:    var(--accent-tint);
  --green:         var(--success);
  --green-light:   var(--success-tint);
  --red:           var(--danger);
  --red-light:     var(--danger-tint);
  --amber:         var(--warning);
  --amber-light:   var(--warning-tint);
  --purple:        var(--system-purple);
  --purple-light:  rgba(175,82,222,.12);
  --cyan:          var(--system-teal);
  --cyan-light:    rgba(90,200,250,.14);
  --yellow:        var(--system-yellow);
  --radius:        var(--radius-card);
  --shadow-sm:     var(--shadow-1);
  --shadow:        var(--shadow-1);
  --shadow-lg:     var(--shadow-2);
}

/* ═══════════════════════════════════════════════════════════════════
 * BASE TYPOGRAPHY
 * Apply the system font stack to html AND body so the page stops
 * falling back to Times in browsers where body inherits from html.
 * Enable tabular numerals so $ columns and timestamps align — this
 * alone makes Finance + Insights read 10× more premium.
 * ═══════════════════════════════════════════════════════════════════ */
html, body {
  font-family: var(--font-system);
  font-feature-settings: "ss01", "cv11";
  font-variant-numeric: tabular-nums;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
}
body {
  font-size: var(--text-body);
  line-height: var(--lh-body);
  color: var(--label-primary);
  background: var(--bg-canvas);
}

h1, h2, h3, h4 {
  font-family: var(--font-display);
  color: var(--label-primary);
}
h1 { font-size: var(--text-display); line-height: var(--lh-display); letter-spacing: var(--tracking-display); font-weight: var(--weight-semibold); }
h2 { font-size: var(--text-title-1); line-height: var(--lh-title-1); letter-spacing: var(--tracking-title-1); font-weight: var(--weight-semibold); }
h3 { font-size: var(--text-title-2); line-height: var(--lh-title-2); letter-spacing: var(--tracking-title-2); font-weight: var(--weight-semibold); }
h4 { font-size: var(--text-headline); line-height: var(--lh-headline); letter-spacing: var(--tracking-headline); font-weight: var(--weight-semibold); }

/* ═══════════════════════════════════════════════════════════════════
 * DARK-SURFACE LABEL REBIND
 * Any component inside an intentionally-dark container (sidebar nav,
 * CMO brief card) needs the label tokens to resolve to their
 * alpha-WHITE *-dark variants. Without this rebind, descendants that
 * inherit --label-primary / --label-secondary / --label-tertiary
 * render as DARK text (rgba(15,17,26,*) per the v2 light ramp)
 * against the dark background = invisible.
 *
 * Scoped rebind: redeclare the canonical token names on the dark
 * container so every descendant inherits the dark-mode values. This
 * is the OPPOSITE of the v1 mistake (a media query that rebound
 * tokens globally based on OS dark mode). Here we rebind ONLY when
 * the markup explicitly opts in by placing content inside .sidebar
 * or .surface-dark.
 *
 * Legacy aliases (--text, --text-secondary, --text-muted) follow
 * automatically because they're defined as `var(--label-*)`.
 * ═══════════════════════════════════════════════════════════════════ */
.sidebar,
.surface-dark {
  --label-primary:    var(--label-primary-dark);
  --label-secondary:  var(--label-secondary-dark);
  --label-tertiary:   var(--label-tertiary-dark);
  --label-quaternary: var(--label-quaternary-dark);
  color: var(--label-primary);
}

/* Belt-and-suspenders: any inline-SVG injected via [data-icon] without
   intrinsic width/height should never escape to viewport size. The JS
   renderIcons() helper also injects a width/height attribute on every
   SVG, but if a future raw inject misses that step the CSS clamp here
   prevents a giant clipboard from filling the form pane. */
[data-icon] > svg {
  width: 1em;
  height: 1em;
  max-width: 24px;
  max-height: 24px;
  vertical-align: middle;
}
