@layer tokens {
/* =============================================================================
   @elements/style — default theme

   Ships with the toolkit. Every Elements app gets this.

   - Single neutral ramp (navy-tinted, perceptually uniform OKLCH).
   - 4 status ramps (success, warning, danger, info) on a matched lightness curve.
   - --accent defaults to neutral-900 → apps are MONOCHROME until customized.

   To brand an app: override --accent (and optionally --accent-deep, --accent-soft,
   --accent-ink) in a theme file imported after this one. themes/elements.css is
   the canonical example; themes/customer-example.css documents the recipe.

   Dark mode: follows the OS preference by default. Set data-theme="dark" or
   data-theme="light" on <html> to force a mode (e.g. from a user toggle) —
   the attribute always wins over the OS preference. The dark token set
   appears twice below (media query + attribute); keep the two blocks
   identical.
============================================================================= */

:root {

  color-scheme: light;

  /* PALETTE — achromatic ---------------------------------------------- */

  --white:        #ffffff;
  --black:        #000000;

  /* PALETTE — neutral
     Cool navy-tinted gray. Hue 240, low chroma. neutral-900 is the Elements
     navy (#102C42) exactly. ------------------------------------------------- */

  --neutral-50:   oklch(0.985 0.005 240);
  --neutral-100:  oklch(0.96  0.008 240);
  --neutral-200:  oklch(0.92  0.012 240);
  --neutral-300:  oklch(0.86  0.016 240);
  --neutral-400:  oklch(0.74  0.020 240);
  --neutral-500:  oklch(0.62  0.024 240);
  --neutral-600:  oklch(0.50  0.028 240);
  --neutral-700:  oklch(0.38  0.032 240);
  --neutral-800:  oklch(0.28  0.036 240);
  --neutral-900:  #102C42;
  --neutral-950:  oklch(0.12  0.030 240);

  /* PALETTE — status. Same lightness curve as neutral so the 500 step in any
     ramp reads at the same perceived weight as 500 of any other. ------------ */

  /* success — green, hue 145. Hue 145 rather than 150: at 150 the sRGB gamut
     caps chroma at 0.171, at 145 it allows 0.195 — a materially brighter green
     that still reads green, not teal. The mid steps sit near that cap because
     the old ramp peaked at 0.150 and every green in the system read brown. */
  --success-50:   oklch(0.985 0.010 145);
  --success-100:  oklch(0.96  0.025 145);
  --success-200:  oklch(0.92  0.055 145);
  --success-300:  oklch(0.86  0.100 145);
  --success-400:  oklch(0.74  0.180 145);
  --success-500:  oklch(0.62  0.190 145);
  --success-600:  oklch(0.52  0.155 145);
  --success-700:  oklch(0.42  0.120 145);
  --success-800:  oklch(0.32  0.090 145);
  --success-900:  oklch(0.22  0.065 145);
  --success-950:  oklch(0.14  0.045 145);

  /* warning — orange, hue 50. Was amber at hue 75, which cannot produce a
     readable text step: 4.5:1 on white forces L down to ~0.55, and at hue 75 the
     sRGB gamut caps chroma at 0.116 there — the result is brown, not a warning.
     Hue 45 allows more chroma at the same lightness, so the ink step stays
     orange. The ink is -600 (L 0.60, #cd570d, 4.22:1) rather than a darker step:
     brown IS dark orange, so any value dark enough for a clean 4.5:1 reads brown.
     4.22:1 clears the 3:1 large-text floor and is the deliberate trade. */
  --warning-50:   oklch(0.985 0.008 45);
  --warning-100:  oklch(0.96  0.022 45);
  --warning-200:  oklch(0.92  0.046 45);
  --warning-300:  oklch(0.86  0.084 45);
  --warning-400:  oklch(0.76  0.158 45);
  --warning-500:  oklch(0.70  0.175 45);
  --warning-600:  oklch(0.65  0.170 45);
  --warning-700:  oklch(0.55  0.145 45);
  --warning-800:  oklch(0.36  0.095 45);
  --warning-900:  oklch(0.26  0.070 45);
  --warning-950:  oklch(0.16  0.045 45);

  /* danger — red, hue 25 */
  --danger-50:    oklch(0.985 0.012 25);
  --danger-100:   oklch(0.95  0.035 25);
  --danger-200:   oklch(0.90  0.075 25);
  --danger-300:   oklch(0.82  0.130 25);
  --danger-400:   oklch(0.70  0.185 25);
  --danger-500:   oklch(0.58  0.229 25);
  --danger-600:   oklch(0.50  0.197 25);
  --danger-700:   oklch(0.42  0.150 25);
  --danger-800:   oklch(0.32  0.115 25);
  --danger-900:   oklch(0.22  0.080 25);
  --danger-950:   oklch(0.14  0.050 25);

  /* info — blue, hue 255. Was cyan at hue 200, justified as "deliberately
     distinct from a typical blue accent" — but --accent is neutral-900, so there
     is no blue to collide with, and the cyan read as teal rather than as
     information. */
  --info-50:      oklch(0.985 0.007 255);
  --info-100:     oklch(0.96  0.019 255);
  --info-200:     oklch(0.92  0.039 255);
  --info-300:     oklch(0.86  0.070 255);
  --info-400:     oklch(0.74  0.136 255);
  --info-500:     oklch(0.62  0.200 255);
  --info-600:     oklch(0.52  0.172 255);
  --info-700:     oklch(0.42  0.140 255);
  --info-800:     oklch(0.32  0.108 255);
  --info-900:     oklch(0.22  0.077 255);
  --info-950:     oklch(0.14  0.055 255);

  /* SURFACES ---------------------------------------------------------- */

  --bg:           #ffffff;
  --bg-soft:      var(--neutral-50);
  --bg-muted:     var(--neutral-100);
  --bg-panel:     var(--neutral-50);
  --bg-elevated:  #ffffff;
  --bg-canvas:    var(--neutral-100);
  --bg-inverse:   var(--neutral-900);

  /* INK (text) -------------------------------------------------------- */

  --ink:          var(--neutral-900);
  --ink-soft:     var(--neutral-700);
  --ink-dim:      var(--neutral-500);
  --ink-faint:    var(--neutral-400);
  --ink-inverse:  var(--neutral-50);

  /* RULES (borders) --------------------------------------------------- */

  --rule:         var(--neutral-200);
  --rule-soft:    var(--neutral-100);
  --rule-strong:  var(--neutral-300);

  /* ACCENT — MONOCHROME BY DEFAULT
     The single most important variable for branding an Elements app.
     Override --accent (and companions) in a theme file to brand the whole
     system in one place. ---------------------------------------------- */

  --accent:       var(--neutral-900);
  --accent-deep:  var(--neutral-950);
  --accent-soft:  var(--neutral-100);
  --accent-ink:   var(--neutral-50);
  --accent-edge:  var(--neutral-300);

  /* STATUS triples
     Pattern for every alert/badge/toast:
       background: var(--{name}-soft);
       color:      var(--{name}-ink);
       border:     var(--{name});                                        */

  /* -fill is now the same vivid step as the accent: a -600 fill cleared 4.5:1
     with white text but read as dark/muddy, and vividness won. White on these
     lands at 3.4-4.8:1 — over the 3:1 large-text floor, under AA for body copy,
     which is the deliberate trade. Use -soft + -ink for anything text-heavy.

     -ink is the TEXT step. It must read on the page background AND on a -soft
     fill, so it is -600 (-700 for amber, which is only 4.03:1 on white at -600).
     It used to be -800, which is 11-13:1 — so dark it read as black and stopped
     signalling anything; form.css:236 documents a local workaround for exactly
     that.
     -fill is the step to put WHITE TEXT ON; the plain alias is the ACCENT (dot,
     border, icon) and is tuned to be vivid, which necessarily costs contrast.
     Green is the case that forces the split: at this hue sRGB has no colour that
     is both a bright green and 4.5:1 against white. Red clears both, so its fill
     and accent are the same step. */
  --success:       var(--success-500);
  --success-fill:  var(--success-500);
  --success-soft:  var(--success-50);
  --success-ink:   var(--success-600);
  --success-edge:  var(--success-200);

  --warning:       var(--warning-500);
  --warning-soft:  var(--warning-50);
  --warning-ink:   var(--warning-600);
  --warning-edge:  var(--warning-200);

  --danger:        var(--danger-500);
  --danger-fill:   var(--danger-500);
  --danger-soft:   var(--danger-50);
  --danger-ink:    var(--danger-600);
  --danger-edge:   var(--danger-200);

  --info:          var(--info-500);
  --info-fill:     var(--info-500);
  --info-soft:     var(--info-50);
  --info-ink:      var(--info-600);
  --info-edge:     var(--info-200);

  /* FOCUS — single ring spec. Every focusable component uses
     box-shadow: var(--focus-ring). ----------------------------------- */

  --focus:             var(--accent);
  --focus-ring:        0 0 0 2px var(--bg), 0 0 0 4px var(--focus);
  --focus-ring-danger: 0 0 0 2px var(--bg), 0 0 0 4px var(--danger);

  /* OPACITY slots ----------------------------------------------------- */

  --opacity-disabled: 0.55;
  --opacity-muted:    0.7;
  --opacity-overlay:  0.5;

  /* TRANSITION presets ------------------------------------------------ */

  --transition-colors:
    background-color var(--duration-fast) var(--ease-out),
    border-color     var(--duration-fast) var(--ease-out),
    color            var(--duration-fast) var(--ease-out),
    fill             var(--duration-fast) var(--ease-out),
    stroke           var(--duration-fast) var(--ease-out);
  --transition-shadow:    box-shadow var(--duration-fast) var(--ease-out);
  --transition-transform: transform var(--duration-fast) var(--ease-out);
  --transition-opacity:   opacity var(--duration-fast) var(--ease-out);

  /* RADIUS — 4px default. -------------------------------------------- */

  --radius:          4px;
  --radius-control:  var(--radius);          /* buttons, inputs, selects, tabs */
  --radius-surface:  var(--radius);          /* cards, panels */
  --radius-overlay:  var(--radius-md);       /* popovers, dropdowns, toasts — 6px */
  --radius-dialog:   var(--radius-lg);       /* modals, sheets — 8px */
  --radius-tag:      var(--radius-xs);       /* tags, chips, badges — 2px */
  --radius-pill:     var(--radius-full);     /* avatars, pills, status dots */

  /* CONTROL GLYPHS — data-URI strokes can't reference css variables, so
     each mode ships a literal-color variant. The stroke tracks
     --accent-ink (checkbox) and --ink-dim (select caret); a theme that
     changes those should repoint these too. -------------------------- */

  --checkbox-check: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='%23f8fafc' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='3.5 8.5 6.5 11.5 12.5 4.5'/%3E%3C/svg%3E");
  --select-caret:   url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12' fill='none' stroke='%23808d9a' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M3 5l3 3 3-3'/%3E%3C/svg%3E");

  /* COMPONENT slots --------------------------------------------------- */

  --input-height:        2.5rem;
  --input-height-sm:     2rem;
  --input-height-lg:     3rem;
  --input-padding-x:     0.875rem;
  --input-padding-y:     0.5rem;
  --input-radius:        var(--radius-control);
  --input-font-size:     var(--text-sm);
  --input-bg:            var(--bg);
  --input-border:        var(--rule);
  --input-border-hover:  var(--rule-strong);
  --input-border-focus:  var(--accent);
  --input-placeholder:   var(--ink-faint);

  --button-height:        2.5rem;
  --button-height-sm:     2rem;
  --button-height-lg:     3rem;
  --button-height-hero:   3.5rem;
  --button-padding-x:     1rem;
  --button-padding-x-sm:  0.75rem;
  --button-padding-x-lg:  1.25rem;
  --button-radius:        var(--radius-control);
  --button-font-size:     var(--text-sm);
  --button-font-size-lg:  var(--text-base);
  --button-font-weight:   var(--weight-medium);

  --avatar-size:     2rem;
  --avatar-size-xs:  1.25rem;
  --avatar-size-sm:  1.5rem;
  --avatar-size-lg:  2.5rem;
  --avatar-size-xl:  3.5rem;
  --avatar-radius:   var(--radius-pill);

  /* Terminal — fixed dark surface in both modes (unlike bare <pre>,
     which uses --bg-inverse and flips with the theme). ---------------- */

  --terminal-bg:      var(--neutral-900);
  --terminal-ink:     var(--neutral-100);
  --terminal-dim:     var(--neutral-500);
}

/* =============================================================================
   Dark mode
   Same semantic tokens, inverted surface/ink. Status hues stay readable.
   Two identical blocks: the OS preference (skipped when data-theme="light"
   forces light) and the data-theme="dark" attribute. Keep them in sync.
============================================================================= */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    color-scheme: dark;

    --bg:           var(--neutral-950);
    --bg-soft:      var(--neutral-900);
    --bg-muted:     var(--neutral-800);
    --bg-panel:     var(--neutral-900);
    --bg-elevated:  var(--neutral-800);
    --bg-canvas:    #000000;
    --bg-inverse:   var(--neutral-50);

    --ink:          var(--neutral-50);
    --ink-soft:     var(--neutral-300);
    --ink-dim:      var(--neutral-400);
    --ink-faint:    var(--neutral-500);
    --ink-inverse:  var(--neutral-900);

    --rule:         var(--neutral-800);
    --rule-soft:    var(--neutral-900);
    --rule-strong:  var(--neutral-700);

    --accent:       var(--neutral-50);
    --accent-deep:  #ffffff;
    --accent-soft:  var(--neutral-800);
    --accent-ink:   var(--neutral-900);
    --accent-edge:  var(--neutral-700);

    --success:       var(--success-400);
    --success-fill:  var(--success-600);
    --success-soft:  var(--success-950);
    --success-ink:   var(--success-200);
    --success-edge:  var(--success-800);

    --warning:       var(--warning-400);
    --warning-soft:  var(--warning-950);
    --warning-ink:   var(--warning-200);
    --warning-edge:  var(--warning-800);

    --danger:        var(--danger-400);
    --danger-fill:   var(--danger-600);
    --danger-soft:   var(--danger-950);
    --danger-ink:    var(--danger-200);
    --danger-edge:   var(--danger-800);

    --info:          var(--info-400);
    --info-soft:     var(--info-950);
    --info-ink:      var(--info-200);
    --info-edge:     var(--info-800);

    --checkbox-check: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='%23102c42' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='3.5 8.5 6.5 11.5 12.5 4.5'/%3E%3C/svg%3E");
    --select-caret:   url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12' fill='none' stroke='%23a7b0ba' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M3 5l3 3 3-3'/%3E%3C/svg%3E");
  }
}

