/* ============================================================================
   TechSyntax design tokens
   ----------------------------------------------------------------------------
   The single source of truth for colour, type, spacing, radius, elevation and
   motion. Loaded BEFORE styles.min.css so the legacy sheet can still win where
   it has not been migrated yet, and so every new component in modern.css can be
   written against tokens instead of literals.

   Dark mode resolves in three states, deliberately in this order:
     1. :root                                   -> light palette (the default)
     2. prefers-color-scheme: dark, un-forced   -> dark palette
     3. [data-theme="dark"]                     -> dark palette, explicit choice
   The existing head script stamps data-theme="dark" before first paint, so
   there is no flash; the media query keeps the page correct if that script is
   ever blocked.
   ========================================================================== */

:root {
    color-scheme: light;

    /* ---- Brand ----------------------------------------------------------
       Indigo is the established TechSyntax accent; the scale below is the
       same hue expressed as usable steps rather than five unrelated literals. */
    --ts-brand-50:  #eef2ff;
    --ts-brand-100: #e0e7ff;
    --ts-brand-200: #c7d2fe;
    --ts-brand-300: #a5b4fc;
    --ts-brand-400: #818cf8;
    --ts-brand-500: #6366f1;
    --ts-brand-600: #4f46e5;
    --ts-brand-700: #4338ca;
    --ts-brand-800: #3730a3;
    --ts-brand-900: #312e81;

    /* ---- Neutrals ---- */
    --ts-neutral-0:   #ffffff;
    --ts-neutral-25:  #fcfcfd;
    --ts-neutral-50:  #f8fafc;
    --ts-neutral-100: #f1f5f9;
    --ts-neutral-200: #e2e8f0;
    --ts-neutral-300: #cbd5e1;
    --ts-neutral-400: #94a3b8;
    --ts-neutral-500: #64748b;
    --ts-neutral-600: #475569;
    --ts-neutral-700: #334155;
    --ts-neutral-800: #1e293b;
    --ts-neutral-900: #0f172a;
    --ts-neutral-950: #020617;

    /* ---- Status ---- */
    --ts-success: #047857;
    --ts-warning: #b45309;
    --ts-danger:  #b91c1c;
    --ts-info:    #0369a1;

    /* ---- Semantic surfaces ---------------------------------------------
       Components reference these, never the raw scales above, so the dark
       palette is a re-point of ~25 variables instead of 212 overrides. */
    --ts-bg:            var(--ts-neutral-50);
    --ts-bg-raised:     var(--ts-neutral-0);
    --ts-bg-sunken:     var(--ts-neutral-100);
    --ts-bg-inset:      var(--ts-neutral-100);
    --ts-bg-hover:      var(--ts-neutral-100);
    --ts-bg-header:     rgba(248, 250, 252, .88);
    --ts-bg-overlay:    rgba(15, 23, 42, .45);

    --ts-text:          var(--ts-neutral-800);
    --ts-text-strong:   var(--ts-neutral-900);
    /* Slate-500 (#64748b) lands at 4.34:1 on the sunken surface, just under
       AA. This is the same hue two steps darker so muted text passes on every
       surface the theme uses. */
    --ts-text-muted:    #5c6b80;
    --ts-text-subtle:   var(--ts-neutral-400);
    --ts-text-invert:   var(--ts-neutral-0);

    --ts-border:        var(--ts-neutral-200);
    --ts-border-strong: var(--ts-neutral-300);
    --ts-border-subtle: rgba(15, 23, 42, .07);

    --ts-accent:        var(--ts-brand-600);
    --ts-accent-hover:  var(--ts-brand-700);
    --ts-accent-soft:   var(--ts-brand-50);
    --ts-accent-text:   var(--ts-brand-700);
    --ts-accent-on:     #ffffff;

    --ts-focus:         var(--ts-brand-600);
    --ts-focus-ring:    0 0 0 2px var(--ts-bg), 0 0 0 4px var(--ts-focus);

    /* Code surfaces stay dark in both themes: a code block that inverts with
       the page makes the same snippet look like two different languages. */
    --ts-code-bg:       #0f172a;
    --ts-code-text:     #e2e8f0;
    --ts-code-border:   rgba(148, 163, 184, .22);
    --ts-code-inline-bg:   var(--ts-neutral-100);
    --ts-code-inline-text: var(--ts-brand-800);

    /* ---- Typography -----------------------------------------------------
       Inter carries body and UI (it is already loaded for the wordmark);
       Montserrat is demoted to display only, where its tight, heavy cut is an
       asset rather than a readability tax on 2,000-word articles. */
    --ts-font-sans: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
    --ts-font-display: "Montserrat", var(--ts-font-sans);
    /* System monospace only: a third webfont would cost a round trip and a
       layout shift on the page that most needs to paint fast. */
    --ts-font-mono: ui-monospace, "SFMono-Regular", "SF Mono", Menlo, Consolas, "Liberation Mono", monospace;

    /* Type scale. Fluid where the jump between phone and desktop is large
       enough to matter, fixed elsewhere so rhythm stays predictable. */
    --ts-text-display:  clamp(2rem, 1.35rem + 2.6vw, 3.25rem);
    --ts-text-h1:       clamp(1.75rem, 1.3rem + 1.9vw, 2.5rem);
    --ts-text-h2:       clamp(1.375rem, 1.18rem + .82vw, 1.75rem);
    --ts-text-h3:       clamp(1.125rem, 1.04rem + .36vw, 1.3125rem);
    --ts-text-h4:       1.0625rem;
    --ts-text-body-lg:  1.0625rem;
    --ts-text-body:     1rem;
    --ts-text-sm:       .9375rem;
    --ts-text-meta:     .8125rem;
    --ts-text-label:    .75rem;
    --ts-text-code:     .875rem;

    --ts-leading-tight: 1.15;
    --ts-leading-snug:  1.3;
    --ts-leading-body:  1.7;
    --ts-leading-loose: 1.75;

    --ts-tracking-tight: -.022em;
    --ts-tracking-label: .07em;

    --ts-weight-normal: 400;
    --ts-weight-medium: 500;
    --ts-weight-semi:   600;
    --ts-weight-bold:   700;
    --ts-weight-black:  800;

    /* Comfortable measure for long-form technical prose. */
    --ts-measure: 68ch;

    /* ---- Spacing (4px base) ---- */
    --ts-space-1:  .25rem;
    --ts-space-2:  .5rem;
    --ts-space-3:  .75rem;
    --ts-space-4:  1rem;
    --ts-space-5:  1.25rem;
    --ts-space-6:  1.5rem;
    --ts-space-8:  2rem;
    --ts-space-10: 2.5rem;
    --ts-space-12: 3rem;
    --ts-space-16: 4rem;
    --ts-space-20: 5rem;

    /* Vertical rhythm between homepage/section blocks. */
    --ts-section-gap: clamp(2.5rem, 1.6rem + 3.6vw, 4.5rem);
    --ts-gutter: clamp(1rem, .55rem + 1.8vw, 1.5rem);

    /* ---- Radius ---- */
    --ts-radius-xs: 3px;
    --ts-radius-sm: 5px;
    --ts-radius-md: 8px;
    --ts-radius-lg: 12px;
    --ts-radius-pill: 999px;

    /* ---- Elevation ---- */
    --ts-shadow-xs: 0 1px 2px rgba(15, 23, 42, .05);
    --ts-shadow-sm: 0 1px 3px rgba(15, 23, 42, .07), 0 1px 2px rgba(15, 23, 42, .04);
    --ts-shadow-md: 0 4px 12px rgba(15, 23, 42, .08);
    --ts-shadow-lg: 0 12px 32px rgba(15, 23, 42, .12);

    /* ---- Motion ---- */
    --ts-ease: cubic-bezier(.2, 0, .13, 1);
    --ts-dur-fast: 120ms;
    --ts-dur: 180ms;
    --ts-dur-slow: 280ms;

    /* ---- Layout ---- */
    --ts-header-h: 3.75rem;
    --ts-container: 78rem;
    --ts-z-header: 100;
    --ts-z-drawer: 10001;
    --ts-z-overlay: 10000;
    --ts-z-modal: 10010;
    --ts-z-cookie: 10020;

    /* Smallest comfortable touch target (WCAG 2.2 target size, minimum). */
    --ts-tap: 2.75rem;
}

