/* ==========================================================================
   Spotless Mind — Design tokens
   The single source of truth for colour, type, space, radius, elevation.
   Nothing in this codebase should hardcode a raw value that belongs here.
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. PRIMITIVES — raw ramps. Never used directly in components; the semantic
   layer below maps them to roles so themes can be swapped wholesale.
   -------------------------------------------------------------------------- */
:root {
  /* Brand green — the Spotless Mind hue, from the logo and app icon */
  --green-50:  #EDF6F1;
  --green-100: #D6EBE0;
  --green-200: #AFD8C4;
  --green-300: #7EBFA2;
  --green-400: #4E9F7C;
  --green-500: #1F6B52;   /* light-theme brand: 6.4:1 on --sand-50 */
  --green-600: #175540;
  --green-700: #10402F;
  --green-800: #0B2C21;
  --green-900: #071C15;
  --green-950: #04110C;
  --green-bright: #6FDCB4; /* dark-theme brand: 10.6:1 on --green-950 */

  /* Warm neutral — paper, sand, the light theme's substrate */
  --sand-50:  #FBF8F2;
  --sand-100: #F5F0E6;
  --sand-200: #EBE4D6;
  --sand-300: #DBD2C0;
  --sand-400: #B9AF9C;

  /* Cool-green ink — text and dark surfaces, shares the brand's hue family */
  --ink-900: #16251D;
  --ink-800: #22362B;
  --ink-700: #33453A;
  --ink-600: #4A5B50;
  --ink-500: #5A6B5F;
  --ink-400: #7C8A80;
  --ink-300: #9FB3A6;
  --ink-200: #C7D5CC;
  --ink-100: #E4EDE7;

  /* Accents — each has a TEXT-SAFE value (AA on its theme's page background)
     and a DECORATIVE value used only for fills, gradients and charts. */
  --clay-text-light:  #9A5626;   /* 5.3:1 on sand-50 */
  --clay-text-dark:   #F0B183;
  --clay-deco:        #C87A42;

  --blue-text-light:  #2F5C89;   /* 6.6:1 on sand-50 */
  --blue-text-dark:   #93C2F0;
  --blue-deco:        #5D93C9;

  --rose-text-light:  #9E3F3C;   /* 6.6:1 on sand-50 */
  --rose-text-dark:   #F2A9A2;
  --rose-deco:        #C96F5E;

  --plum-text-light:  #6A4A8C;
  --plum-text-dark:   #C6AEE8;
  --plum-deco:        #8E71B5;
}

/* --------------------------------------------------------------------------
   2. SEMANTIC — LIGHT THEME (default)
   -------------------------------------------------------------------------- */
:root {
  /* Surfaces, back to front */
  --bg:             var(--sand-50);
  --bg-sunk:        var(--sand-100);
  --surface:        #FFFDF9;
  --surface-2:      var(--sand-100);
  --surface-3:      var(--sand-200);
  --surface-inverse: var(--green-800);

  /* Translucent "glass" panels over the ambient background */
  --glass:          rgba(255, 253, 249, .72);
  --glass-strong:   rgba(255, 253, 249, .92);
  --glass-quiet:    rgba(255, 253, 249, .45);

  /* The header sits over the hero artwork, so it needs a denser ground than
     a general-purpose glass panel or the bloom bleeds straight through it. */
  --nav-bg:         rgba(251, 248, 242, .80);
  --nav-bg-stuck:   rgba(251, 248, 242, .95);

  /* Text roles */
  --text:           var(--ink-900);   /* headings, primary */
  --text-body:      var(--ink-700);   /* running prose */
  --text-muted:     var(--ink-500);   /* secondary, meta — still AA */
  --text-faint:     var(--ink-400);   /* decorative only, never load-bearing */
  --text-on-brand:  #FFFDF9;
  --text-inverse:   var(--ink-100);

  /* Brand */
  --brand:          var(--green-500);
  --brand-hover:    var(--green-600);
  --brand-contrast: var(--green-700);
  --brand-tint:     var(--green-50);
  --brand-tint-2:   var(--green-100);
  --brand-ring:     rgba(31, 107, 82, .40);

  /* Accents (text-safe) */
  --accent-warm:    var(--clay-text-light);
  --accent-cool:    var(--blue-text-light);
  --accent-rose:    var(--rose-text-light);
  --accent-plum:    var(--plum-text-light);

  /* Accents (decorative fills / gradients / data viz) */
  --deco-green:     var(--green-400);
  --deco-warm:      var(--clay-deco);
  --deco-cool:      var(--blue-deco);
  --deco-rose:      var(--rose-deco);
  --deco-plum:      var(--plum-deco);

  /* Borders */
  --border-subtle:  rgba(22, 37, 29, .08);
  --border:         rgba(22, 37, 29, .14);
  --border-strong:  rgba(22, 37, 29, .26);
  --border-brand:   rgba(31, 107, 82, .38);

  /* Elevation — warm-tinted shadows read better on sand than neutral black */
  --shadow-1: 0 1px 2px rgba(38, 32, 20, .05);
  --shadow-2: 0 2px 4px rgba(38, 32, 20, .05), 0 4px 10px rgba(38, 32, 20, .05);
  --shadow-3: 0 4px 8px rgba(38, 32, 20, .05), 0 10px 22px rgba(38, 32, 20, .07);
  --shadow-4: 0 8px 16px rgba(38, 32, 20, .06), 0 20px 44px rgba(38, 32, 20, .09);
  --shadow-5: 0 16px 32px rgba(38, 32, 20, .08), 0 36px 80px rgba(38, 32, 20, .12);
  --shadow-brand: 0 8px 26px rgba(31, 107, 82, .22);

  /* Ambient field (hero mesh / aurora) */
  --field-1: #BCE0CB;
  --field-2: #F3D9B6;
  --field-3: #BFD8EE;
  --field-opacity: .55;
  --grain-opacity: .045;

  color-scheme: light;
}

