/* ============================================================================
   NIMBUS DESIGN TOKENS  -  canonical source of truth
   ----------------------------------------------------------------------------
   This file is the ONE place colors, type, radii, shadows and motion are
   defined. It is copied verbatim to:
       website/css/tokens.css
       app/renderer/css/tokens.css
   Run `npm run sync:tokens` from /server (or `node scripts/sync-tokens.js`)
   after editing. Never edit the copies.

   SYSTEM RULES (see AGENTS.md section "Design contract"):
     - ONE accent: --brand. No second accent color anywhere.
     - Radius rule: buttons + chips = pill, cards = --r-lg, inputs = --r-md.
     - Shadows are tinted with the sky hue. No pure-black shadows.
     - No pure #000 / #fff as surfaces.
   ========================================================================== */

:root {
  color-scheme: light dark;

  /* --- Brand: one cobalt accent, used identically on site and in app ------ */
  --brand-50:  #eef2ff;
  --brand-100: #dfe7ff;
  --brand-200: #c4d2ff;
  --brand-300: #9db4ff;
  --brand-400: #6d8bfa;
  --brand:     #3d63f5;   /* primary: "Zenith", a sky blue with a periwinkle lean */
  --brand-600: #2c4fd6;
  --brand-700: #223fb0;
  --brand-800: #1c3189;
  --brand-900: #162568;

  /* --- Sky: used for the hero atmosphere + app ambient wash -------------- */
  --sky-top:   #3f7fe0;
  --sky-mid:   #6aa6ef;
  --sky-low:   #a9cdf7;
  --sky-haze:  #e4f0fd;

  /* --- Semantic (status only, never decorative) ------------------------- */
  --ok:    #1f9d6b;
  --warn:  #c4841a;
  --err:   #d04545;
  --info:  var(--brand);

  /* --- Neutrals: cool-tinted to match the cool accent. One family only. -- */
  /* Cloudscape surfaces. --cloud is the primary surface, --cloud-2 a nested
     one, --cloud-3 an input or inner tile. The older --surface names are KEPT
     as aliases, so every stylesheet that already says var(--surface) follows
     the new palette without being edited. */
  --canvas:      #f4f8ff;
  --cloud:       #ffffff;
  --cloud-2:     #f3f6ff;
  --cloud-3:     #e7edfd;
  --surface:     var(--cloud);
  --surface-2:   var(--cloud-2);
  --surface-3:   var(--cloud-3);
  --hairline:    #dde5f7;
  --hairline-soft:#e8eefb;
  --ink:         #101a3a;
  --body:        #3f4b70;
  /* Measured against every light surface, --cloud-3 and the frosted glass over
     the sky included. See scripts/contrast-check.js. */
  --muted:       #5a6689;
  --on-brand:    #ffffff;
  /* Text on a --warn or --err fill.

     `--on-brand` covers --err, because --err tracks --brand's lightness in
     both themes: white on the light-mode red measures 4.55:1 and the dark
     ink on the lifted dark-mode red measures 6.32:1.

     --warn does NOT track it. The light-mode amber is bright enough that
     white reaches only 3.15:1, so it needs dark ink in BOTH themes: 5.80:1
     on the light amber and 8.44:1 on the dark one. Hence a token of its own
     rather than another use of --on-brand.

     This existed as a literal `#ffffff` in app.css, which failed AA on three
     of the four surfaces it could land on. */
  --on-warn:     #07142e;

  /* "Achieved" is a status, so the sun is --warn under another name: the streak
     flame and a met daily goal. It is NOT a second accent. */
  --sun:         var(--warn);

  /* THE ACCENT, AS SMALL TEXT.
     --brand is the fill colour: white on it measures 4.82:1, so buttons are
     fine. As *text* on a light surface it is the same 4.82:1 against white
     but only 4.24:1 against --surface-2, so links and captions in the accent
     fail AA on half the surfaces in the app.

     This is not a second accent (AGENTS.md section 4, rule 1). It is the 600
     step of the one accent that already exists, reserved for accent-coloured
     text below ~18px. Large accent numerals and decorative icons keep
     --brand, because 3:1 is the bar at that size and they clear it. */
  --brand-text:  var(--brand-600);

  /* --- Glass (the signature material, light mode) ----------------------- */
  --glass-bg:     rgba(255, 255, 255, 0.58);
  --glass-bg-2:   rgba(255, 255, 255, 0.78);
  --glass-stroke: rgba(255, 255, 255, 0.70);
  --glass-inner:  rgba(255, 255, 255, 0.90);
  --glass-blur:   22px;

  /* --- Type ------------------------------------------------------------- */
  --font-sans: "Outfit", ui-sans-serif, -apple-system,
               BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  --font-mono: "Geist Mono", ui-monospace, "SF Mono", "JetBrains Mono",
               Menlo, monospace;

  --t-display-xl: 700 clamp(2.5rem, 5vw, 4.25rem)/1.05 var(--font-sans);
  --t-display-lg: 700 clamp(2.3rem, 4.2vw, 3.5rem)/1.07 var(--font-sans);
  --t-display-md: 650 clamp(1.7rem, 2.6vw, 2.35rem)/1.14 var(--font-sans);
  --t-title-lg:   600 1.25rem/1.3  var(--font-sans);
  --t-title-md:   600 1.0625rem/1.35 var(--font-sans);
  --t-title-sm:   600 0.9375rem/1.4 var(--font-sans);
  --t-body:       400 1rem/1.6     var(--font-sans);
  --t-body-sm:    400 0.875rem/1.55 var(--font-sans);
  --t-label:      550 0.8125rem/1.3 var(--font-sans);
  --t-caption:    450 0.75rem/1.4  var(--font-sans);

  --tracking-display: -0.025em;
  --tracking-tight:   -0.012em;

  /* --- Radius: the locked scale ----------------------------------------- */
  --r-xs:  6px;
  --r-sm:  9px;
  --r-md:  16px;   /* inputs, inner tiles */
  --r-lg:  24px;   /* cards, panels */
  --r-xl:  32px;   /* the shell, big floating surfaces */
  --r-pill: 999px; /* every button and chip */

  /* --- Elevation: sky-tinted, never black ------------------------------- */
  --e-1: 0 1px 2px rgba(17, 42, 94, 0.05),
         0 1px 1px rgba(17, 42, 94, 0.04);
  --e-2: 0 2px 6px rgba(17, 42, 94, 0.06),
         0 8px 18px -10px rgba(17, 42, 94, 0.14);
  --e-3: 0 4px 12px rgba(17, 42, 94, 0.07),
         0 22px 44px -22px rgba(17, 42, 94, 0.26);
  --e-4: 0 8px 24px rgba(17, 42, 94, 0.09),
         0 48px 90px -40px rgba(17, 42, 94, 0.38);
  --ring: 0 0 0 3px rgba(61, 99, 245, 0.30);

  /* --- Spacing + layout -------------------------------------------------- */
  --s-1: 4px;  --s-2: 8px;  --s-3: 12px; --s-4: 16px; --s-5: 20px;
  --s-6: 24px; --s-7: 32px; --s-8: 40px; --s-9: 56px; --s-10: 72px;
  --s-11: 96px; --s-12: 128px;
  --page-max: 1240px;
  --gutter: clamp(20px, 4vw, 48px);

  /* --- Motion ------------------------------------------------------------ */
  --ease-out: cubic-bezier(0.16, 1, 0.3, 1);
  --ease-in-out: cubic-bezier(0.65, 0, 0.35, 1);
  --d-fast: 140ms;
  --d-base: 260ms;
  --d-slow: 620ms;

  /* --- Layering: the documented z scale. Never invent values. ------------ */
  --z-base: 0;
  --z-sticky: 100;
  --z-dropdown: 200;
  --z-overlay: 300;
  --z-modal: 400;
  --z-toast: 500;
}

