/**
 * @todayai-labs/tck-host/style — host-side baseline contract.
 *
 * Every TCK consumer (workbench, apps/web embed shell, future
 * macOS WKWebView host) `<link>`s this stylesheet so the bits the
 * widget bundler deliberately strips from each `.tckb`'s
 * `widget.css` are present on the host: a baseline reset, theme
 * tokens, and the `[data-theme='dark']` variant binding that
 * bundled widgets compile against.
 *
 * It does NOT ship Tailwind's element-level preflight (the
 * `h1…/p/button/img/…` reset rules) — only a minimal baseline:
 * a `box-sizing` reset, an `html, body` reset, design tokens,
 * the `[data-theme]` swaps, and the feed-chrome classes. A host
 * that needs element preflight supplies it via its own
 * `@import 'tailwindcss'` (host-playground does this at
 * `src/index.css`); a pure-light-DOM host that `<link>`s only
 * this file gets none.
 *
 * No utility classes ship here — utilities are the widget's
 * responsibility, delivered inside `widget.css` and adopted into the
 * widget's shadow root. The host's job is to provide:
 *
 *   - A `box-sizing` reset so widget JSX layout works as authored.
 *   - `--tck-columns` / `--tck-gap` / `--tck-cell` defaults the
 *     canvas reads (hosts override per breakpoint via media query).
 *   - `--tck-radius-*` tokens for chrome-side rounded surfaces.
 *   - `--font-sans` as a system stack. Consumers wanting a brand
 *     face override `--font-sans` on the host element before
 *     loading this stylesheet.
 *   - Light/dark token pairs swapped via `[data-theme='dark']`.
 *     The attribute lives on `<html>` and is the canonical theme
 *     surface across the TCK ecosystem (bundler, preview,
 *     workbench, embed shell). Host-specific theming conventions
 *     (`html.dark`, OS prefers-color-scheme, etc.) don't reach
 *     widgets — only `[data-theme]` does.
 *
 * # Scoping — `data-tck-host` sentinel (host-style@0.5.0+)
 *
 * Before 0.5.0 this stylesheet declared its reset, tokens, and
 * theme rules at bare `:root` / `html, body` / `*` selectors,
 * leaking the box-sizing reset, the body-color override, and the
 * full Tailwind v4 stock palette into consumer documents that
 * `<link>`'d the file. apps/web users on todayai.dev surfaced the
 * leak (Task #32): the Tailwind palette and `--font-sans` override
 * showed up on the document `<html>` even on non-TCK routes.
 *
 * Post-0.5.0 every leak-prone rule is wrapped in
 * `:where([data-tck-host])`. Consumers MUST mark the ancestor of
 * their widget mount point with `data-tck-host`; the box-sizing
 * reset, the typography reset, the design tokens, and the
 * Tailwind palette all cascade to descendants of that element
 * (and only those descendants).
 *
 *   - Full-document hosts (embed shells, the workbench): add
 *     `data-tck-host` to `<html>`. Behavior matches pre-0.5.0.
 *   - Scoped hosts (apps/web `<TodayHomeV2>` inside the opal
 *     chrome): add `data-tck-host` to the canvas mount div
 *     (`#canvas-feed-root`). Only the canvas subtree sees the
 *     reset + tokens; the opal chrome's own typography and box
 *     sizing stay independent.
 *
 * `:where(...)` carries zero specificity, so consumer overrides
 * (a brand font-family on the host element, a custom
 * `--font-sans`, a different background) still win on collision.
 *
 * Cascade order consumers should produce:
 *   1. host-base.css           (this file — baseline reset + tokens
 *                                under `:where([data-tck-host])`)
 *   2. per-widget widget.css   (fetched at mount and adopted inside
 *                                the widget shadow root; selectors
 *                                match only widget DOM)
 *   3. host-chrome.css         (the consumer's own card surface,
 *                                gradient, page-level decoration)
 */

:where([data-tck-host]),
:where([data-tck-host]) *,
:where([data-tck-host]) *::before,
:where([data-tck-host]) *::after {
  box-sizing: border-box;
}

/* Transparent-canvas declaration is NOT here. The load-bearing
 * `html, body { background: transparent }` rule emits from
 * `getHostHeadNodes` (`bootstrap/get-host-head-nodes.tsx`) as a
 * dedicated `<style data-tck-host-transparent-canvas>` head node,
 * with the CSS Color Adjust spec citation visible at the emission
 * point. Keeping it out of this stylesheet prevents a refactor (or
 * a downstream `style.css`-only consumer that skips
 * `getHostHeadNodes`) from silently dropping the iframe-mode
 * transparency invariant. See `documents/render-mode-contract.md`
 * §7.4.
 *
 * Pre-0.5.0 this used `html, body { margin/padding/font-family }`,
 * which leaked into the consumer's document body. Post-0.5.0 the
 * rule targets only `:where([data-tck-host])` — full-document
 * consumers put the attribute on `<html>` to get the original
 * behavior; scoped consumers put it on their canvas-root div
 * and only that subtree resets. */