:root[data-theme="dark"] {
  color-scheme: dark;

  --bg:           var(--neutral-950);
  --bg-soft:      var(--neutral-900);
  --bg-muted:     var(--neutral-800);
  --bg-panel:     var(--neutral-900);
  --bg-elevated:  var(--neutral-800);
  --bg-canvas:    #000000;
  --bg-inverse:   var(--neutral-50);

  --ink:          var(--neutral-50);
  --ink-soft:     var(--neutral-300);
  --ink-dim:      var(--neutral-400);
  --ink-faint:    var(--neutral-500);
  --ink-inverse:  var(--neutral-900);

  --rule:         var(--neutral-800);
  --rule-soft:    var(--neutral-900);
  --rule-strong:  var(--neutral-700);

  --accent:       var(--neutral-50);
  --accent-deep:  #ffffff;
  --accent-soft:  var(--neutral-800);
  --accent-ink:   var(--neutral-900);
  --accent-edge:  var(--neutral-700);

  --success:       var(--success-400);
  --success-fill:  var(--success-500);
  --success-soft:  var(--success-950);
  --success-ink:   var(--success-200);
  --success-edge:  var(--success-800);

  --warning:       var(--warning-400);
  --warning-soft:  var(--warning-950);
  --warning-ink:   var(--warning-200);
  --warning-edge:  var(--warning-800);

  --danger:        var(--danger-400);
  --danger-fill:   var(--danger-600);
  --danger-soft:   var(--danger-950);
  --danger-ink:    var(--danger-200);
  --danger-edge:   var(--danger-800);

  --info:          var(--info-400);
  --info-soft:     var(--info-950);
  --info-ink:      var(--info-200);
  --info-edge:     var(--info-800);

  --checkbox-check: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='%23102c42' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='3.5 8.5 6.5 11.5 12.5 4.5'/%3E%3C/svg%3E");
  --select-caret:   url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12' fill='none' stroke='%23a7b0ba' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M3 5l3 3 3-3'/%3E%3C/svg%3E");
}

@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;
  }
}
}