/* --------------------------------------------------------------------------
   3. SEMANTIC — DARK THEME
   Applied when the user's OS prefers dark (unless they chose light explicitly)
   or when they pick dark from the theme control. Written as a real design,
   not an inversion: surfaces get lighter as they come forward, the brand
   shifts to a luminous mint that can carry weight on near-black.
   -------------------------------------------------------------------------- */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) { color-scheme: dark; }
}
:root[data-theme="dark"] { color-scheme: dark; }

/* The dark palette is defined once and referenced by both selectors below. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --bg:             var(--green-950);
    --bg-sunk:        #020B07;
    --surface:        var(--green-900);
    --surface-2:      var(--green-800);
    --surface-3:      #12291F;
    --surface-inverse: var(--sand-100);

    --nav-bg:         rgba(6, 16, 12, .78);
    --nav-bg-stuck:   rgba(6, 16, 12, .94);
    --glass:          rgba(174, 216, 195, .06);
    --glass-strong:   rgba(174, 216, 195, .11);
    --glass-quiet:    rgba(174, 216, 195, .035);

    --text:           #EDF4EF;
    --text-body:      var(--ink-200);
    --text-muted:     var(--ink-300);
    --text-faint:     #7A8E82;
    --text-on-brand:  #04110C;
    --text-inverse:   var(--ink-900);

    --brand:          var(--green-bright);
    --brand-hover:    #8FE9C7;
    --brand-contrast: #A9F0D6;
    --brand-tint:     rgba(111, 220, 180, .10);
    --brand-tint-2:   rgba(111, 220, 180, .18);
    --brand-ring:     rgba(111, 220, 180, .45);

    --accent-warm:    var(--clay-text-dark);
    --accent-cool:    var(--blue-text-dark);
    --accent-rose:    var(--rose-text-dark);
    --accent-plum:    var(--plum-text-dark);

    --deco-green:     var(--green-bright);
    --deco-warm:      var(--clay-text-dark);
    --deco-cool:      var(--blue-text-dark);
    --deco-rose:      var(--rose-text-dark);
    --deco-plum:      var(--plum-text-dark);

    --border-subtle:  rgba(174, 216, 195, .08);
    --border:         rgba(174, 216, 195, .15);
    --border-strong:  rgba(174, 216, 195, .30);
    --border-brand:   rgba(111, 220, 180, .42);

    --shadow-1: 0 1px 2px rgba(0, 0, 0, .40);
    --shadow-2: 0 2px 4px rgba(0, 0, 0, .35), 0 4px 10px rgba(0, 0, 0, .35);
    --shadow-3: 0 4px 8px rgba(0, 0, 0, .35), 0 10px 22px rgba(0, 0, 0, .40);
    --shadow-4: 0 8px 16px rgba(0, 0, 0, .40), 0 20px 44px rgba(0, 0, 0, .45);
    --shadow-5: 0 16px 32px rgba(0, 0, 0, .45), 0 36px 80px rgba(0, 0, 0, .55);
    --shadow-brand: 0 8px 26px rgba(111, 220, 180, .16);

    --field-1: #12463A;
    --field-2: #1C4A52;
    --field-3: #15304F;
    --field-opacity: .42;
    --grain-opacity: .06;
  }
}

:root[data-theme="dark"] {
  --bg:             var(--green-950);
  --bg-sunk:        #020B07;
  --surface:        var(--green-900);
  --surface-2:      var(--green-800);
  --surface-3:      #12291F;
  --surface-inverse: var(--sand-100);

  --nav-bg:         rgba(6, 16, 12, .78);
  --nav-bg-stuck:   rgba(6, 16, 12, .94);
  --glass:          rgba(174, 216, 195, .06);
  --glass-strong:   rgba(174, 216, 195, .11);
  --glass-quiet:    rgba(174, 216, 195, .035);

  --text:           #EDF4EF;
  --text-body:      var(--ink-200);
  --text-muted:     var(--ink-300);
  --text-faint:     #7A8E82;
  --text-on-brand:  #04110C;
  --text-inverse:   var(--ink-900);

  --brand:          var(--green-bright);
  --brand-hover:    #8FE9C7;
  --brand-contrast: #A9F0D6;
  --brand-tint:     rgba(111, 220, 180, .10);
  --brand-tint-2:   rgba(111, 220, 180, .18);
  --brand-ring:     rgba(111, 220, 180, .45);

  --accent-warm:    var(--clay-text-dark);
  --accent-cool:    var(--blue-text-dark);
  --accent-rose:    var(--rose-text-dark);
  --accent-plum:    var(--plum-text-dark);

  --deco-green:     var(--green-bright);
  --deco-warm:      var(--clay-text-dark);
  --deco-cool:      var(--blue-text-dark);
  --deco-rose:      var(--rose-text-dark);
  --deco-plum:      var(--plum-text-dark);

  --border-subtle:  rgba(174, 216, 195, .08);
  --border:         rgba(174, 216, 195, .15);
  --border-strong:  rgba(174, 216, 195, .30);
  --border-brand:   rgba(111, 220, 180, .42);

  --shadow-1: 0 1px 2px rgba(0, 0, 0, .40);
  --shadow-2: 0 2px 4px rgba(0, 0, 0, .35), 0 4px 10px rgba(0, 0, 0, .35);
  --shadow-3: 0 4px 8px rgba(0, 0, 0, .35), 0 10px 22px rgba(0, 0, 0, .40);
  --shadow-4: 0 8px 16px rgba(0, 0, 0, .40), 0 20px 44px rgba(0, 0, 0, .45);
  --shadow-5: 0 16px 32px rgba(0, 0, 0, .45), 0 36px 80px rgba(0, 0, 0, .55);
  --shadow-brand: 0 8px 26px rgba(111, 220, 180, .16);

  --field-1: #12463A;
  --field-2: #1C4A52;
  --field-3: #15304F;
  --field-opacity: .42;
  --grain-opacity: .06;
}

/* --------------------------------------------------------------------------
   4. TYPOGRAPHY
   Newsreader (display serif) carries headings and pull quotes.
   Public Sans (grotesque) carries running text and UI.
   IBM Plex Mono carries eyebrows, labels and data — the "clinical" register.
   -------------------------------------------------------------------------- */