/* ---------------------------------------------------------------------------
   DARK MODE  -  page-level lock. The site and the app each flip as a whole;
   individual sections never invert. Brand is LIFTED rather than desaturated so
   the accent keeps AA contrast on dark surfaces and stays recognisably Nimbus.
   Three states are handled: no attribute = follow the OS, [data-theme="dark"]
   = explicit dark, [data-theme="light"] = explicit light wins over the OS.
   ------------------------------------------------------------------------ */

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --brand-50:  #151f4a;
    --brand-100: #1b2860;
    --brand-200: #263a8a;
    --brand-300: #3351b8;
    --brand-400: #5878e6;
    --brand:     #8ab0ff;
    --brand-600: #a3c1ff;
    --brand-700: #bfd4ff;
    
    --sky-top:   #0f2347;
    --sky-mid:   #17355f;
    --sky-low:   #1e4575;
    --sky-haze:  #122744;
    
    --ok:   #3cc08a;
    --warn: #e0a63c;
    --err:  #f58888;
    
    --canvas:       #0e1538;
    --cloud:        #1a2350;
    --cloud-2:      #212b5e;
    --cloud-3:      #2a356c;
    --hairline:     #2c3768;
    --hairline-soft:#232d5a;
    --ink:          #eef2ff;
    --body:         #b6c1e6;
    --muted:        #a1addb;
    --on-brand:     #07142e;
    --on-warn:      #07142e;

    /* Dark mode lifts the brand rather than desaturating it (rule 6), and the
       lifted value already measures 5.80:1 against the worst dark surface. No
       separate text step is needed, so the accent stays one colour here. */
    --brand-text:   var(--brand);

    --glass-bg:     rgba(20, 31, 51, 0.60);
    --glass-bg-2:   rgba(24, 37, 60, 0.82);
    --glass-stroke: rgba(150, 180, 230, 0.16);
    --glass-inner:  rgba(190, 215, 255, 0.10);

    --e-1: 0 1px 2px rgba(0, 0, 0, 0.40);
    --e-2: 0 2px 6px rgba(0, 0, 0, 0.42), 0 8px 18px -10px rgba(0, 0, 0, 0.55);
    --e-3: 0 4px 12px rgba(0, 0, 0, 0.45), 0 22px 44px -22px rgba(0, 0, 0, 0.70);
    --e-4: 0 8px 24px rgba(0, 0, 0, 0.50), 0 48px 90px -40px rgba(0, 0, 0, 0.80);
    --ring: 0 0 0 3px rgba(138, 176, 255, 0.40);
  }
}

