/* ==========================================================================
   Strict Web Design: token set
   Copy this file into the project first, before any markup.
   Adjust the accent hue and the font stack. Do not adjust the scales.
   Components reference SEMANTIC tokens only, never primitives.
   ========================================================================== */

:root {
  /* ---------------------------------------------------------------------
     PRIMITIVES. Raw values with no meaning attached.
     Never reference these directly from a component.
     --------------------------------------------------------------------- */

  /* Neutrals. A 10-step ramp is enough for any interface. */
  --gray-0:   #ffffff;
  --gray-50:  #f8f9fa;
  --gray-100: #f1f3f5;
  --gray-200: #e9ecef;
  --gray-300: #dee2e6;
  --gray-400: #ced4da;
  --gray-500: #adb5bd;
  --gray-600: #868e96;
  --gray-650: #6c757d;
  --gray-700: #495057;
  --gray-800: #343a40;
  --gray-900: #212529;
  --gray-950: #121212; /* near-black. Never use #000 as a surface. */

  /* Accent. One hue. Muted, not neon.
     Swap this ramp for the project's brand hue and recheck contrast.
     The -600 step is the light-mode action color (4.5:1+ on white).
     The -400 step is the dark-mode action color. */
  --accent-100: #dbeafe;
  --accent-200: #bfdbfe;
  --accent-400: #60a5fa;
  --accent-500: #3b82f6;
  --accent-600: #2563eb;
  --accent-700: #1d4ed8;

  /* Status hues. Muted. Each needs a light and a dark variant. */
  --red-100:   #fee2e2;
  --red-400:   #f87171;
  --red-600:   #dc2626;
  --red-700:   #b91c1c;
  --amber-100: #fef3c7;
  --amber-400: #fbbf24;
  --amber-700: #b45309;
  --green-100: #dcfce7;
  --green-400: #4ade80;
  --green-700: #15803d;

  /* Spacing. 8-point scale, with 4 for fine alignment.
     8-based because it scales to whole pixels at 1.5x, 2x, and 3x. */
  --space-1:  4px;
  --space-2:  8px;
  --space-3:  12px;
  --space-4:  16px;
  --space-5:  24px;
  --space-6:  32px;
  --space-7:  40px;
  --space-8:  48px;
  --space-9:  64px;
  --space-10: 80px;
  --space-11: 96px;

  /* Radius. Nested shapes stay concentric:
     inner radius = outer radius - padding between them. */
  --radius-xs:   4px;
  --radius-sm:   8px;
  --radius-md:   12px;
  --radius-lg:   16px;
  --radius-full: 9999px; /* avatars, status dots, true chips only */

  /* Type sizes. Every line height is a multiple of 4. */
  --text-xs:   12px;  --leading-xs:   16px;
  --text-sm:   14px;  --leading-sm:   20px;
  --text-base: 16px;  --leading-base: 24px;
  --text-md:   18px;  --leading-md:   28px;
  --text-lg:   20px;  --leading-lg:   28px;
  --text-xl:   24px;  --leading-xl:   32px;
  --text-2xl:  32px;  --leading-2xl:  40px;
  --text-3xl:  40px;  --leading-3xl:  48px;
  --text-4xl:  48px;  --leading-4xl:  56px;

  --weight-regular:  400;
  --weight-medium:   500;
  --weight-semibold: 600;
  --weight-bold:     700;
  /* Light weights are banned. They fail at small sizes and in dark mode. */

  /* Motion. Nothing exceeds 400ms. */
  --duration-instant: 100ms;
  --duration-fast:    150ms;
  --duration-normal:  200ms;
  --duration-slow:    300ms;
  --duration-slowest: 400ms;

  --ease-standard:   cubic-bezier(0.2, 0, 0, 1);
  --ease-decelerate: cubic-bezier(0, 0, 0, 1);    /* entering */
  --ease-accelerate: cubic-bezier(0.3, 0, 1, 1);  /* leaving */
  /* No spring, bounce, or elastic curves. */

  /* Shadow. Two layers, x-offset 0, background-tinted, never pure black.
     Higher elevation means larger and fainter, never darker. */
  --shadow-color: 220 12% 40%;
  --shadow-1:
    0 1px 2px 0 hsl(var(--shadow-color) / 0.10),
    0 1px 3px 1px hsl(var(--shadow-color) / 0.06);
  --shadow-2:
    0 1px 2px 0 hsl(var(--shadow-color) / 0.09),
    0 2px 6px 2px hsl(var(--shadow-color) / 0.05);
  --shadow-3:
    0 1px 3px 0 hsl(var(--shadow-color) / 0.08),
    0 4px 8px 3px hsl(var(--shadow-color) / 0.04);
  /* There is no --shadow-4. Use a tonal surface step instead. */

  --border-width: 1px;
  --focus-ring-width: 2px;
  --focus-ring-offset: 2px;

  --font-sans: -apple-system, BlinkMacSystemFont, "Segoe UI", system-ui,
               sans-serif;
  --font-mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, monospace;

  /* ---------------------------------------------------------------------
     SEMANTIC TOKENS. Meaning attached. Components use only these.
     Redefined wholesale for dark mode below.
     --------------------------------------------------------------------- */

  /* Surfaces. Depth comes from these steps, not from shadow. */
  --color-surface-page:    var(--gray-50);
  --color-surface-raised:  var(--gray-0);
  --color-surface-overlay: var(--gray-0);
  --color-surface-sunken:  var(--gray-100);

  /* Text. A four-step ramp covers almost everything. */
  --color-text-primary:    var(--gray-900); /* 16.1:1 on white */
  --color-text-secondary:  var(--gray-700); /*  8.2:1 */
  --color-text-tertiary:   var(--gray-650); /*  4.7:1. The floor for any
                                                text a user has to read. */
  --color-text-disabled:   var(--gray-500); /*  2.1:1. Exempt under WCAG
                                                1.4.3, and the only token
                                                allowed below 4.5:1. */
  --color-text-on-accent:  var(--gray-0);   /*  5.2:1 on --color-action */

  /* Borders. Two tokens, and the distinction is load-bearing.
     --color-border is a decorative separator (table rows, card edges). It
     divides, it does not identify a control, so it is exempt from 1.4.11.
     --color-border-strong is the boundary of an interactive control and
     MUST clear 3:1, because that border is what makes the control findable.
     Never use --color-border on an input, button, or checkbox.
     Never use either one as a text color. */
  --color-border:        var(--gray-300); /* 1.3:1, decorative only */
  --color-border-strong: var(--gray-600); /* 3.3:1 on white and on the page
                                             surface. Controls use this. */

  /* Action. Reserved for interactive elements. Never decorative. */
  --color-action:          var(--accent-600);
  --color-action-hover:    var(--accent-700);
  --color-action-subtle:   var(--accent-100);
  --color-focus-ring:      var(--accent-600);

  /* Status */
  /* Status. Each is used as TEXT, so each clears 4.5:1 on the page surface.
     The common mistake is reaching for a 500 or 600 weight because it looks
     right as a fill: #d97706 amber is 3.2:1 and #16a34a green is 3.3:1, both
     of which fail as text. Use these darker values for the text and icon,
     and the -subtle token only as the fill behind them. */
  --color-danger:         var(--red-600);   /* 4.8:1 */
  --color-danger-subtle:  var(--red-100);
  --color-danger-on-subtle:  var(--red-700);   /* 5.3:1 on danger-subtle */
  --color-warning:        var(--amber-700); /* 5.0:1 */
  --color-warning-subtle: var(--amber-100);
  --color-warning-on-subtle: var(--amber-700); /* 4.5:1 on warning-subtle */
  --color-success:        var(--green-700); /* 5.0:1 */
  --color-success-subtle: var(--green-100);
  --color-success-on-subtle: var(--green-700); /* 4.6:1 on success-subtle */

  /* State layers. Overlays of the element's own content color.
     Never hand-pick a second hex for hover. */
  --state-hover-opacity:   0.08;
  --state-pressed-opacity: 0.12;
  --state-disabled-container-opacity: 0.12;
  --state-disabled-content-opacity:   0.38;

  /* Composite spacing tokens */
  --space-inset-card:    var(--space-5);
  --space-inset-card-sm: var(--space-4);
  --space-gutter:        var(--space-4);
  --space-gutter-lg:     var(--space-6);
  --space-section:       var(--space-8);
  --space-stack-tight:   var(--space-2);
  --space-stack:         var(--space-4);
  --space-stack-loose:   var(--space-5);

  /* Sizing */
  --size-target-min:  44px; /* touch. 24px is the absolute WCAG floor. */
  --size-control-sm:  32px;
  --size-control-md:  40px;
  --size-control-lg:  48px;
  --measure:          68ch; /* 45 to 75 characters */
}

