/*
 * The design-system token contract: colors, spacing, typography, radii, motion,
 * elevation, and the z-scale, all as CSS variables. This ships as PRECOMPILED CSS
 * with preflight disabled (the SHELL owns preflight). Plugins style via these
 * tokens + SDK components ONLY.
 *
 * CASCADE ORDER. This file is the canonical layer-order emitter and loads FIRST.
 * The host's reset/`base` layer is ordered BEFORE the design-system layers so a
 * preflight that zeroes borders and heading typography cannot erase a DS
 * component class; the host's own utility layers are declared afterwards and so
 * sort AFTER `tai-utilities`, keeping host utilities the final word over DS
 * component styles.
 *
 * THEMING. The light value is the token; the dark value sits beside it under a
 * `--tai-dark-` name. Each colour is therefore still written exactly once, and
 * the two blocks that apply the dark half carry no values of their own — they
 * only re-point each token at its `--tai-dark-*` neighbour, so a light and dark
 * pair cannot drift apart. A `data-theme` pin on the root decides the theme in
 * BOTH directions — the media query stands down for a root pinned to light, and
 * the pinned-dark block applies the same set outright — so `prefers-color-scheme`
 * is the DEFAULT only for a root that carries no pin. In `apps/studio` that
 * window is the first paint: `ThemeProvider` (`useTheme`) stamps `data-theme` on
 * mount, after which the media query no longer decides and an OS theme flip
 * while the app is open changes nothing. Following the OS live — a `matchMedia`
 * listener and a `system` preference — belongs to the host's theme provider, not
 * to this sheet. A host that mounts no provider keeps the media query as its
 * theme source. `color-scheme` follows the same three states, so native scrollbars,
 * selects and form autofill match the tokens.
 *
 * BROWSER FLOOR. Deliberately NOT `light-dark()`. That function would fold each
 * pair onto one line, but it is invalid at computed-value time below Chrome 123 /
 * Firefox 120 / Safari 17.5 — and because every themed token would use it, the
 * whole palette drops out at once below that line, leaving text on text rather
 * than an unstyled page. These sheets ship as authored (the SDK build is `tsc`
 * plus a copy, so nothing lowers them), so what they ask for IS the floor: the
 * highest thing here is `@layer` and `:focus-visible`, at Chrome/Edge 99,
 * Firefox 97, and Safari / iOS Safari 15.4. That floor is declared in this
 * package's `browserslist` rather than left implicit, and the token scanner test
 * bans `light-dark()` so it cannot be raised back by accident. (The SHELL app
 * sits higher — it compiles Tailwind v4, whose own output needs `@property` and
 * `color-mix()` — and declares that floor in the repo root's `browserslist`.)
 *
 * UNITS. Type and spacing tokens are authored in rem so a viewer's font-size
 * preference scales them; radius, elevation, and z tokens stay px/unitless. The
 * comment beside each type/space token is its rendered px at a 16 px root.
 * Line-height and weight are NOT baked into these tokens — the component classes
 * own them, so a `font:` shorthand never resets them.
 */
@layer theme, base, tai-tokens, tai-components, tai-utilities;

@keyframes tai-spin {
  to {
    transform: rotate(360deg);
  }
}

/* Loading skeleton: a raised band sweeps across the LINE-tone ground the block
   rests at, which is what makes a placeholder read as pending rather than as
   empty content. The band is an OVERLAY (`.tai-skeleton::after` in
   `components.css`) travelling on `transform`, so the block itself never moves
   and the browser can carry the sweep on the compositor instead of restyling
   and repainting every skeleton on the page each frame. */
@keyframes tai-shimmer {
  from {
    transform: translateX(-100%);
  }
  to {
    transform: translateX(100%);
  }
}

/* Indeterminate progress: a short fill sweeps across the track when a running
   tool reports progress but no total is known. */
@keyframes tai-progress-indeterminate {
  0% {
    transform: translateX(-100%);
  }
  100% {
    transform: translateX(320%);
  }
}