:root[data-theme="dark"] {
    --brand-50:  #151f4a;
    --brand-100: #1b2860;
    --brand-200: #263a8a;
    --brand-300: #3351b8;
    --brand-400: #5878e6;
    --brand:     #8ab0ff;
    --brand-600: #a3c1ff;
    --brand-700: #bfd4ff;
    
    --sky-top:   #0f2347;
    --sky-mid:   #17355f;
    --sky-low:   #1e4575;
    --sky-haze:  #122744;
    
    --ok:   #3cc08a;
    --warn: #e0a63c;
    --err:  #f58888;
    
    --canvas:       #0e1538;
    --cloud:        #1a2350;
    --cloud-2:      #212b5e;
    --cloud-3:      #2a356c;
    --hairline:     #2c3768;
    --hairline-soft:#232d5a;
    --ink:          #eef2ff;
    --body:         #b6c1e6;
    --muted:        #a1addb;
    --on-brand:     #07142e;
    --on-warn:      #07142e;

    /* Dark mode lifts the brand rather than desaturating it (rule 6), and the
       lifted value already measures 5.80:1 against the worst dark surface. No
       separate text step is needed, so the accent stays one colour here. */
    --brand-text:   var(--brand);

    --glass-bg:     rgba(20, 31, 51, 0.60);
    --glass-bg-2:   rgba(24, 37, 60, 0.82);
    --glass-stroke: rgba(150, 180, 230, 0.16);
    --glass-inner:  rgba(190, 215, 255, 0.10);

    --e-1: 0 1px 2px rgba(0, 0, 0, 0.40);
    --e-2: 0 2px 6px rgba(0, 0, 0, 0.42), 0 8px 18px -10px rgba(0, 0, 0, 0.55);
    --e-3: 0 4px 12px rgba(0, 0, 0, 0.45), 0 22px 44px -22px rgba(0, 0, 0, 0.70);
    --e-4: 0 8px 24px rgba(0, 0, 0, 0.50), 0 48px 90px -40px rgba(0, 0, 0, 0.80);
    --ring: 0 0 0 3px rgba(138, 176, 255, 0.40);
}

/* Reduced transparency: glass collapses to a solid tinted fill. */
@media (prefers-reduced-transparency: reduce) {
  :root {
    --glass-bg: var(--surface);
    --glass-bg-2: var(--surface);
    --glass-blur: 0px;
  }
}

/* Reduced motion: every duration collapses. Components also guard
   individually, this is the global safety net. */
@media (prefers-reduced-motion: reduce) {
  :root { --d-fast: 1ms; --d-base: 1ms; --d-slow: 1ms; }
  *, *::before, *::after {
    animation-duration: 1ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 1ms !important;
    scroll-behavior: auto !important;
  }
}