/* ---- Dark palette -------------------------------------------------------
   Applied for an explicit dark choice, and for system-dark when the visitor
   has not forced light. Both selectors point at one shared block below. */
:root[data-theme="dark"] {
    color-scheme: dark;

    --ts-bg:            var(--ts-neutral-950);
    --ts-bg-raised:     #0b1220;
    --ts-bg-sunken:     #080e1a;
    --ts-bg-inset:      #111c30;
    --ts-bg-hover:      #16233a;
    --ts-bg-header:     rgba(2, 6, 23, .85);
    --ts-bg-overlay:    rgba(2, 6, 23, .7);

    --ts-text:          #d7dfeb;
    --ts-text-strong:   #f1f5f9;
    --ts-text-muted:    #94a3b8;
    --ts-text-subtle:   #64748b;
    --ts-text-invert:   var(--ts-neutral-900);

    --ts-border:        #1e2c44;
    --ts-border-strong: #2b3d5c;
    --ts-border-subtle: rgba(226, 232, 240, .08);

    --ts-accent:        var(--ts-brand-400);
    --ts-accent-hover:  var(--ts-brand-300);
    --ts-accent-soft:   rgba(99, 102, 241, .16);
    --ts-accent-text:   var(--ts-brand-300);
    --ts-accent-on:     #0b1020;

    --ts-focus:         var(--ts-brand-300);

    --ts-success: #34d399;
    --ts-warning: #fbbf24;
    --ts-danger:  #f87171;
    --ts-info:    #38bdf8;

    --ts-code-bg:       #0b1220;
    --ts-code-border:   rgba(148, 163, 184, .18);
    --ts-code-inline-bg:   rgba(129, 140, 248, .14);
    --ts-code-inline-text: #c7d2fe;

    --ts-shadow-xs: 0 1px 2px rgba(0, 0, 0, .4);
    --ts-shadow-sm: 0 1px 3px rgba(0, 0, 0, .45);
    --ts-shadow-md: 0 4px 14px rgba(0, 0, 0, .5);
    --ts-shadow-lg: 0 14px 36px rgba(0, 0, 0, .55);
}