:root {
  --font-display: 'Newsreader', 'Newsreader Fallback', Georgia, 'Times New Roman', serif;
  --font-body:    'Public Sans', 'Public Sans Fallback', system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;
  --font-mono:    'IBM Plex Mono', ui-monospace, 'SF Mono', 'Cascadia Mono', Menlo, monospace;

  /* Fluid type scale — 1.200 minor third at small sizes, widening to 1.250
     at display sizes. Every clamp is viewport-fluid between 360px and 1280px. */
  --text-2xs: 0.6875rem;                                    /* 11px  labels   */
  --text-xs:  0.75rem;                                      /* 12px  meta     */
  --text-sm:  0.8125rem;                                    /* 13px  captions */
  --text-base: clamp(0.9375rem, 0.90rem + 0.16vw, 1rem);    /* 15→16 UI       */
  --text-md:  clamp(1rem, 0.96rem + 0.19vw, 1.0625rem);     /* 16→17 prose    */
  --text-lg:  clamp(1.0625rem, 1.00rem + 0.28vw, 1.1875rem);/* 17→19 lead     */
  --text-xl:  clamp(1.1875rem, 1.10rem + 0.39vw, 1.375rem); /* 19→22 h4       */
  --text-2xl: clamp(1.3125rem, 1.18rem + 0.58vw, 1.625rem); /* 21→26 h3       */
  --text-3xl: clamp(1.5rem, 1.28rem + 0.98vw, 2.125rem);    /* 24→34 h2       */
  --text-4xl: clamp(1.875rem, 1.48rem + 1.76vw, 2.875rem);  /* 30→46 h1       */
  --text-5xl: clamp(2.25rem, 1.61rem + 2.83vw, 3.75rem);    /* 36→60 hero     */

  /* Line heights — tight for display, open for prose */
  --leading-none:  1;
  --leading-tight: 1.12;
  --leading-snug:  1.28;
  --leading-normal:1.5;
  --leading-prose: 1.68;
  --leading-loose: 1.78;

  /* Letter spacing — negative tracking on large serif, positive on small caps */
  --tracking-tighter: -0.028em;
  --tracking-tight:   -0.018em;
  --tracking-normal:  0;
  --tracking-wide:    0.04em;
  --tracking-wider:   0.12em;
  --tracking-widest:  0.20em;

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

  /* Measure — the readable line length for body copy */
  --measure:        65ch;
  --measure-narrow: 50ch;
  --measure-wide:   78ch;
}