/* ==========================================================================
   DARK MODE
   Not an inversion. Accents get their own lighter variants, because a hue
   that passes 4.5:1 on white commonly falls to 2.3:1 on a dark surface.
   Surfaces are near-black, never #000, to limit halation.
   ========================================================================== */

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --color-surface-page:    var(--gray-950);
    --color-surface-raised:  #1c1c1e;
    --color-surface-overlay: #252528;
    --color-surface-sunken:  #0d0d0d;

    --color-text-primary:   #e5e7eb; /* 15.1:1. Not pure white, which
                                        blooms (halation) on dark. */
    --color-text-secondary: var(--gray-400); /* 12.5:1 */
    --color-text-tertiary:  var(--gray-500); /*  9.0:1 */
    --color-text-disabled:  var(--gray-600); /*  5.6:1 */
    --color-text-on-accent: var(--gray-950);

    --color-border:        #2e2e32; /* 1.3:1, decorative only */
    --color-border-strong: #6b6b74; /* 3.2:1 on the raised surface */

    --color-action:        var(--accent-400);
    --color-action-hover:  var(--accent-200);
    --color-action-subtle: #1e3a5f;
    --color-focus-ring:    var(--accent-400);

    --color-danger:         var(--red-400);   /* 6.2:1 */
    --color-danger-subtle:  #3f1d1d;
    --color-danger-on-subtle:  var(--red-400);
    --color-warning:        var(--amber-400); /* 10.2:1 */
    --color-warning-subtle: #3d2f0f;
    --color-warning-on-subtle: var(--amber-400);
    --color-success:        var(--green-400); /* 9.8:1 */
    --color-success-subtle: #143024;
    --color-success-on-subtle: var(--green-400);

    --shadow-color: 0 0% 0%;
  }
}