@layer tai-tokens {
  :root {
    /* The OS preference is the default theme source; the data-theme blocks
       below pin it. */
    color-scheme: light dark;

    /* Every colour below carries the LIGHT value; the `--tai-dark-` line beside
       it carries the dark one. Nothing else in the repo writes either — the two
       blocks further down only re-point a token at its dark neighbour. */

    /* -- Grounds ---------------------------------------------------------- */
    --tai-color-bg: #ffffff;
    --tai-dark-color-bg: #0c0e12;
    --tai-color-surface: #f9fafb;
    --tai-dark-color-surface: #12151b;
    --tai-color-surface-raised: #ffffff;
    --tai-dark-color-surface-raised: #171c24;
    --tai-color-surface-disabled: var(--tai-color-surface);
    --tai-color-code-bg: #f3f4f6;
    --tai-dark-color-code-bg: #10131a;

    /* -- Lines ------------------------------------------------------------
       `border` and `border-strong` are decorative: they are below 3:1 and may
       never be a control's only boundary. `control-border` is the contrast-safe
       boundary for inputs, checkboxes, and secondary buttons. */
    --tai-color-border: #e5e7eb;
    --tai-dark-color-border: #262c36;
    --tai-color-border-strong: #d1d5db;
    --tai-dark-color-border-strong: #39414e;
    --tai-color-control-border: #767c85;
    --tai-dark-color-control-border: #646c79;
    --tai-color-border-disabled: var(--tai-color-border);

    /* -- Ink ---------------------------------------------------------------
       `decor` is the NON-TEXT tier (dividers, watermarks, decorative SVG fill
       or stroke). It never appears on `color:` and never identifies a component
       or a state. */
    --tai-color-text: #111827;
    --tai-dark-color-text: #e6e8ec;
    --tai-color-heading: #000000;
    --tai-dark-color-heading: #ffffff;
    --tai-color-text-muted: rgba(17, 24, 39, 0.62);
    --tai-dark-color-text-muted: rgba(230, 232, 236, 0.64);
    --tai-color-text-disabled: rgba(17, 24, 39, 0.38);
    --tai-dark-color-text-disabled: rgba(230, 232, 236, 0.36);
    --tai-color-placeholder: var(--tai-color-text-muted);
    --tai-color-decor: rgba(17, 24, 39, 0.44);
    --tai-dark-color-decor: rgba(230, 232, 236, 0.42);

    /* -- Accent (crimson) --------------------------------------------------
       The accent is brand, never status. `accent-hover` darkens in light and
       LIGHTENS in dark. `accent-on-tint` is accent TEXT sitting on accent-tint;
       `on-accent` is the label on an accent FILL. */
    --tai-color-accent: #dc143c;
    --tai-dark-color-accent: #ed4c67;
    --tai-color-accent-hover: #800020;
    --tai-dark-color-accent-hover: #f4718a;
    --tai-color-accent-on-tint: #be123c;
    --tai-dark-color-accent-on-tint: #f4718a;
    --tai-color-on-accent: #ffffff;
    --tai-dark-color-on-accent: #0c0e12;
    --tai-color-accent-tint: rgba(220, 20, 60, 0.08);
    --tai-dark-color-accent-tint: rgba(237, 76, 103, 0.12);

    /* -- Semantic ----------------------------------------------------------
       The `-text` members are the ONLY ones legible as text, dots, or icons;
       the `-fill` members are for fills and charts and carry `on-fill` ink
       labels in both themes. */
    --tai-color-ok-text: #047857;
    --tai-dark-color-ok-text: #34d399;
    --tai-color-err-text: #b91c1c;
    --tai-dark-color-err-text: #f87171;
    --tai-color-warn-text: #92400e;
    --tai-dark-color-warn-text: #fbbf24;
    --tai-color-ok-fill: #10b981;
    --tai-dark-color-ok-fill: #34d399;
    --tai-color-err-fill: #ef4444;
    --tai-dark-color-err-fill: #f87171;
    --tai-color-warn-fill: #d97706;
    --tai-dark-color-warn-fill: #fbbf24;
    --tai-color-ok-tint: rgba(16, 185, 129, 0.1);
    --tai-dark-color-ok-tint: rgba(52, 211, 153, 0.12);
    --tai-color-err-tint: rgba(239, 68, 68, 0.1);
    --tai-dark-color-err-tint: rgba(248, 113, 113, 0.12);
    --tai-color-warn-tint: rgba(217, 119, 6, 0.1);
    --tai-dark-color-warn-tint: rgba(251, 191, 36, 0.12);
    /* The one ink deliberately identical in both themes: every semantic fill is
       light enough that only the dark label clears the contrast floor on it. */
    --tai-color-on-fill: #0c0e12;

    /* -- Focus + overlay ----------------------------------------------------
       The ring is an ALIAS, not a restatement: it IS the accent, so referencing
       it keeps two values that must move together from drifting apart, and it
       needs no dark half of its own. */
    --tai-color-focus-ring: var(--tai-color-accent);
    --tai-color-scrim: rgba(0, 0, 0, 0.45);
    --tai-dark-color-scrim: rgba(0, 0, 0, 0.6);

    /* -- Prose --------------------------------------------------------------
       A prose link is always underlined, so colour is a reinforcement rather
       than the only cue. Dark rest is the LIGHTER crimson: the light-theme
       accent is too dim against a dark ground, and the hover value is the
       legible one there (6.17 on raised). Hover then moves to the other member
       in both themes. Spelled out rather than aliased — the two halves of each
       pair come from different members of the accent ramp. */
    --tai-color-prose-link: #dc143c;
    --tai-dark-color-prose-link: #f4718a;
    --tai-color-prose-link-hover: #800020;
    --tai-dark-color-prose-link-hover: #ed4c67;

    /* -- Syntax (JSON/code on code-bg) -------------------------------------- */
    --tai-color-syntax-key: var(--tai-color-text-muted);
    --tai-color-syntax-string: var(--tai-color-ok-text);
    --tai-color-syntax-number: var(--tai-color-accent);
    --tai-color-syntax-bool: var(--tai-color-warn-text);

    /* -- Legacy token slots -------------------------------------------------
       The names a plugin already styles against. `primary`/`success`/`warning`
       re-point at the members of the contract above that keep them legible.

       `danger` is the one destructive EMPHASIS, and it runs deeper than the
       accent on purpose: a destructive fill sharing the crimson brand ramp reads
       as the primary action, so this is its own deep red — clearly darker and
       less pink than the accent in BOTH themes, unlike the light-fill dark-ink
       convention the accent follows. Its label is white in both themes and its
       hover a shade deeper still, so a destructive button is instantly told apart
       from a primary one. `danger-text` is that white label on the danger FILL;
       `danger-surface` is the faint error-tint ground the label sits over
       elsewhere. */
    --tai-color-primary: var(--tai-color-accent);
    --tai-color-primary-text: var(--tai-color-on-accent);
    --tai-color-danger: #991b1b;
    --tai-dark-color-danger: #dc2626;
    --tai-color-danger-text: #ffffff;
    --tai-dark-color-danger-text: #ffffff;
    --tai-color-danger-hover: #7f1d1d;
    --tai-dark-color-danger-hover: #b91c1c;
    --tai-color-danger-surface: var(--tai-color-err-tint);
    --tai-color-success: var(--tai-color-ok-text);
    --tai-color-warning: var(--tai-color-warn-text);

    /* -- Spacing (n x 4; there is deliberately no space-7) ------------------ */
    --tai-space-1: 0.25rem; /* 4px */
    --tai-space-2: 0.5rem; /* 8px */
    --tai-space-3: 0.75rem; /* 12px */
    --tai-space-4: 1rem; /* 16px */
    --tai-space-5: 1.25rem; /* 20px */
    --tai-space-6: 1.5rem; /* 24px */
    --tai-space-8: 2rem; /* 32px */

    /* -- Radius ------------------------------------------------------------- */
    --tai-radius-sm: 4px;
    --tai-radius-code: 6px;
    --tai-radius-md: 8px;
    --tai-radius-tile: 10px;
    --tai-radius-lg: 12px;
    --tai-radius-overlay: 14px;
    --tai-radius-full: 999px;

    /* -- Type --------------------------------------------------------------- */
    --tai-font-sans:
      'Inter Variable', ui-sans-serif, system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;
    --tai-font-mono:
      'Geist Mono Variable', ui-monospace, 'SF Mono', 'JetBrains Mono', Menlo, monospace;
    --tai-text-display: 1.625rem; /* 26px — KPI numbers */
    --tai-text-xl: 1.4375rem; /* 23px — page title */
    --tai-text-section: 1.0625rem; /* 17px — section heading */
    --tai-text-lg: 0.9375rem; /* 15px — card title */
    --tai-text-md: 0.84375rem; /* 13.5px — body */
    --tai-text-sm: 0.78125rem; /* 12.5px — secondary */
    --tai-text-code: 0.75rem; /* 12px — mono blocks */
    --tai-text-xs: 0.6875rem; /* 11px — labels, badges, axes (the floor) */

    /* -- Control geometry ---------------------------------------------------
       One height for every button, input, and select trigger; the coarse value
       is the pointer-target minimum a touch device gets instead. */
    --tai-control-height: 36px;
    --tai-control-height-coarse: 44px;

    /* -- Motion -------------------------------------------------------------- */
    --tai-motion-fast: 150ms;
    --tai-motion-base: 250ms;

    /* -- Elevation ------------------------------------------------------------
       Only the shadow COLOUR varies by theme; the geometry is written once, so a
       dark override cannot silently move an offset or a blur. */
    --tai-shadow-lift-color: rgb(0 0 0 / 0.08);
    --tai-dark-shadow-lift-color: rgb(0 0 0 / 0.45);
    --tai-shadow-overlay-color: rgb(0 0 0 / 0.16);
    --tai-dark-shadow-overlay-color: rgb(0 0 0 / 0.6);
    --tai-shadow-lift: 0 12px 32px var(--tai-shadow-lift-color);
    --tai-shadow-overlay: 0 24px 48px var(--tai-shadow-overlay-color);
    /* Legacy slots, re-pointed at the new elevation pair. Both names are kept
       and both changed MEANING: they were resting shadows (`0 1px 2px` /
       `0 4px 12px`) and now alias the lift and overlay geometry. */
    --tai-shadow-sm: var(--tai-shadow-lift);
    --tai-shadow-md: var(--tai-shadow-overlay);

    /* -- Stacking ------------------------------------------------------------
       `popover` and `tooltip` sit ABOVE the modal layers on purpose. Both are
       portalled to the document body as siblings of a dialog, and both can only
       be opened from whatever layer is on top — so a listbox or a tip raised
       from inside a dialog has to clear that dialog's scrim to be usable.
       `dropdown` is the rung reserved for an in-flow menu surface — one that
       stacks against the page rather than being portalled. Nothing in this repo
       is on it; it is part of the published scale so a plugin's own menu has a
       rung to sit on instead of inventing a number. */
    --tai-z-sticky: 10;
    --tai-z-dropdown: 20;
    --tai-z-overlay: 30;
    --tai-z-dialog: 40;
    --tai-z-popover: 45;
    --tai-z-tooltip: 50;
  }

  /*
   * THE DARK HALF, APPLIED. The next two blocks are the only places the dark
   * values are put into service, and neither carries a value of its own: every
   * line re-points a token at its `--tai-dark-*` neighbour above. The media query
   * stands down for a root explicitly pinned to light, so the viewer's choice
   * always wins over the operating system's. The token scanner test holds the two
   * blocks to the same token set, so a token can never take the dark half under
   * one of them and keep the light half under the other.
   */
  @media (prefers-color-scheme: dark) {
    :root:not([data-theme='light']) {
      --tai-color-bg: var(--tai-dark-color-bg);
      --tai-color-surface: var(--tai-dark-color-surface);
      --tai-color-surface-raised: var(--tai-dark-color-surface-raised);
      --tai-color-code-bg: var(--tai-dark-color-code-bg);
      --tai-color-border: var(--tai-dark-color-border);
      --tai-color-border-strong: var(--tai-dark-color-border-strong);
      --tai-color-control-border: var(--tai-dark-color-control-border);
      --tai-color-text: var(--tai-dark-color-text);
      --tai-color-heading: var(--tai-dark-color-heading);
      --tai-color-text-muted: var(--tai-dark-color-text-muted);
      --tai-color-text-disabled: var(--tai-dark-color-text-disabled);
      --tai-color-decor: var(--tai-dark-color-decor);
      --tai-color-accent: var(--tai-dark-color-accent);
      --tai-color-accent-hover: var(--tai-dark-color-accent-hover);
      --tai-color-accent-on-tint: var(--tai-dark-color-accent-on-tint);
      --tai-color-on-accent: var(--tai-dark-color-on-accent);
      --tai-color-accent-tint: var(--tai-dark-color-accent-tint);
      --tai-color-ok-text: var(--tai-dark-color-ok-text);
      --tai-color-err-text: var(--tai-dark-color-err-text);
      --tai-color-warn-text: var(--tai-dark-color-warn-text);
      --tai-color-ok-fill: var(--tai-dark-color-ok-fill);
      --tai-color-err-fill: var(--tai-dark-color-err-fill);
      --tai-color-warn-fill: var(--tai-dark-color-warn-fill);
      --tai-color-ok-tint: var(--tai-dark-color-ok-tint);
      --tai-color-err-tint: var(--tai-dark-color-err-tint);
      --tai-color-warn-tint: var(--tai-dark-color-warn-tint);
      --tai-color-scrim: var(--tai-dark-color-scrim);
      --tai-color-prose-link: var(--tai-dark-color-prose-link);
      --tai-color-prose-link-hover: var(--tai-dark-color-prose-link-hover);
      --tai-color-danger: var(--tai-dark-color-danger);
      --tai-color-danger-text: var(--tai-dark-color-danger-text);
      --tai-color-danger-hover: var(--tai-dark-color-danger-hover);
      --tai-shadow-lift-color: var(--tai-dark-shadow-lift-color);
      --tai-shadow-overlay-color: var(--tai-dark-shadow-overlay-color);
    }
  }

  /* The viewer's explicit toggle wins over the system preference, in BOTH
     directions (data-theme is stamped on the root by useTheme). Pinning
     `color-scheme` is what keeps native UI — scrollbars, selects, autofill — on
     the same theme as the tokens. */
  :root[data-theme='light'] {
    color-scheme: light;
  }

  :root[data-theme='dark'] {
    color-scheme: dark;
    --tai-color-bg: var(--tai-dark-color-bg);
    --tai-color-surface: var(--tai-dark-color-surface);
    --tai-color-surface-raised: var(--tai-dark-color-surface-raised);
    --tai-color-code-bg: var(--tai-dark-color-code-bg);
    --tai-color-border: var(--tai-dark-color-border);
    --tai-color-border-strong: var(--tai-dark-color-border-strong);
    --tai-color-control-border: var(--tai-dark-color-control-border);
    --tai-color-text: var(--tai-dark-color-text);
    --tai-color-heading: var(--tai-dark-color-heading);
    --tai-color-text-muted: var(--tai-dark-color-text-muted);
    --tai-color-text-disabled: var(--tai-dark-color-text-disabled);
    --tai-color-decor: var(--tai-dark-color-decor);
    --tai-color-accent: var(--tai-dark-color-accent);
    --tai-color-accent-hover: var(--tai-dark-color-accent-hover);
    --tai-color-accent-on-tint: var(--tai-dark-color-accent-on-tint);
    --tai-color-on-accent: var(--tai-dark-color-on-accent);
    --tai-color-accent-tint: var(--tai-dark-color-accent-tint);
    --tai-color-ok-text: var(--tai-dark-color-ok-text);
    --tai-color-err-text: var(--tai-dark-color-err-text);
    --tai-color-warn-text: var(--tai-dark-color-warn-text);
    --tai-color-ok-fill: var(--tai-dark-color-ok-fill);
    --tai-color-err-fill: var(--tai-dark-color-err-fill);
    --tai-color-warn-fill: var(--tai-dark-color-warn-fill);
    --tai-color-ok-tint: var(--tai-dark-color-ok-tint);
    --tai-color-err-tint: var(--tai-dark-color-err-tint);
    --tai-color-warn-tint: var(--tai-dark-color-warn-tint);
    --tai-color-scrim: var(--tai-dark-color-scrim);
    --tai-color-prose-link: var(--tai-dark-color-prose-link);
    --tai-color-prose-link-hover: var(--tai-dark-color-prose-link-hover);
    --tai-color-danger: var(--tai-dark-color-danger);
    --tai-color-danger-text: var(--tai-dark-color-danger-text);
    --tai-color-danger-hover: var(--tai-dark-color-danger-hover);
    --tai-shadow-lift-color: var(--tai-dark-shadow-lift-color);
    --tai-shadow-overlay-color: var(--tai-dark-shadow-overlay-color);
  }

  /* The motion durations are published API: a plugin writes
     `transition: … var(--tai-motion-fast)` against them and has no other way to
     learn the viewer's preference. Zeroing them here honours that preference for
     every consumer at once — this repo's classes, and code the design system
     never sees. (The component layer additionally pins `transition: none` on its
     own controls, which covers any that do not spell their duration as a token.) */
  @media (prefers-reduced-motion: reduce) {
    :root {
      --tai-motion-fast: 0ms;
      --tai-motion-base: 0ms;
    }
  }
}