:where([data-tck-host]) {
  margin: 0;
  padding: 0;
  font-family: var(--font-sans);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

:where([data-tck-host]) {
  /* Widget-bundle `rem` resolution — the contract token.
   *
   * Widgets are mounted in shadow DOM, but `rem` resolves against
   * `<html>` regardless of shadow boundary (CSS Values 4 §6.1.1:
   * `rem` = the root element's `font-size`). That makes the
   * widget's rendered scale silently dependent on whatever
   * `font-size` the consumer document happens to land on — browser
   * default, accessibility override, or a host that decided to set
   * `html { font-size: 14px }` for layout reasons.
   *
   * `tck-bundler` v3+ rewrites every `Nrem` declaration in the
   * compiled `widget.css` to `calc(N * var(--tck-rem, 16px))`, so
   * widgets read this token instead of `<html>`'s root font-size.
   * Paired with the `:host { font-size: var(--tck-rem, 16px) }`
   * declaration the shared shadow reset adopts (`tck-host/src/
   * bootstrap/shared-stylesheets.ts`), every length unit a widget
   * can consume — `rem` (rewritten), `em`, `%` font-size — agrees
   * on this same value, so the widget's intrinsic scale is fully
   * decoupled from the host document's `<html>`.
   *
   * 16px is the spec-default UA root font-size and the value every
   * current TCK consumer (preview-web, host-playground, the macOS
   * `harness.html` WKWebView, apps/web embed) renders against
   * today. Hosts that want a different uniform widget scale —
   * compact mode, accessibility-large mode, brand calibration —
   * override this single property and every widget's `rem` chain
   * follows. The `, 16px` fallback inside the bundler-emitted
   * `calc(... var(--tck-rem, 16px))` keeps old hosts that don't
   * declare the token rendering at the previous baseline.
   *
   * NOT a widget design token — widgets must not redeclare it; the
   * bundler's strip of `--default-*`/`--color-*` etc. doesn't reach
   * `--tck-rem`, so a stray widget-side declaration would override
   * the host's calibration. The token's contract surface lives on
   * the host's `[data-tck-host]` element and inherits across the
   * shadow boundary like other `--tck-*` tokens. */
  --tck-rem: 16px;

  /* Typography — Tailwind v4's stock `@theme` font stacks, transcribed
     verbatim from `tailwindcss/theme.css` (--font-sans / --font-serif /
     --font-mono). The host injects standard, un-customized Tailwind: no
     brand face, no reordering. Consumers wanting a brand font override
     --font-sans on the host element (or anywhere inside it) before
     loading this stylesheet. */
  --font-sans:
    ui-sans-serif, system-ui, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol',
    'Noto Color Emoji';
  --font-serif: ui-serif, Georgia, Cambria, 'Times New Roman', Times, serif;
  --font-mono:
    ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, 'Liberation Mono', 'Courier New',
    monospace;

  /* Radii — mirror Tailwind defaults so widget cards composed with
     `rounded-lg` / `rounded-3xl` line up with host-side surfaces
     authored against the same scale. */
  --tck-radius-sm: 0.5rem;
  --tck-radius-md: 0.75rem;
  --tck-radius-lg: 1rem;
  --tck-radius-xl: 1.5rem;

  /* Surface tokens (light defaults). Widgets and host chrome
     consume these so a theme flip propagates via attribute alone. */
  --tck-fg: oklch(0.145 0 0);
  --tck-bg: oklch(1 0 0);
  --tck-muted: oklch(0.97 0 0);
  --tck-muted-fg: oklch(0.556 0 0);
  --tck-border: oklch(0.922 0 0);
  --tck-ring: oklch(0.708 0 0);

  /* Text hierarchy tokens — designed for 3 weights of emphasis
     within the same paragraph (e.g. feed group header reads
     "kind · when" with kind primary, divider tertiary, when
     secondary). Aliases let consumers use either the semantic
     name (--tck-fg / --tck-muted-fg) or the hierarchy name. */
  --tck-text-primary: var(--tck-fg);
  --tck-text-secondary: oklch(0.4 0 0);
  --tck-text-tertiary: var(--tck-muted-fg);

  /* Naming bridge: consumers using the longer `--tck-color-*`
     convention (matches design system docs in some hosts) can
     read these aliases. Sources of truth remain the short names
     above; aliases never carry their own values. */
  --tck-color-bg-muted: var(--tck-muted);
  --tck-color-text-warning: oklch(0.65 0.15 30);

  /* Per-tile glass-card surface tokens — consumed by boot.ts's
     `renderTile` so widget tiles inside the iframe canvas read
     theme-correct values via `var(...)`. Hosts that want a
     different card aesthetic override the four tokens on the host
     element or another host-owned ancestor; boot.ts stays pure
     (theme-agnostic JS object styles). Design calibrated values:
     `/55` background opacity so the dawn
     gradient reads through warmly, 12px backdrop blur (not 4px —
     gradient banding ghosts at smaller blur), inset highlight
     +1px to lift the card off the iframe-transparent body. */
  --tck-card-bg: rgb(255 255 255 / 0.55);
  --tck-card-shadow: 0 1px 0 rgba(255, 255, 255, 0.7) inset, 0 4px 12px -6px rgba(15, 23, 42, 0.12);
  --tck-card-radius: 16px;
  --tck-card-backdrop-filter: blur(12px);

  /* Canvas grid defaults — 4 columns at the widest breakpoint,
     16px gap, cell side derived from container width. Hosts
     override --tck-columns per breakpoint via media queries; the
     canvas re-publishes a measured pixel value for --tck-cell at
     runtime so 1×1 tiles render exactly square (see
     TodayWidgetCanvas.useMeasuredCellSize). */
  --tck-columns: 4;
  --tck-gap: 16px;
  --tck-cell: calc((100% - (var(--tck-columns) - 1) * var(--tck-gap)) / var(--tck-columns));
}

@media (max-width: 479.9px) {
  :where([data-tck-host]) {
    --tck-columns: 2;
  }
}

/* Dark theme. `[data-theme='dark']` on <html> is the canonical
   switch — the widget bundler bakes Tailwind's `dark:` variant
   against this exact selector (see tck-bundler/src/css.ts:99),
   so tokens and `dark:` utilities flip in lockstep. Post-0.5.0
   scoping requires that the dark tokens apply to the
   `[data-tck-host]` subtree when EITHER:
     - the host element itself carries `[data-theme='dark']`
       (full-document hosts: `<html data-tck-host data-theme>`)
     - an ancestor of the host element carries it (scoped
       hosts: `<html data-theme><div data-tck-host>`)
   The two-selector list below covers both. We do NOT scope to
   `[data-tck-host] [data-theme='dark']` (a `[data-theme]`
   *inside* the host subtree) — that's not a documented use case
   and would let widget DOM accidentally redefine the host's
   theme. */
:where([data-tck-host])[data-theme='dark'],
:where([data-theme='dark']) :where([data-tck-host]) {
  --tck-fg: oklch(0.985 0 0);
  --tck-bg: oklch(0.145 0 0);
  --tck-muted: oklch(0.205 0 0);
  --tck-muted-fg: oklch(0.708 0 0);
  --tck-border: oklch(0.205 0 0);
  --tck-ring: oklch(0.439 0 0);
  --tck-text-secondary: oklch(0.7 0 0);

  /* Dark-side glass card. Background steps to neutral-900-ish at
     50% so the dark dawn-gradient still reads through; inset
     highlight drops to 5% (subtle edge lift); ambient shadow
     deepens. Same shape as light — only the values flip. */
  --tck-card-bg: rgb(38 38 46 / 0.5);
  --tck-card-shadow: 0 1px 0 rgba(255, 255, 255, 0.05) inset, 0 4px 12px -6px rgba(0, 0, 0, 0.45);
}

/* `color-scheme` so UA-painted UI inside the host subtree — scrollbars,
   native form controls, and the canvas layer behind a transparent
   widget — tracks `[data-theme]` rather than the OS
   `prefers-color-scheme`. Without this a widget in TCK dark theme that
   sits on a `prefers-color-scheme: light` machine gets light scrollbars
   / a light UA canvas bleeding through. Rides the same selectors as the
   token swaps above so it flips in lockstep; the iframe render path sets
   the equivalent in `tck-preview`'s `widget-frame/frame.css`. */
:where([data-tck-host]) {
  color-scheme: light;
}
:where([data-tck-host]) body {
  color-scheme: light;
}
:where([data-tck-host])[data-theme='dark'],
:where([data-tck-host])[data-theme='dark'] body,
:where([data-theme='dark']) :where([data-tck-host]) {
  color-scheme: dark;
}

/* ─────────────────────────────────────────────────────────────────
 * Tailwind v4 stock palette — Class C systemic fix (Task #44).
 *
 * Architect's ratified shape (2026-05-19, after retracting an
 * earlier @theme proposal): plain custom-property declarations,
 * now scoped to `:where([data-tck-host])`.
 *
 * **Why this lives here**: widget bundles compiled with Tailwind v4
 * have their `@layer theme { ... }` block stripped by the bundler
 * (intentional — host owns the cascade root, widgets must not
 * redeclare). Pre-Class-C, the host did NOT then re-emit Tailwind's
 * stock palette, so `--color-neutral-500`, `--color-sky-200`, and
 * peers resolved to undefined at runtime and Tailwind utilities like
 * `bg-neutral-100` or `text-sky-700` rendered as transparent /
 * inheriting. 28/28 feed widgets on Surface A (preview-playground)
 * and 32/32 elements on Surface C (apps/web embed via
 * `/__tck/v1/style.css`) exhibited the failure.
 *
 * **Why a host-scoped selector and not `@theme`**: `tck-host/style.css`
 * ships as static CSS bytes — Vite's CSS-import handling on
 * consumers preserves the file as-is (no Tailwind v4 closure runs
 * at consumer build time), and apps/web's `/__tck/v1/style.css`
 * route returns the raw file. Nothing re-processes this file
 * through Tailwind v4, so `@theme { ... }` would be an unknown
 * at-rule the browser skips. Plain CSS custom-property declarations
 * DO take effect: the vars cascade, `var(--color-neutral-500)`
 * resolves, utilities render correctly. Post-0.5.0 the declarations
 * live on `:where([data-tck-host])` instead of `:root`; widgets
 * still resolve them because every widget mount lives inside a
 * `[data-tck-host]` ancestor by construction.
 *
 * **Single source of truth**: OKLCH values transcribed from Tailwind
 * v4's stock theme (tailwindcss/theme.css upstream) — byte-identical,
 * including the percent-form OKLCH lightness, so re-syncing on a
 * Tailwind upgrade is a clean diff. Theme-agnostic
 * — Tailwind v4 expresses dark variants via `.dark:bg-*` utility
 * classes rather than re-declaring palette vars, so no
 * `[data-theme='dark']` override block is needed for the palette
 * itself (the existing dark block above only flips semantic
 * `--tck-*` tokens).
 *
 * **Scale coverage — 11 of Tailwind v4's 22 stock scales**: this
 * block emits neutral, slate, sky, blue, red, green, amber, indigo,
 * pink, violet, yellow — 11 shades each (50 through 950), 121 vars.
 * The other 11 stock scales (orange, lime, emerald, teal, cyan,
 * purple, fuchsia, rose, gray, zinc, stone) are intentionally NOT
 * emitted: no feed widget references them today, and declaring all
 * 22 would add ~120 unused custom properties to every host payload.
 * To use an omitted scale, add its 11 shades here, transcribed
 * verbatim from `tailwindcss/theme.css` (same percent-OKLCH form).
 *
 * **Constraint widgets must follow**: do not use `@theme` extensions
 * in widget CSS for runtime-resolved vars — the bundler strips that
 * block, and the host pre-declares only what's in the Tailwind v4
 * stock palette. To add a brand-specific shade, override the
 * relevant `--color-<name>-<shade>` var on `[data-tck-host]` AFTER
 * importing this file (or in the host chrome stylesheet that loads
 * later in the cascade).
 *
 * Refs: Task #44, design's SEVERITY-TABLE.md, architect ratify on
 * 2026-05-19.
 * ───────────────────────────────────────────────────────────────── */

:where([data-tck-host]) {
  /* Black / white — the two non-scale anchors of Tailwind v4's stock
     `@theme` (`tailwindcss/theme.css`: `--color-black: #000;` /
     `--color-white: #fff;`). The bundler strips ALL `--color-*` from a
     widget bundle (color is theme, host-provided — `tck-bundler/src/
     css.ts` partitionThemeLayer), so a widget using `border-black/5` or
     `bg-white/50` reaches for `var(--color-black)` / `var(--color-white)`
     at render time. Tailwind compiles those to
     `color-mix(in oklab, var(--color-black) 5%, transparent)` under an
     `@supports (color-mix in lab)` guard that every modern engine takes;
     if the host omits the token the `var()` is undefined, the whole
     declaration is invalid at computed-value time, and `border-color`
     falls back to its initial `currentColor` — rendering a 5% hairline
     as a solid near-black border (`bg-white/*` collapses to transparent
     the same way). They are absolute constants, not themeable, so no
     `[data-theme='dark']` override is needed. */
  --color-black: #000;
  --color-white: #fff;

  /* Neutral — theme-agnostic in Tailwind v4 (no dark override). */
  --color-neutral-50: oklch(98.5% 0 0);
  --color-neutral-100: oklch(97% 0 0);
  --color-neutral-200: oklch(92.2% 0 0);
  --color-neutral-300: oklch(87% 0 0);
  --color-neutral-400: oklch(70.8% 0 0);
  --color-neutral-500: oklch(55.6% 0 0);
  --color-neutral-600: oklch(43.9% 0 0);
  --color-neutral-700: oklch(37.1% 0 0);
  --color-neutral-800: oklch(26.9% 0 0);
  --color-neutral-900: oklch(20.5% 0 0);
  --color-neutral-950: oklch(14.5% 0 0);

  /* Slate */
  --color-slate-50: oklch(98.4% 0.003 247.858);
  --color-slate-100: oklch(96.8% 0.007 247.896);
  --color-slate-200: oklch(92.9% 0.013 255.508);
  --color-slate-300: oklch(86.9% 0.022 252.894);
  --color-slate-400: oklch(70.4% 0.04 256.788);
  --color-slate-500: oklch(55.4% 0.046 257.417);
  --color-slate-600: oklch(44.6% 0.043 257.281);
  --color-slate-700: oklch(37.2% 0.044 257.287);
  --color-slate-800: oklch(27.9% 0.041 260.031);
  --color-slate-900: oklch(20.8% 0.042 265.755);
  --color-slate-950: oklch(12.9% 0.042 264.695);

  /* Sky */
  --color-sky-50: oklch(97.7% 0.013 236.62);
  --color-sky-100: oklch(95.1% 0.026 236.824);
  --color-sky-200: oklch(90.1% 0.058 230.902);
  --color-sky-300: oklch(82.8% 0.111 230.318);
  --color-sky-400: oklch(74.6% 0.16 232.661);
  --color-sky-500: oklch(68.5% 0.169 237.323);
  --color-sky-600: oklch(58.8% 0.158 241.966);
  --color-sky-700: oklch(50% 0.134 242.749);
  --color-sky-800: oklch(44.3% 0.11 240.79);
  --color-sky-900: oklch(39.1% 0.09 240.876);
  --color-sky-950: oklch(29.3% 0.066 243.157);

  /* Blue */
  --color-blue-50: oklch(97% 0.014 254.604);
  --color-blue-100: oklch(93.2% 0.032 255.585);
  --color-blue-200: oklch(88.2% 0.059 254.128);
  --color-blue-300: oklch(80.9% 0.105 251.813);
  --color-blue-400: oklch(70.7% 0.165 254.624);
  --color-blue-500: oklch(62.3% 0.214 259.815);
  --color-blue-600: oklch(54.6% 0.245 262.881);
  --color-blue-700: oklch(48.8% 0.243 264.376);
  --color-blue-800: oklch(42.4% 0.199 265.638);
  --color-blue-900: oklch(37.9% 0.146 265.522);
  --color-blue-950: oklch(28.2% 0.091 267.935);

  /* Red */
  --color-red-50: oklch(97.1% 0.013 17.38);
  --color-red-100: oklch(93.6% 0.032 17.717);
  --color-red-200: oklch(88.5% 0.062 18.334);
  --color-red-300: oklch(80.8% 0.114 19.571);
  --color-red-400: oklch(70.4% 0.191 22.216);
  --color-red-500: oklch(63.7% 0.237 25.331);
  --color-red-600: oklch(57.7% 0.245 27.325);
  --color-red-700: oklch(50.5% 0.213 27.518);
  --color-red-800: oklch(44.4% 0.177 26.899);
  --color-red-900: oklch(39.6% 0.141 25.723);
  --color-red-950: oklch(25.8% 0.092 26.042);

  /* Green */
  --color-green-50: oklch(98.2% 0.018 155.826);
  --color-green-100: oklch(96.2% 0.044 156.743);
  --color-green-200: oklch(92.5% 0.084 155.995);
  --color-green-300: oklch(87.1% 0.15 154.449);
  --color-green-400: oklch(79.2% 0.209 151.711);
  --color-green-500: oklch(72.3% 0.219 149.579);
  --color-green-600: oklch(62.7% 0.194 149.214);
  --color-green-700: oklch(52.7% 0.154 150.069);
  --color-green-800: oklch(44.8% 0.119 151.328);
  --color-green-900: oklch(39.3% 0.095 152.535);
  --color-green-950: oklch(26.6% 0.065 152.934);

  /* Amber */
  --color-amber-50: oklch(98.7% 0.022 95.277);
  --color-amber-100: oklch(96.2% 0.059 95.617);
  --color-amber-200: oklch(92.4% 0.12 95.746);
  --color-amber-300: oklch(87.9% 0.169 91.605);
  --color-amber-400: oklch(82.8% 0.189 84.429);
  --color-amber-500: oklch(76.9% 0.188 70.08);
  --color-amber-600: oklch(66.6% 0.179 58.318);
  --color-amber-700: oklch(55.5% 0.163 48.998);
  --color-amber-800: oklch(47.3% 0.137 46.201);
  --color-amber-900: oklch(41.4% 0.112 45.904);
  --color-amber-950: oklch(27.9% 0.077 45.635);

  /* Indigo */
  --color-indigo-50: oklch(96.2% 0.018 272.314);
  --color-indigo-100: oklch(93% 0.034 272.788);
  --color-indigo-200: oklch(87% 0.065 274.039);
  --color-indigo-300: oklch(78.5% 0.115 274.713);
  --color-indigo-400: oklch(67.3% 0.182 276.935);
  --color-indigo-500: oklch(58.5% 0.233 277.117);
  --color-indigo-600: oklch(51.1% 0.262 276.966);
  --color-indigo-700: oklch(45.7% 0.24 277.023);
  --color-indigo-800: oklch(39.8% 0.195 277.366);
  --color-indigo-900: oklch(35.9% 0.144 278.697);
  --color-indigo-950: oklch(25.7% 0.09 281.288);

  /* Pink */
  --color-pink-50: oklch(97.1% 0.014 343.198);
  --color-pink-100: oklch(94.8% 0.028 342.258);
  --color-pink-200: oklch(89.9% 0.061 343.231);
  --color-pink-300: oklch(82.3% 0.12 346.018);
  --color-pink-400: oklch(71.8% 0.202 349.761);
  --color-pink-500: oklch(65.6% 0.241 354.308);
  --color-pink-600: oklch(59.2% 0.249 0.584);
  --color-pink-700: oklch(52.5% 0.223 3.958);
  --color-pink-800: oklch(45.9% 0.187 3.815);
  --color-pink-900: oklch(40.8% 0.153 2.432);
  --color-pink-950: oklch(28.4% 0.109 3.907);

  /* Violet */
  --color-violet-50: oklch(96.9% 0.016 293.756);
  --color-violet-100: oklch(94.3% 0.029 294.588);
  --color-violet-200: oklch(89.4% 0.057 293.283);
  --color-violet-300: oklch(81.1% 0.111 293.571);
  --color-violet-400: oklch(70.2% 0.183 293.541);
  --color-violet-500: oklch(60.6% 0.25 292.717);
  --color-violet-600: oklch(54.1% 0.281 293.009);
  --color-violet-700: oklch(49.1% 0.27 292.581);
  --color-violet-800: oklch(43.2% 0.232 292.759);
  --color-violet-900: oklch(38% 0.189 293.745);
  --color-violet-950: oklch(28.3% 0.141 291.089);

  /* Yellow */
  --color-yellow-50: oklch(98.7% 0.026 102.212);
  --color-yellow-100: oklch(97.3% 0.071 103.193);
  --color-yellow-200: oklch(94.5% 0.129 101.54);
  --color-yellow-300: oklch(90.5% 0.182 98.111);
  --color-yellow-400: oklch(85.2% 0.199 91.936);
  --color-yellow-500: oklch(79.5% 0.184 86.047);
  --color-yellow-600: oklch(68.1% 0.162 75.834);
  --color-yellow-700: oklch(55.4% 0.135 66.442);
  --color-yellow-800: oklch(47.6% 0.114 61.907);
  --color-yellow-900: oklch(42.1% 0.095 57.708);
  --color-yellow-950: oklch(28.6% 0.066 53.813);

  /* ──────────────────────────────────────────────────────────────────
   * Post-Task #32: complete the Tailwind v4 stock palette so a minimal
   * host (apps/web embed) provides every `--color-*` a widget bundle
   * can reach for. Pre-fix this file mirrored only 11 of v4's 22 stock
   * scales (audit Phase 2 finding #20); the 11 below close the gap.
   * Bytes are paid once by the host. Values track v4.3.0's `theme.css`.
   * ────────────────────────────────────────────────────────────────── */

  /* Orange */
  --color-orange-50: oklch(98% 0.016 73.684);
  --color-orange-100: oklch(95.4% 0.038 75.164);
  --color-orange-200: oklch(90.1% 0.076 70.697);
  --color-orange-300: oklch(83.7% 0.128 66.29);
  --color-orange-400: oklch(75% 0.183 55.934);
  --color-orange-500: oklch(70.5% 0.213 47.604);
  --color-orange-600: oklch(64.6% 0.222 41.116);
  --color-orange-700: oklch(55.3% 0.195 38.402);
  --color-orange-800: oklch(47% 0.157 37.304);
  --color-orange-900: oklch(40.8% 0.123 38.172);
  --color-orange-950: oklch(26.6% 0.079 36.259);

  /* Lime */
  --color-lime-50: oklch(98.6% 0.031 120.757);
  --color-lime-100: oklch(96.7% 0.067 122.328);
  --color-lime-200: oklch(93.8% 0.127 124.321);
  --color-lime-300: oklch(89.7% 0.196 126.665);
  --color-lime-400: oklch(84.1% 0.238 128.85);
  --color-lime-500: oklch(76.8% 0.233 130.85);
  --color-lime-600: oklch(64.8% 0.2 131.684);
  --color-lime-700: oklch(53.2% 0.157 131.589);
  --color-lime-800: oklch(45.3% 0.124 130.933);
  --color-lime-900: oklch(40.5% 0.101 131.063);
  --color-lime-950: oklch(27.4% 0.072 132.109);

  /* Emerald */
  --color-emerald-50: oklch(97.9% 0.021 166.113);
  --color-emerald-100: oklch(95% 0.052 163.051);
  --color-emerald-200: oklch(90.5% 0.093 164.15);
  --color-emerald-300: oklch(84.5% 0.143 164.978);
  --color-emerald-400: oklch(76.5% 0.177 163.223);
  --color-emerald-500: oklch(69.6% 0.17 162.48);
  --color-emerald-600: oklch(59.6% 0.145 163.225);
  --color-emerald-700: oklch(50.8% 0.118 165.612);
  --color-emerald-800: oklch(43.2% 0.095 166.913);
  --color-emerald-900: oklch(37.8% 0.077 168.94);
  --color-emerald-950: oklch(26.2% 0.051 172.552);

  /* Teal */
  --color-teal-50: oklch(98.4% 0.014 180.72);
  --color-teal-100: oklch(95.3% 0.051 180.801);
  --color-teal-200: oklch(91% 0.096 180.426);
  --color-teal-300: oklch(85.5% 0.138 181.071);
  --color-teal-400: oklch(77.7% 0.152 181.912);
  --color-teal-500: oklch(70.4% 0.14 182.503);
  --color-teal-600: oklch(60% 0.118 184.704);
  --color-teal-700: oklch(51.1% 0.096 186.391);
  --color-teal-800: oklch(43.7% 0.078 188.216);
  --color-teal-900: oklch(38.6% 0.063 188.416);
  --color-teal-950: oklch(27.7% 0.046 192.524);

  /* Cyan */
  --color-cyan-50: oklch(98.4% 0.019 200.873);
  --color-cyan-100: oklch(95.6% 0.045 203.388);
  --color-cyan-200: oklch(91.7% 0.08 205.041);
  --color-cyan-300: oklch(86.5% 0.127 207.078);
  --color-cyan-400: oklch(78.9% 0.154 211.53);
  --color-cyan-500: oklch(71.5% 0.143 215.221);
  --color-cyan-600: oklch(60.9% 0.126 221.723);
  --color-cyan-700: oklch(52% 0.105 223.128);
  --color-cyan-800: oklch(45% 0.085 224.283);
  --color-cyan-900: oklch(39.8% 0.07 227.392);
  --color-cyan-950: oklch(30.2% 0.056 229.695);

  /* Purple */
  --color-purple-50: oklch(97.7% 0.014 308.299);
  --color-purple-100: oklch(94.6% 0.033 307.174);
  --color-purple-200: oklch(90.2% 0.063 306.703);
  --color-purple-300: oklch(82.7% 0.119 306.383);
  --color-purple-400: oklch(71.4% 0.203 305.504);
  --color-purple-500: oklch(62.7% 0.265 303.9);
  --color-purple-600: oklch(55.8% 0.288 302.321);
  --color-purple-700: oklch(49.6% 0.265 301.924);
  --color-purple-800: oklch(43.8% 0.218 303.724);
  --color-purple-900: oklch(38.1% 0.176 304.987);
  --color-purple-950: oklch(29.1% 0.149 302.717);

  /* Fuchsia */
  --color-fuchsia-50: oklch(97.7% 0.017 320.058);
  --color-fuchsia-100: oklch(95.2% 0.037 318.852);
  --color-fuchsia-200: oklch(90.3% 0.076 319.62);
  --color-fuchsia-300: oklch(83.3% 0.145 321.434);
  --color-fuchsia-400: oklch(74% 0.238 322.16);
  --color-fuchsia-500: oklch(66.7% 0.295 322.15);
  --color-fuchsia-600: oklch(59.1% 0.293 322.896);
  --color-fuchsia-700: oklch(51.8% 0.253 323.949);
  --color-fuchsia-800: oklch(45.2% 0.211 324.591);
  --color-fuchsia-900: oklch(40.1% 0.17 325.612);
  --color-fuchsia-950: oklch(29.3% 0.136 325.661);

  /* Rose */
  --color-rose-50: oklch(96.9% 0.015 12.422);
  --color-rose-100: oklch(94.1% 0.03 12.58);
  --color-rose-200: oklch(89.2% 0.058 10.001);
  --color-rose-300: oklch(81% 0.117 11.638);
  --color-rose-400: oklch(71.2% 0.194 13.428);
  --color-rose-500: oklch(64.5% 0.246 16.439);
  --color-rose-600: oklch(58.6% 0.253 17.585);
  --color-rose-700: oklch(51.4% 0.222 16.935);
  --color-rose-800: oklch(45.5% 0.188 13.697);
  --color-rose-900: oklch(41% 0.159 10.272);
  --color-rose-950: oklch(27.1% 0.105 12.094);

  /* Gray — theme-agnostic (v4 stock; no dark override). */
  --color-gray-50: oklch(98.5% 0.002 247.839);
  --color-gray-100: oklch(96.7% 0.003 264.542);
  --color-gray-200: oklch(92.8% 0.006 264.531);
  --color-gray-300: oklch(87.2% 0.01 258.338);
  --color-gray-400: oklch(70.7% 0.022 261.325);
  --color-gray-500: oklch(55.1% 0.027 264.364);
  --color-gray-600: oklch(44.6% 0.03 256.802);
  --color-gray-700: oklch(37.3% 0.034 259.733);
  --color-gray-800: oklch(27.8% 0.033 256.848);
  --color-gray-900: oklch(21% 0.034 264.665);
  --color-gray-950: oklch(13% 0.028 261.692);

  /* Zinc — theme-agnostic (v4 stock; no dark override). */
  --color-zinc-50: oklch(98.5% 0 0);
  --color-zinc-100: oklch(96.7% 0.001 286.375);
  --color-zinc-200: oklch(92% 0.004 286.32);
  --color-zinc-300: oklch(87.1% 0.006 286.286);
  --color-zinc-400: oklch(70.5% 0.015 286.067);
  --color-zinc-500: oklch(55.2% 0.016 285.938);
  --color-zinc-600: oklch(44.2% 0.017 285.786);
  --color-zinc-700: oklch(37% 0.013 285.805);
  --color-zinc-800: oklch(27.4% 0.006 286.033);
  --color-zinc-900: oklch(21% 0.006 285.885);
  --color-zinc-950: oklch(14.1% 0.005 285.823);

  /* Stone — theme-agnostic (v4 stock; no dark override). */
  --color-stone-50: oklch(98.5% 0.001 106.423);
  --color-stone-100: oklch(97% 0.001 106.424);
  --color-stone-200: oklch(92.3% 0.003 48.717);
  --color-stone-300: oklch(86.9% 0.005 56.366);
  --color-stone-400: oklch(70.9% 0.01 56.259);
  --color-stone-500: oklch(55.3% 0.013 58.071);
  --color-stone-600: oklch(44.4% 0.011 73.639);
  --color-stone-700: oklch(37.4% 0.01 67.558);
  --color-stone-800: oklch(26.8% 0.007 34.298);
  --color-stone-900: oklch(21.6% 0.006 56.043);
  --color-stone-950: oklch(14.7% 0.004 49.25);
}

/* ─────────────────────────────────────────────────────────────────
 * Tailwind v4 @theme consumption aliases — bridge.
 *
 * Surfaces using Tailwind v4 with `@theme { --color-* }` previously
 * had to declare a parallel palette in their own CSS to make
 * utilities like `bg-foreground` / `text-muted-foreground` /
 * `border-border` work. With the bridge below, any surface that
 * `@import`s this stylesheet (directly via JS import or via the
 * canonical `<link>`) gets the `--color-*` names pointing at our
 * `--tck-*` tokens.
 *
 * Decision 1(a) from KC 3 inventory (architect's mountHost design,
 * 2026-05-19): bridge in canonical CSS instead of forcing each
 * surface to redeclare an @theme block. Tokens stay single-source
 * (`--tck-*` are canonical); aliases are just window-dressing for
 * the Tailwind-conventional naming.
 *
 * Notably NOT bridged: `--color-accent*`, `--color-destructive*`,
 * `--color-primary*` (workbench / app-chrome specific; no TCK
 * equivalent), and `--radius-*` (different value scales between
 * Tailwind stock and TCK; unification routed to a separate design-
 * system review per Task #36 / #38).
 * ───────────────────────────────────────────────────────────────── */

:where([data-tck-host]) {
  --color-background: var(--tck-bg);
  --color-foreground: var(--tck-fg);
  --color-muted: var(--tck-muted);
  --color-muted-foreground: var(--tck-muted-fg);
  --color-border: var(--tck-border);
  --color-ring: var(--tck-ring);
}

:where([data-tck-host]) {
  color: var(--tck-fg);
}

/* ─────────────────────────────────────────────────────────────────
 * Feed-group header chrome
 *
 * The iframe canvas renders feed batches as vertically-stacked
 * cards with a group header above each batch reading
 *
 *     <kind> · <when>     e.g. "Morning brief · Today, 8:00"
 *
 * The header is a flex row of three elements:
 *
 *     .tck-feed-group-header
 *       └── .tck-feed-group-header__kind       (13px / 600 weight)
 *       └── .tck-feed-group-header__divider    ("·", 400 weight)
 *       └── .tck-feed-group-header__when       (12px / 400 weight)
 *
 * Three-tier hierarchy reads left-to-right: kind first (primary
 * text token), then drift through the divider (tertiary), settling
 * on when (secondary). Tabular-num figures on the row keep digits
 * width-stable across batches so "8:00" and "11:30" don't reflow
 * the layout when the data updates.
 *
 * The hierarchy is implemented via opacity-less colored text rather
 * than `opacity` because `opacity` compounds with the iframe's
 * resolved alpha against the dawn-gradient backdrop and produces a
 * muddy mid-tone. Per-tier OKLCH colors hold their hue/lightness
 * regardless of backdrop.
 * ───────────────────────────────────────────────────────────────── */

.tck-feed-group-header {
  display: flex;
  align-items: baseline;
  gap: 0.375rem; /* 6px */
  padding: 0 0.25rem; /* slight inset from card edges */
  font-family: var(--font-sans);
  font-feature-settings: 'tnum';
}

.tck-feed-group-header__kind {
  font-size: 0.8125rem; /* 13px */
  font-weight: 600;
  letter-spacing: -0.01em;
  color: var(--tck-text-primary);
}

.tck-feed-group-header__divider {
  font-weight: 400;
  margin: 0 0.125rem;
  color: var(--tck-text-tertiary);
}

.tck-feed-group-header__when {
  font-size: 0.75rem; /* 12px */
  font-weight: 400;
  color: var(--tck-text-secondary);
}

/* Anchor fade-in: when boot.ts resolves `?batchId=<id>` and
   `scrollIntoView()` settles, it flips `data-anchored="true"` on
   the matching group header. The starting `opacity: 0` is owned
   by the class-based rule below (not by an inline style boot.ts
   would have to set), so cascade hygiene stays clean:
   `[data-anchored='true']` lights up both `opacity: 0` (initial)
   AND the animation that lerps to 1. `forwards` holds opacity 1
   after the keyframe finishes.

   Easing is a "ease-out-expo"-ish bezier — content settles into
   place rather than ramping linearly. 220ms keeps the fade
   perceptible without delaying first-meaningful-paint.

   prefers-reduced-motion override has equal specificity to the
   active rule (one class + one attribute selector each), so
   source order alone — not !important — promotes `opacity: 1`
   over the initial `opacity: 0` and skips the keyframe. The
   stranded-invisible regression that would happen if the
   override only said `animation: none` is closed by the
   explicit `opacity: 1`. */
@keyframes tck-feed-anchor-fade-in {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}

.tck-feed-group-header[data-anchored='true'] {
  opacity: 0;
  animation: tck-feed-anchor-fade-in 220ms cubic-bezier(0.16, 1, 0.3, 1) forwards;
}

@media (prefers-reduced-motion: reduce) {
  .tck-feed-group-header[data-anchored='true'] {
    opacity: 1;
    animation: none;
  }
}

/* ─────────────────────────────────────────────────────────────────
 * Forward-declared canvas-state chrome
 *
 * Loading, empty, and error states for the feed canvas. boot.ts
 * renders DOM with these class names; the rules below carry the
 * shape, motion, and color so boot.ts stays declarative.
 *
 * These rules are dead until boot.ts emits the matching DOM —
 * intentional. Forward-declaring the contract here means the
 * style + JSX adoption can land in two separate PRs without an
 * intermediate broken state.
 *
 * Design ownership: `.tck-feed-loading` (skeleton breathing
 * pulse), `.tck-feed-empty` (passive wait-state card),
 * `.tck-feed-error` (error-state card with retry CTA). Each gets
 * a glass-card surface via the same `--tck-card-*` tokens the
 * per-tile chrome reads — visual coherence across states.
 * ───────────────────────────────────────────────────────────────── */

/* Skeleton pulse — 2s ease-in-out infinite, "ambient breathing"
   rather than nervous flicker. Opacity range 0.35 → 0.65 → 0.35
   keeps the bars visible enough to read as placeholders without
   competing with real content above/below. */
@keyframes tck-feed-skeleton-pulse {
  0%,
  100% {
    opacity: 0.35;
  }
  50% {
    opacity: 0.65;
  }
}

.tck-feed-loading {
  display: flex;
  flex-direction: column;
  gap: 2rem; /* 32px between batches */
}

.tck-feed-loading__batch {
  display: flex;
  flex-direction: column;
  gap: 0.5rem; /* 8px header → first tile */
}

.tck-feed-loading__header-bar {
  width: 9rem;
  height: 0.75rem;
  border-radius: 0.25rem;
  background: var(--tck-color-bg-muted);
  animation: tck-feed-skeleton-pulse 2s ease-in-out infinite;
}

.tck-feed-loading__tile {
  width: 100%;
  height: 6rem;
  border-radius: 1rem;
  background: var(--tck-color-bg-muted);
  animation: tck-feed-skeleton-pulse 2s ease-in-out infinite;
  margin-top: 1rem; /* 16px between tiles within a batch */
}

.tck-feed-loading__tile:first-of-type {
  margin-top: 0;
}

@media (prefers-reduced-motion: reduce) {
  .tck-feed-loading__header-bar,
  .tck-feed-loading__tile {
    animation: none;
    opacity: 0.5; /* hold the mid-pulse value so the skeleton stays
                     visible without breathing */
  }
}

/* Centered single-card surface shared by empty + error states.
   Both render one glass card at max-width 24rem (384px); only
   the content inside differs. Reuses card tokens so dark mode
   flips automatically. */
.tck-feed-empty,
.tck-feed-error {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: 0.75rem;
  max-width: 24rem;
  margin: 4rem auto;
  padding: 2rem;
  background: var(--tck-card-bg);
  backdrop-filter: var(--tck-card-backdrop-filter);
  -webkit-backdrop-filter: var(--tck-card-backdrop-filter);
  border-radius: var(--tck-card-radius);
  box-shadow: var(--tck-card-shadow);
}

.tck-feed-empty__title,
.tck-feed-error__title {
  font-size: 0.9375rem; /* 15px */
  font-weight: 600;
  color: var(--tck-text-primary);
  letter-spacing: -0.01em;
}

.tck-feed-empty__body,
.tck-feed-error__body {
  font-size: 0.8125rem; /* 13px */
  color: var(--tck-text-secondary);
  line-height: 1.5;
}

.tck-feed-error__icon {
  width: 1.5rem; /* 24px */
  height: 1.5rem;
  color: var(--tck-color-text-warning);
}

.tck-feed-error__actions {
  display: flex;
  gap: 0.5rem;
  margin-top: 0.5rem;
}