:root[data-theme="dark"] {
  --color-surface-page:    var(--gray-950);
  --color-surface-raised:  #1c1c1e;
  --color-surface-overlay: #252528;
  --color-surface-sunken:  #0d0d0d;
  --color-text-primary:   #e5e7eb;
  --color-text-secondary: var(--gray-400); /* 12.5:1 */
  --color-text-tertiary:  var(--gray-500); /*  9.0:1 */
  --color-text-disabled:  var(--gray-600); /*  5.6:1 */
  --color-text-on-accent: var(--gray-950);
  --color-border:        #2e2e32; /* 1.3:1, decorative only */
  --color-border-strong: #6b6b74; /* 3.2:1 on the raised surface */
  --color-action:        var(--accent-400);
  --color-action-hover:  var(--accent-200);
  --color-action-subtle: #1e3a5f;
  --color-focus-ring:    var(--accent-400);
  --color-danger:         var(--red-400);   /* 6.2:1 */
  --color-danger-subtle:  #3f1d1d;
  --color-danger-on-subtle:  var(--red-400);
  --color-warning:        var(--amber-400); /* 10.2:1 */
  --color-warning-subtle: #3d2f0f;
  --color-warning-on-subtle: var(--amber-400);
  --color-success:        var(--green-400); /* 9.8:1 */
  --color-success-subtle: #143024;
  --color-success-on-subtle: var(--green-400);
  --shadow-color: 0 0% 0%;
}

/* ==========================================================================
   BASE
   ========================================================================== */

*, *::before, *::after { box-sizing: border-box; }

body {
  margin: 0;
  background: var(--color-surface-page);
  color: var(--color-text-primary);
  font-family: var(--font-sans);
  font-size: var(--text-base);
  line-height: var(--leading-base);
  -webkit-font-smoothing: antialiased;
}

/* Focus is never removed. :focus-visible keeps it off mouse clicks. */
:focus-visible {
  outline: var(--focus-ring-width) solid var(--color-focus-ring);
  outline-offset: var(--focus-ring-offset);
}

/* Reduced motion: replace movement with fades, keep the state feedback. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}

/* Running prose is capped so lines stay in the 45 to 75 character range. */
.prose { max-width: var(--measure); }