/* --------------------------------------------------------------------------
   5. SPACE — 4px base, geometric-ish so steps stay distinguishable
   -------------------------------------------------------------------------- */
:root {
  --space-0:  0;
  --space-1:  0.25rem;   /*  4 */
  --space-2:  0.5rem;    /*  8 */
  --space-3:  0.75rem;   /* 12 */
  --space-4:  1rem;      /* 16 */
  --space-5:  1.5rem;    /* 24 */
  --space-6:  2rem;      /* 32 */
  --space-7:  2.5rem;    /* 40 */
  --space-8:  3rem;      /* 48 */
  --space-9:  4rem;      /* 64 */
  --space-10: 5rem;      /* 80 */
  --space-11: 6.5rem;    /* 104 */
  --space-12: 8rem;      /* 128 */

  /* Fluid rhythm between major page sections */
  --section-gap: clamp(3.5rem, 2.6rem + 4vw, 6.5rem);
  --block-gap:   clamp(1.75rem, 1.4rem + 1.6vw, 2.75rem);

  /* Page shell */
  --page-max:    75rem;    /* 1200px */
  --page-gutter: clamp(1.25rem, 0.9rem + 1.6vw, 2.5rem);
  --nav-height:  4rem;
}

/* --------------------------------------------------------------------------
   6. RADIUS
   -------------------------------------------------------------------------- */
:root {
  --radius-xs:   0.375rem;
  --radius-sm:   0.625rem;
  --radius-md:   0.875rem;
  --radius-lg:   1.125rem;
  --radius-xl:   1.5rem;
  --radius-2xl:  2rem;
  --radius-full: 999px;
}

/* --------------------------------------------------------------------------
   7. MOTION
   Durations stay in the 150–400ms band. Easings are named by intent so a
   component asks for "entrance" rather than guessing a cubic-bezier.
   -------------------------------------------------------------------------- */
:root {
  --dur-instant: 90ms;
  --dur-fast:    160ms;
  --dur-base:    240ms;
  --dur-slow:    320ms;
  --dur-slower:  400ms;

  --ease-out:      cubic-bezier(.22, .90, .30, 1);
  --ease-in-out:   cubic-bezier(.62, .02, .34, 1);
  --ease-entrance: cubic-bezier(.16, .84, .32, 1);
  --ease-spring:   cubic-bezier(.34, 1.42, .56, 1);

  --reveal-shift: 18px;
}

/* Under reduced-motion every duration collapses, so components that read these
   tokens are disabled without needing their own media query. */
@media (prefers-reduced-motion: reduce) {
  :root {
    --dur-instant: 1ms;
    --dur-fast:    1ms;
    --dur-base:    1ms;
    --dur-slow:    1ms;
    --dur-slower:  1ms;
    --reveal-shift: 0px;
  }
}

/* --------------------------------------------------------------------------
   8. ICON MASKS — for the few places a pseudo-element needs an icon shape
   -------------------------------------------------------------------------- */
:root {
  --icon-check: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M4.5 12.5 9.5 17.5 19.5 7'/%3E%3C/svg%3E");
}

/* --------------------------------------------------------------------------
   9. LAYERS — one place to reason about what sits above what
   -------------------------------------------------------------------------- */
:root {
  --z-field:    -4;
  --z-aurora:   -3;
  --z-particle: -2;
  --z-grain:    -1;
  --z-base:      0;
  --z-raised:    10;
  --z-nav:       100;
  --z-menu:      200;
  --z-modal:     300;
  --z-reader:    400;
  --z-toast:     500;
  --z-skip:      600;
}
