/* ═══════════════════════════════════════════════════
   Design System Tokens · v4
   Source: https://design.seantippen.com/

   Import in any project:
   <link rel="stylesheet" href="https://design.seantippen.com/tokens.css">

   A 3-variable GENERATOR tier sits at the top:
     --accent-h, --secondary-h, --base-h, --contrast
   Surfaces, text, and accents DERIVE from those via
   oklch() with var() channels. Default output matches the
   original palette, so every linked dashboard renders
   unchanged, but the whole system can be re-skinned by
   changing the hue/contrast variables (the live generator).

   v3 self-hosts the three faces (Inter, JetBrains Mono,
   Big Shoulders Display) via @font-face below, served from
   this same domain with long-cache immutable headers. No
   Google Fonts link is needed in a consuming page. All three
   are OFL variable fonts, latin subset.

   Rules:
   - Consume SEMANTIC tokens (--color-*, --space-*, etc.).
   - The channel/generator vars are an implementation tier.
   - Do NOT edit per-project. Update this file, push, every
     linked project picks up the change.
   - Public token names never change or disappear; the
     compatibility-alias block near the bottom stays.
   ═══════════════════════════════════════════════════ */

/* ─── Self-hosted faces (absolute URLs so the ~40 CDN
   consumers resolve them against this domain, not their own).
   Variable weight, latin subset, font-display: swap. ─── */
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 300 900;
  font-display: swap;
  src: url(fonts/inter-latin-var.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'JetBrains Mono';
  font-style: normal;
  font-weight: 100 800;
  font-display: swap;
  src: url(fonts/jetbrains-mono-latin-var.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Big Shoulders Display';
  font-style: normal;
  font-weight: 500 900;
  font-display: swap;
  src: url(fonts/big-shoulders-display-latin-var.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

/* ─── DARK MODE (default) ─── */
:root {
  color-scheme: dark;

  /* ═══ GENERATOR TIER ═══
     Three hue knobs + one contrast knob drive the system.
     Blurple (hue 270-285) is structurally avoided: the cyan
     accent sits at 195, the neon-pink secondary at 320. */
  --accent-h: 195;          /* cyan - the one rationed accent */
  --accent-c: 0.17;
  --secondary-h: 320;       /* neon pink - state / secondary only */
  --secondary-c: 0.25;
  --base-h: 252;            /* cool-rich neutral hue for surfaces + text */
  --base-c: 0.015;          /* surface chroma (the faint backlight glow) */
  --contrast: 1;            /* 0.85 calm … 1.2 high-contrast (dark mode) */

  /* === Accents (derived from the hue/chroma knobs) === */
  --color-accent:            oklch(0.75 var(--accent-c) var(--accent-h));
  --color-accent-hover:      oklch(0.80 var(--accent-c) var(--accent-h));
  --color-accent-solid-hover: oklch(0.70 var(--accent-c) var(--accent-h)); /* Radix step 10 */
  --color-accent-border:     oklch(0.62 calc(var(--accent-c) * 0.9) var(--accent-h)); /* step 7-8 */
  --color-secondary:         oklch(0.70 var(--secondary-c) var(--secondary-h));

  /* Backward-compat RGB for components using rgba(var(...), x) */
  --color-accent-rgb: 0, 205, 207;
  --color-secondary-rgb: 223, 89, 252;

  /* Derived accent scales */
  --accent-muted:  oklch(0.87 var(--accent-c) var(--accent-h) / 0.15);
  --accent-subtle: oklch(0.87 var(--accent-c) var(--accent-h) / 0.08);

  /* === Surfaces - 5-level elevation ===
     Lightness pivots on 0.22; --contrast widens/narrows the
     spread. At --contrast:1 the values equal v1 exactly. */
  --color-bg:              oklch(calc(0.22 - 0.08 * var(--contrast)) var(--base-c) var(--base-h));
  --color-surface:         oklch(calc(0.22 - 0.04 * var(--contrast)) var(--base-c) var(--base-h));
  --color-surface-hover:   oklch(0.22 0.016 var(--base-h));
  --color-surface-raised:  oklch(calc(0.22 + 0.04 * var(--contrast)) 0.016 var(--base-h));
  --color-surface-overlay: oklch(calc(0.22 + 0.08 * var(--contrast)) 0.017 var(--base-h));

  /* === Text Hierarchy ===
     Lightness pivots on 0.665; --contrast pushes text brighter
     and muted darker. At --contrast:1 values equal v1 exactly. */
  --color-text:           oklch(calc(0.665 + 0.265 * var(--contrast)) 0.012 var(--base-h));
  --color-text-secondary: oklch(calc(0.665 + 0.085 * var(--contrast)) 0.012 var(--base-h));
  --color-text-muted:     oklch(calc(0.665 - 0.115 * var(--contrast)) 0.016 var(--base-h));
  --color-text-disabled:  oklch(calc(0.665 - 0.265 * var(--contrast)) 0.012 var(--base-h));

  /* === Opacity-Based Text (fine-grained hierarchy) === */
  --text-alpha-90: oklch(0.93 0.012 var(--base-h) / 0.9);
  --text-alpha-70: oklch(0.93 0.012 var(--base-h) / 0.7);
  --text-alpha-50: oklch(0.93 0.012 var(--base-h) / 0.5);
  --text-alpha-30: oklch(0.93 0.012 var(--base-h) / 0.3);
  --text-alpha-15: oklch(0.93 0.012 var(--base-h) / 0.15);

  /* === Borders (neutral white-alpha, hue-independent) === */
  --color-border: oklch(1 0 0 / 0.08);
  --color-border-emphasis: oklch(1 0 0 / 0.15);
  --color-border-strong: oklch(1 0 0 / 0.25);

  /* === Status Colors (fixed semantic hues, never accent-swapped) === */
  --color-success: oklch(0.72 0.17 145);
  --color-warning: oklch(0.80 0.16 85);
  --color-danger: oklch(0.70 0.19 25);
  --color-info: oklch(0.72 0.14 230);
  --color-success-subtle: oklch(0.22 0.05 145);
  --color-warning-subtle: oklch(0.24 0.06 85);
  --color-danger-subtle: oklch(0.22 0.05 25);
  --color-info-subtle: oklch(0.22 0.05 230);

  /* === Shadows === */
  --shadow-sm: 0 1px 2px oklch(0 0 0 / 0.3);
  --shadow-md: 0 4px 12px oklch(0 0 0 / 0.4);
  --shadow-lg: 0 12px 32px oklch(0 0 0 / 0.5);
  --shadow-ring: 0 0 0 0.5px oklch(1 0 0 / 0.1);
  --shadow-float: 0 4px 20px oklch(0 0 0 / 0.3), var(--shadow-ring);
  --shadow-float-lg: 0 12px 40px oklch(0 0 0 / 0.4), var(--shadow-ring);

  /* === Focus === */
  --focus-ring: 0 0 0 2px var(--color-bg), 0 0 0 4px var(--color-accent);

  /* === Data Series (hex - Canvas API can't resolve OKLCH) === */
  --green: #4CC97A;
  --blue: #6BA3FF;
  --red: #F28878;
  --amber: #D4AD42;
  --purple: #C688E0;
  --cyan: #4BC3CA;
  --yellow: #E8D44D;
  --orange: #E89B4D;

  /* === Type Badge Palette === */
  --color-type-dashboard: #60a5fa;
  --color-type-chatbot: #a78bfa;
  --color-type-gallery: #fbbf24;
  --color-type-xlsx: #4ade80;
  --color-type-seatmap: #2dd4bf;
  --color-type-report: #94a3b8;
  --color-type-app: #f97316;
  --color-type-research: #22d3ee;

  /* === Typography - fluid clamp() scale === */
  --font-sans: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
  --font-mono: 'JetBrains Mono', 'Fira Code', monospace;
  --font-display: 'Big Shoulders Display', 'Inter', sans-serif;
  /* Scale bumped up 2026-06-16: the whole system read too small and too
     cramped. Every step's floor AND ceiling moved up. --text-xs (13px floor)
     is now the absolute minimum for ANY text, and --text-label is the floor
     for every uppercase mono label (nav, eyebrows, KPI/stat labels, table
     headers). The raw sub-13px font-sizes that used to live in components.css
     were routed onto these tokens. Size only via --text-* tokens. */
  --text-xs:    clamp(0.8125rem, 0.78rem + 0.2vw, 0.9375rem);   /* 13 -> 15 · absolute floor */
  --text-sm:    clamp(0.9375rem, 0.9rem + 0.28vw, 1.0625rem);   /* 15 -> 17 */
  --text-label: clamp(0.875rem, 0.84rem + 0.18vw, 0.9375rem);   /* 14 -> 15 · uppercase mono label floor */
  --text-base:  clamp(1.0625rem, 1rem + 0.32vw, 1.1875rem);     /* 17 -> 19 · body default */
  --text-lg:    clamp(1.28rem, 1.15rem + 0.6vw, 1.5rem);        /* 20.5 -> 24 · subsection headers */
  --text-xl:    clamp(1.625rem, 1.3rem + 1.3vw, 2.25rem);       /* 26 -> 36 */
  --text-2xl:   clamp(2.125rem, 1.6rem + 2.1vw, 3.25rem);       /* 34 -> 52 · section titles */
  --text-3xl:   clamp(2.75rem, 1.9rem + 3.4vw, 4.375rem);       /* 44 -> 70 · page titles */
  --text-4xl:   clamp(3.375rem, 2.2rem + 4.7vw, 5.75rem);       /* 54 -> 92 · hero */

  /* === Leading === */
  --leading-tight: 1.2;
  --leading-snug: 1.35;
  --leading-normal: 1.5;
  --leading-relaxed: 1.65;
  --measure: 65ch;

  /* === Tracking (display + label) === */
  --tracking-display: -0.03em;
  --tracking-tight: -0.01em;
  --tracking-label: 0.12em;

  /* === Fluid Spacing === */
  /* Spacing bumped 2026-06-16 alongside the type scale: more air between
     blocks, the system read cramped. */
  --space-xs: clamp(0.375rem, 0.3rem + 0.2vw, 0.625rem);
  --space-sm: clamp(0.625rem, 0.5rem + 0.45vw, 1rem);
  --space-md: clamp(1.125rem, 0.95rem + 0.6vw, 1.75rem);
  --space-lg: clamp(1.75rem, 1.4rem + 1.1vw, 3rem);
  --space-xl: clamp(2.5rem, 1.9rem + 2.2vw, 5rem);

  /* === Fixed Spacing (4px base) === */
  --space-1: 0.25rem;
  --space-2: 0.5rem;
  --space-3: 0.75rem;
  --space-4: 1rem;
  --space-5: 1.25rem;
  --space-6: 1.5rem;
  --space-8: 2rem;
  --space-10: 2.5rem;
  --space-12: 3rem;
  --space-16: 4rem;
  --space-section: clamp(4rem, 2.75rem + 5vw, 7rem);

  /* === Motion === */
  --duration-instant: 80ms;
  --duration-fast: 150ms;
  --duration-normal: 250ms;
  --duration-slow: 400ms;
  --duration-slower: 600ms;
  --ease-out: cubic-bezier(0, 0, 0.2, 1);
  --ease-out-expo: cubic-bezier(0.16, 1, 0.3, 1);
  --ease-in: cubic-bezier(0.4, 0, 1, 1);
  --ease-in-out: cubic-bezier(0.4, 0, 0.2, 1);
  --ease-spring: cubic-bezier(0.34, 1.56, 0.64, 1);
  --ease-bounce: cubic-bezier(0.34, 1.56, 0.64, 1);

  /* === Border Radius - sharp by default === */
  --radius-xs: 0;
  --radius-sm: 0;
  --radius-md: 0;
  --radius: 0;
  --radius-lg: 0;
  --radius-xl: 0;
  --radius-full: 9999px;

  /* === Layout === */
  --max-width: 1100px;
  --sidebar-w: 260px;

  /* === Native control theming (v4) ===
     Checkboxes, radios, range inputs, and scrollbars pick up
     the system palette in every consumer with no markup change. */
  accent-color: var(--color-accent);
  scrollbar-color: var(--color-border-strong) transparent;

  /* === Compatibility Aliases ===
     Legacy dashboards use short names. New code should
     use the --color-* names directly.                    */
  --bg: var(--color-bg);
  --surface: var(--color-surface);
  --surface2: var(--color-surface-hover);
  --surface3: var(--color-surface-raised);
  --surface-hover: var(--color-surface-hover);
  --text: var(--color-text);
  --text-dim: var(--color-text-secondary);
  --text-muted: var(--color-text-muted);
  --text-secondary: var(--color-text-secondary);
  --text-disabled: var(--color-text-disabled);
  --accent: var(--color-accent);
  --accent2: var(--color-secondary);
  --secondary: var(--color-secondary);
  --border: var(--color-border);
  --border-emphasis: var(--color-border-emphasis);
}

/* ─── Richer springs where supported (multi-point linear()) ───
   Degrades to the cubic-bezier spring above on older engines. */
@supports (animation-timing-function: linear(0, 1)) {
  :root {
    --ease-spring: linear(0, 0.0085 1.3%, 0.034, 0.073 4%, 0.165 6.1%, 0.395 11%, 0.5 13.2%, 0.595, 0.68, 0.75, 0.81 22.9%, 0.86, 0.9 28.1%, 0.95 32.4%, 0.985 37%, 1.005 41.6%, 1.025 49.6%, 1.025 54.8%, 1.013 64%, 1.003 78.3%, 1);
    --ease-bounce: linear(0, 0.063, 0.25, 0.563, 1 36.4%, 0.81, 0.75 50.9%, 0.81, 1 72.7%, 0.94, 0.91, 0.94, 1 100%);
  }
}

/* ─── LIGHT MODE ───
   Supports both class-based (.light) and attribute-based
   (data-theme="light") toggling for cross-project compat.
   Surfaces/text re-derive on the same hue knobs so accent
   swapping still works; --contrast is dark-tuned. */
:root.light,
html[data-theme="light"] {
  color-scheme: light;

  --accent-c: 0.18;
  --secondary-c: 0.24;

  --color-accent:            oklch(0.52 var(--accent-c) var(--accent-h));
  --color-accent-hover:      oklch(0.48 var(--accent-c) var(--accent-h));
  --color-accent-solid-hover: oklch(0.46 var(--accent-c) var(--accent-h));
  --color-accent-border:     oklch(0.58 var(--accent-c) var(--accent-h));
  --color-secondary:         oklch(0.60 var(--secondary-c) var(--secondary-h));
  --color-accent-rgb: 0, 133, 137;
  --color-secondary-rgb: 187, 58, 214;
  --accent-muted:  oklch(0.52 var(--accent-c) var(--accent-h) / 0.12);
  --accent-subtle: oklch(0.52 var(--accent-c) var(--accent-h) / 0.06);

  --color-bg:              oklch(0.935 0.008 var(--base-h));
  --color-surface:         oklch(1 0 0);
  --color-surface-hover:   oklch(0.955 0.006 var(--base-h));
  --color-surface-raised:  oklch(1 0 0);
  --color-surface-overlay: oklch(1 0 0);

  --color-text:           oklch(0.16 0.018 var(--base-h));
  --color-text-secondary: oklch(0.35 0.014 var(--base-h));
  --color-text-muted:     oklch(0.50 0.012 var(--base-h));
  --color-text-disabled:  oklch(0.68 0.006 var(--base-h));

  --text-alpha-90: oklch(0.16 0.018 var(--base-h) / 0.9);
  --text-alpha-70: oklch(0.16 0.018 var(--base-h) / 0.7);
  --text-alpha-50: oklch(0.16 0.018 var(--base-h) / 0.5);
  --text-alpha-30: oklch(0.16 0.018 var(--base-h) / 0.3);
  --text-alpha-15: oklch(0.16 0.018 var(--base-h) / 0.15);

  --color-border: oklch(0 0 0 / 0.08);
  --color-border-emphasis: oklch(0 0 0 / 0.15);
  --color-border-strong: oklch(0 0 0 / 0.25);

  --color-success: oklch(0.52 0.17 145);
  --color-warning: oklch(0.60 0.16 85);
  --color-danger: oklch(0.52 0.19 25);
  --color-info: oklch(0.52 0.14 230);
  --color-success-subtle: oklch(0.94 0.04 145);
  --color-warning-subtle: oklch(0.95 0.04 85);
  --color-danger-subtle: oklch(0.94 0.04 25);
  --color-info-subtle: oklch(0.94 0.04 230);

  --shadow-sm: 0 1px 3px oklch(0 0 0 / 0.06);
  --shadow-md: 0 4px 12px oklch(0 0 0 / 0.08);
  --shadow-lg: 0 12px 32px oklch(0 0 0 / 0.12);

  --green: #2D8E52;
  --blue: #3B78D0;
  --red: #D04F3D;
  --amber: #A88520;
  --purple: #9B55B5;
  --cyan: #2A96A0;
  --yellow: #B8A620;
  --orange: #B87620;

  /* Type badge palette - light mode */
  --color-type-dashboard: #2563eb;
  --color-type-chatbot: #7c3aed;
  --color-type-gallery: #d97706;
  --color-type-xlsx: #16a34a;
  --color-type-seatmap: #0d9488;
  --color-type-report: #64748b;
  --color-type-app: #ea580c;
  --color-type-research: #0891b2;

  /* Compatibility aliases */
  --bg: var(--color-bg);
  --surface: var(--color-surface);
  --surface2: var(--color-surface-hover);
  --surface3: var(--color-surface-raised);
  --surface-hover: var(--color-surface-hover);
  --text: var(--color-text);
  --text-dim: var(--color-text-secondary);
  --text-muted: var(--color-text-muted);
  --text-secondary: var(--color-text-secondary);
  --text-disabled: var(--color-text-disabled);
  --accent: var(--color-accent);
  --accent2: var(--color-secondary);
  --secondary: var(--color-secondary);
  --border: var(--color-border);
  --border-emphasis: var(--color-border-emphasis);
}