@media (prefers-color-scheme: dark) {
    :root:not([data-theme="light"]) {
        color-scheme: dark;

        --ts-bg:            var(--ts-neutral-950);
        --ts-bg-raised:     #0b1220;
        --ts-bg-sunken:     #080e1a;
        --ts-bg-inset:      #111c30;
        --ts-bg-hover:      #16233a;
        --ts-bg-header:     rgba(2, 6, 23, .85);
        --ts-bg-overlay:    rgba(2, 6, 23, .7);

        --ts-text:          #d7dfeb;
        --ts-text-strong:   #f1f5f9;
        --ts-text-muted:    #94a3b8;
        --ts-text-subtle:   #64748b;
        --ts-text-invert:   var(--ts-neutral-900);

        --ts-border:        #1e2c44;
        --ts-border-strong: #2b3d5c;
        --ts-border-subtle: rgba(226, 232, 240, .08);

        --ts-accent:        var(--ts-brand-400);
        --ts-accent-hover:  var(--ts-brand-300);
        --ts-accent-soft:   rgba(99, 102, 241, .16);
        --ts-accent-text:   var(--ts-brand-300);
        --ts-accent-on:     #0b1020;

        --ts-focus:         var(--ts-brand-300);

        --ts-success: #34d399;
        --ts-warning: #fbbf24;
        --ts-danger:  #f87171;
        --ts-info:    #38bdf8;

        --ts-code-bg:       #0b1220;
        --ts-code-border:   rgba(148, 163, 184, .18);
        --ts-code-inline-bg:   rgba(129, 140, 248, .14);
        --ts-code-inline-text: #c7d2fe;

        --ts-shadow-xs: 0 1px 2px rgba(0, 0, 0, .4);
        --ts-shadow-sm: 0 1px 3px rgba(0, 0, 0, .45);
        --ts-shadow-md: 0 4px 14px rgba(0, 0, 0, .5);
        --ts-shadow-lg: 0 14px 36px rgba(0, 0, 0, .55);
    }
}

/* Motion is opt-out at the token level, so every component that animates via
   --ts-dur* stops animating without needing its own media query. */
@media (prefers-reduced-motion: reduce) {
    :root {
        --ts-dur-fast: 1ms;
        --ts-dur: 1ms;
        --ts-dur-slow: 1ms;
    }

    *, *::before, *::after {
        animation-duration: 1ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 1ms !important;
        scroll-behavior: auto !important;
    }
}
