/* =====================================================================
   Harness Lab app: design tokens (b35, the Night Shift kit).
   Ported from .claude/skills/night-shift-ui/tokens.css for a no-build app: plain custom properties and plain classes, with no
   @theme, @utility, @layer or @custom-variant. A test (test_app_design.py) compares every kit token with the skill's file, so
   a kit update is a diff. `kb regen` copies this file into views/app/; index.html loads it after theme.js and before app.css.

   THIS IS THE ONLY FILE THAT MAY HOLD A COLOUR LITERAL (hex, rgb, hsl, oklch). app.css, app.js, live.js and theme.js use var().
   Light is :root. Dark is set twice, as before: under the system setting (unless ?theme=light / the saved choice says light) and
   under data-theme="dark". The two dark blocks are identical; a test checks it.
   Not ported on purpose: the kit's shadcn names (--card, --popover, --muted, --secondary, --accent, --sidebar-*). Use --surface-1/2/3
   and --muted-foreground. The app's old names (--ink, --paper, --signal ...) are gone; a design test says none is used.
   ===================================================================== */

/* ---------- fonts (SPEC 13.2: IBM Plex Sans and IBM Plex Mono 400, SIL OFL 1.1, bundled; paths are relative so file:// works) ---------- */
/* Latin only. Persian and Arabic are not in them, so those letters use the system font. */
@font-face {
  font-family: "IBM Plex Sans"; font-style: normal; font-weight: 100 700; font-display: swap;
  src: url("fonts/ibm-plex-sans-latin-wght.woff2") format("woff2");
}
@font-face {
  font-family: "IBM Plex Mono"; font-style: normal; font-weight: 400; font-display: swap;
  src: url("fonts/ibm-plex-mono-latin-400.woff2") format("woff2");
}

/* ---------- light (the default) and everything that does not change with the mode ---------- */
:root {
  color-scheme: light;

  /* type: the sans stack keeps the system fonts after Plex for Persian and Arabic (b26); the scale is the kit's */
  --font-sans: "IBM Plex Sans", system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  --font-display: var(--font-sans);
  --font-mono: "IBM Plex Mono", ui-monospace, "SF Mono", Consolas, monospace;
  --text-2xs: 0.6875rem;  --text-2xs--line-height: 1rem;
  --text-xs: 0.75rem;     --text-xs--line-height: 1.125rem;
  --text-sm: 0.8125rem;   --text-sm--line-height: 1.25rem;
  --text-base: 0.9375rem; --text-base--line-height: 1.5rem;
  --text-lg: 1.125rem;    --text-lg--line-height: 1.75rem;
  --text-xl: 1.375rem;    --text-xl--line-height: 1.875rem;
  --text-2xl: 1.75rem;    --text-2xl--line-height: 2.125rem;
  --text-3xl: 2.25rem;    --text-3xl--line-height: 2.5rem;
  --text-4xl: 3rem;       --text-4xl--line-height: 3.125rem;
  --text-5xl: 4rem;       --text-5xl--line-height: 4rem;

  /* radius scale: badges 6, buttons and inputs 8, cards 12, dialogs and the chat box 16, hero panels 24 */
  --radius-sm: 6px; --radius-md: 8px; --radius-lg: 12px; --radius-xl: 16px; --radius-2xl: 24px;

  /* easing and duration */
  --ease-out-quart: cubic-bezier(0.25, 1, 0.5, 1);
  --ease-out-expo: cubic-bezier(0.16, 1, 0.3, 1);
  --ease-in-out-cubic: cubic-bezier(0.65, 0, 0.35, 1);
  --animate-live: live 2.4s var(--ease-in-out-cubic) infinite;

  /* brand gradients: periwinkle to cyan for brand moments, cyan to periwinkle for the AI at work */
  --gradient-signal: linear-gradient(135deg in oklch, var(--primary), var(--ai));
  --gradient-aura: linear-gradient(135deg in oklch, var(--ai), var(--primary));

  /* ---- palette, light (kit section 1; the hex in the comments is the sRGB fallback) ---- */
  --highlight: oklch(1 0 0 / 0.7);           /* 1px inner top edge on raised surfaces */
  /* Surfaces */
  --background: oklch(0.975 0.008 277); /* #f5f6fd */
  --bg-sunken: oklch(0.959 0.010 277); /* #eff1f8 */
  --code-bg: oklch(0.955 0.011 277); /* #eef0f7 */
  --surface-1: oklch(0.997 0.001 277); /* #fefeff */
  --surface-2: oklch(1.000 0.000 277); /* #ffffff */
  --surface-3: oklch(0.945 0.011 277); /* #ebecf5 */
  /* Text */
  --foreground: oklch(0.215 0.030 277); /* #161827 */
  --muted-foreground: oklch(0.420 0.025 277); /* #494c5b */
  --subtle-foreground: oklch(0.520 0.024 277); /* #656877 */
  /* Primary action */
  --primary: oklch(0.520 0.190 268); /* #3b5bd4 */
  --primary-hover: oklch(0.460 0.190 268); /* #2d48c0 */
  --primary-foreground: oklch(1.000 0.000 0); /* #ffffff */
  --primary-text: oklch(0.500 0.190 268); /* #3655cd */
  --primary-soft: oklch(0.520 0.190 268 / 0.1);
  /* AI / brain */
  --ai: oklch(0.600 0.104 210); /* #0090a2 */
  --ai-solid: oklch(0.550 0.097 215); /* #007f95 */
  --ai-solid-foreground: oklch(1.000 0.000 0); /* #ffffff */
  --ai-text: oklch(0.480 0.085 215); /* #00697b */
  --ai-soft: oklch(0.550 0.097 215 / 0.09);
  --ai-glow: oklch(0.600 0.104 210 / 0.22);
  /* Status */
  --success: oklch(0.620 0.150 152); /* #259f56 */
  --success-text: oklch(0.470 0.120 152); /* #0a6d37 */
  --success-soft: oklch(0.620 0.150 152 / 0.12);
  --warning: oklch(0.760 0.160 75); /* #eba002 */
  --warning-text: oklch(0.500 0.110 65); /* #8d5406 */
  --warning-soft: oklch(0.760 0.160 75 / 0.16);
  --destructive: oklch(0.600 0.200 25); /* #de3b3d */
  --destructive-text: oklch(0.500 0.170 25); /* #b02a2d */
  --destructive-soft: oklch(0.600 0.200 25 / 0.1);
  /* Lines */
  --border: oklch(0.250 0.034 277 / 0.12);
  --border-strong: oklch(0.250 0.034 277 / 0.2);
  --input: oklch(0.620 0.029 277); /* #818598 */
  --ring: oklch(0.500 0.190 268); /* #3655cd */
  /* Code */
  --syn-keyword: oklch(0.500 0.200 305); /* #7f36bc */
  --syn-string: oklch(0.500 0.130 145); /* #27762f */
  --syn-function: oklch(0.500 0.170 262); /* #285cc2 */
  --syn-number: oklch(0.540 0.143 50); /* #ad5000 */
  --syn-type: oklch(0.500 0.086 210); /* #00707e */
  --syn-comment: oklch(0.530 0.030 277); /* #676b7e */
  /* Ribbons and highlights */
  --ribbon: oklch(0.580 0.190 355); /* #ca3a80 */
  --ribbon-foreground: oklch(1.000 0.000 0); /* #ffffff */
  --ribbon-text: oklch(0.520 0.180 355); /* #b12b6e */
  --ribbon-soft: oklch(0.580 0.190 355 / 0.1);
  /* Harness identity colors (one per harness, for dots, tags, chart series) */
  --tool-1: oklch(0.560 0.150 255); /* #2d74ca */
  --tool-2: oklch(0.560 0.097 190); /* #008681 */
  --tool-3: oklch(0.560 0.150 45); /* #b95115 */
  --tool-4: oklch(0.560 0.150 300); /* #835cbe */
  --tool-5: oklch(0.560 0.150 145); /* #2b8a36 */
  --tool-6: oklch(0.560 0.150 350); /* #b24981 */
  --chart-1: var(--primary);
  --chart-2: var(--ai);
  --chart-3: var(--ribbon);
  --chart-4: var(--success);
  --chart-5: var(--warning);
  /* Motion (see Motion section) */
  --chat-bg: var(--bg-sunken);
  --beam-rest: var(--input);
  --beam-tail: var(--primary);
  --beam-head: var(--ai);
  --beam-spark: var(--ai-text);
  --burst: color-mix(in oklch, var(--primary) 50%, transparent);
  --sheen: oklch(1 0 0 / 0.35);
  --lift-edge: color-mix(in oklch, var(--primary) 45%, transparent);

  /* ---- depth, glows and light (kit section 3) ---- */
  --dur-fast: 120ms;   /* hover, press */
  --dur-base: 180ms;   /* menus, tooltips, tabs */
  --dur-slow: 280ms;   /* dialogs, sheets */
  --elevation-card: inset 0 1px 0 0 var(--highlight), 0 1px 2px 0 oklch(0.2 0.02 260 / 0.06), 0 1px 1px 0 oklch(0.2 0.02 260 / 0.04);
  --elevation-pop: 0 12px 32px -10px oklch(0.2 0.02 260 / 0.22), 0 2px 6px -2px oklch(0.2 0.02 260 / 0.12);
  --elevation-modal: 0 24px 64px -16px oklch(0.2 0.02 260 / 0.3);
  --scrim: oklch(0.2 0.02 260 / 0.38);
  --glow-primary: 0 0 0 1px color-mix(in oklch, var(--primary) 40%, transparent), 0 6px 24px -6px color-mix(in oklch, var(--primary) 45%, transparent);
  --glow-ai: 0 0 0 1px color-mix(in oklch, var(--ai) 40%, transparent), 0 6px 24px -6px var(--ai-glow);
  --gradient-surface: linear-gradient(180deg, color-mix(in oklch, var(--foreground) 2%, transparent), transparent 40%);
  --glow-hero: radial-gradient(60% 55% at 50% 0%, color-mix(in oklch, var(--primary) 14%, transparent), transparent 70%),
               radial-gradient(40% 40% at 85% 10%, color-mix(in oklch, var(--ai) 10%, transparent), transparent 70%);

  /* legacy (b35): hues the app keeps until Phases 3 and 5 replace them. The layer ramp L0 to L7 is the band's left edge and the
     tile's top rule, never a text colour; the badges are the Explore banner's (b32), with --on-badge letters (4.5 : 1) */
  --layer-0: #3F2E9E; --layer-1: #3A44B5; --layer-2: #2F5FC2; --layer-3: #1F78C0;
  --layer-4: #1A8DAE; --layer-5: #14968F; --layer-6: #1C9A6C; --layer-7: #3C9A3F;
  --badge-0: #4A3AB0; --badge-1: #3640AE; --badge-2: #2757BC; --badge-3: #1A6DA8;
  --badge-4: #12708A; --badge-5: #0F7A70; --badge-6: #17714F; --badge-7: #2F7A33; --on-badge: #FFFFFF;
  --tint: 7%;
}

/* ---------- dark: the system setting, unless the page is set to light ---------- */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    color-scheme: dark;
    --highlight: oklch(1 0 0 / 0.06);
    /* Surfaces */
    --background: oklch(0.190 0.032 277); /* #101222 */
    --bg-sunken: oklch(0.164 0.029 277); /* #0b0d1a */
    --code-bg: oklch(0.172 0.030 277); /* #0c0e1d */
    --surface-1: oklch(0.226 0.035 277); /* #181a2c */
    --surface-2: oklch(0.260 0.036 277); /* #202235 */
    --surface-3: oklch(0.298 0.037 277); /* #282c40 */
    /* Text */
    --foreground: oklch(0.965 0.012 277); /* #f1f3fc */
    --muted-foreground: oklch(0.805 0.022 277); /* #bbbece */
    --subtle-foreground: oklch(0.690 0.027 277); /* #979aac */
    /* Primary action */
    --primary: oklch(0.760 0.122 268); /* #90aeff */
    --primary-hover: oklch(0.820 0.089 268); /* #abc3ff */
    --primary-foreground: oklch(0.180 0.030 277); /* #0e101f */
    --primary-text: oklch(0.800 0.100 268); /* #a2bcff */
    --primary-soft: oklch(0.760 0.122 268 / 0.14);
    /* AI / brain */
    --ai: oklch(0.820 0.110 208); /* #5fd8e9 */
    --ai-solid: oklch(0.820 0.110 208); /* #5fd8e9 */
    --ai-solid-foreground: oklch(0.180 0.030 277); /* #0e101f */
    --ai-text: oklch(0.850 0.090 208); /* #82dfec */
    --ai-soft: oklch(0.820 0.110 208 / 0.14);
    --ai-glow: oklch(0.820 0.110 208 / 0.35);
    /* Status */
    --success: oklch(0.760 0.160 152); /* #52cd7d */
    --success-text: oklch(0.820 0.130 152); /* #7fdc9a */
    --success-soft: oklch(0.760 0.160 152 / 0.14);
    --warning: oklch(0.830 0.150 80); /* #fabb41 */
    --warning-text: oklch(0.860 0.130 82); /* #fbc865 */
    --warning-soft: oklch(0.830 0.150 80 / 0.14);
    --destructive: oklch(0.700 0.180 24); /* #fa6865 */
    --destructive-text: oklch(0.800 0.114 24); /* #ffa09a */
    --destructive-soft: oklch(0.700 0.180 24 / 0.14);
    /* Lines */
    --border: oklch(1.000 0.000 0 / 0.09);
    --border-strong: oklch(1.000 0.000 0 / 0.15);
    --input: oklch(0.520 0.048 277); /* #616785 */
    --ring: oklch(0.760 0.122 268); /* #90aeff */
    /* Code */
    --syn-keyword: oklch(0.760 0.140 305); /* #c699f8 */
    --syn-string: oklch(0.820 0.130 135); /* #9fd780 */
    --syn-function: oklch(0.760 0.120 262); /* #87b1fd */
    --syn-number: oklch(0.800 0.120 55); /* #f9a870 */
    --syn-type: oklch(0.820 0.100 205); /* #6cd7e3 */
    --syn-comment: oklch(0.660 0.035 277); /* #8c91a8 */
    /* Ribbons and highlights */
    --ribbon: oklch(0.770 0.130 352); /* #f390bd */
    --ribbon-foreground: oklch(0.180 0.030 277); /* #0e101f */
    --ribbon-text: oklch(0.810 0.110 352); /* #f8a3c8 */
    --ribbon-soft: oklch(0.770 0.130 352 / 0.14);
    /* Harness identity colors (one per harness, for dots, tags, chart series) */
    --tool-1: oklch(0.740 0.136 255); /* #6dadff */
    --tool-2: oklch(0.740 0.128 190); /* #00c4bd */
    --tool-3: oklch(0.740 0.150 45); /* #f78955 */
    --tool-4: oklch(0.740 0.150 300); /* #ba93fb */
    --tool-5: oklch(0.740 0.150 145); /* #68c36d */
    --tool-6: oklch(0.740 0.150 350); /* #f080b8 */
    /* Motion (see Motion section) */
    --beam-spark: oklch(0.95 0.045 208);
    --burst: color-mix(in oklch, var(--primary) 55%, transparent);
    --elevation-card: inset 0 1px 0 0 var(--highlight), 0 1px 2px 0 oklch(0 0 0 / 0.3);
    --elevation-pop: inset 0 1px 0 0 var(--highlight), 0 12px 32px -8px oklch(0 0 0 / 0.6), 0 2px 6px -2px oklch(0 0 0 / 0.4);
    --elevation-modal: inset 0 1px 0 0 var(--highlight), 0 24px 64px -12px oklch(0 0 0 / 0.7);
    --scrim: color-mix(in oklch, var(--background) 72%, transparent);
    --glow-primary: 0 0 0 1px color-mix(in oklch, var(--primary) 35%, transparent), 0 6px 24px -6px color-mix(in oklch, var(--primary) 45%, transparent);
    --glow-ai: 0 0 0 1px color-mix(in oklch, var(--ai) 35%, transparent), 0 6px 24px -6px var(--ai-glow);
    --gradient-surface: linear-gradient(180deg, oklch(1 0 0 / 0.035), oklch(1 0 0 / 0) 40%);
    --glow-hero: radial-gradient(60% 55% at 50% 0%, color-mix(in oklch, var(--primary) 16%, transparent), transparent 70%),
                 radial-gradient(40% 40% at 85% 10%, color-mix(in oklch, var(--ai) 12%, transparent), transparent 70%);
    --layer-0: #8F84F0; --layer-1: #8394F5; --layer-2: #7AA4F7; --layer-3: #6BB6F0;
    --layer-4: #5CC6DE; --layer-5: #54CDBC; --layer-6: #5CD296; --layer-7: #8ED06A;
    --badge-0: #8F84F0; --badge-1: #8394F5; --badge-2: #7AA4F7; --badge-3: #6BB6F0;
    --badge-4: #5CC6DE; --badge-5: #54CDBC; --badge-6: #5CD296; --badge-7: #8ED06A; --on-badge: #0D1424;
    --tint: 12%;
  }
}
/* ---------- dark: ?theme=dark or the saved choice ---------- */
:root[data-theme="dark"] {
  color-scheme: dark;
  --highlight: oklch(1 0 0 / 0.06);
  /* Surfaces */
  --background: oklch(0.190 0.032 277); /* #101222 */
  --bg-sunken: oklch(0.164 0.029 277); /* #0b0d1a */
  --code-bg: oklch(0.172 0.030 277); /* #0c0e1d */
  --surface-1: oklch(0.226 0.035 277); /* #181a2c */
  --surface-2: oklch(0.260 0.036 277); /* #202235 */
  --surface-3: oklch(0.298 0.037 277); /* #282c40 */
  /* Text */
  --foreground: oklch(0.965 0.012 277); /* #f1f3fc */
  --muted-foreground: oklch(0.805 0.022 277); /* #bbbece */
  --subtle-foreground: oklch(0.690 0.027 277); /* #979aac */
  /* Primary action */
  --primary: oklch(0.760 0.122 268); /* #90aeff */
  --primary-hover: oklch(0.820 0.089 268); /* #abc3ff */
  --primary-foreground: oklch(0.180 0.030 277); /* #0e101f */
  --primary-text: oklch(0.800 0.100 268); /* #a2bcff */
  --primary-soft: oklch(0.760 0.122 268 / 0.14);
  /* AI / brain */
  --ai: oklch(0.820 0.110 208); /* #5fd8e9 */
  --ai-solid: oklch(0.820 0.110 208); /* #5fd8e9 */
  --ai-solid-foreground: oklch(0.180 0.030 277); /* #0e101f */
  --ai-text: oklch(0.850 0.090 208); /* #82dfec */
  --ai-soft: oklch(0.820 0.110 208 / 0.14);
  --ai-glow: oklch(0.820 0.110 208 / 0.35);
  /* Status */
  --success: oklch(0.760 0.160 152); /* #52cd7d */
  --success-text: oklch(0.820 0.130 152); /* #7fdc9a */
  --success-soft: oklch(0.760 0.160 152 / 0.14);
  --warning: oklch(0.830 0.150 80); /* #fabb41 */
  --warning-text: oklch(0.860 0.130 82); /* #fbc865 */
  --warning-soft: oklch(0.830 0.150 80 / 0.14);
  --destructive: oklch(0.700 0.180 24); /* #fa6865 */
  --destructive-text: oklch(0.800 0.114 24); /* #ffa09a */
  --destructive-soft: oklch(0.700 0.180 24 / 0.14);
  /* Lines */
  --border: oklch(1.000 0.000 0 / 0.09);
  --border-strong: oklch(1.000 0.000 0 / 0.15);
  --input: oklch(0.520 0.048 277); /* #616785 */
  --ring: oklch(0.760 0.122 268); /* #90aeff */
  /* Code */
  --syn-keyword: oklch(0.760 0.140 305); /* #c699f8 */
  --syn-string: oklch(0.820 0.130 135); /* #9fd780 */
  --syn-function: oklch(0.760 0.120 262); /* #87b1fd */
  --syn-number: oklch(0.800 0.120 55); /* #f9a870 */
  --syn-type: oklch(0.820 0.100 205); /* #6cd7e3 */
  --syn-comment: oklch(0.660 0.035 277); /* #8c91a8 */
  /* Ribbons and highlights */
  --ribbon: oklch(0.770 0.130 352); /* #f390bd */
  --ribbon-foreground: oklch(0.180 0.030 277); /* #0e101f */
  --ribbon-text: oklch(0.810 0.110 352); /* #f8a3c8 */
  --ribbon-soft: oklch(0.770 0.130 352 / 0.14);
  /* Harness identity colors (one per harness, for dots, tags, chart series) */
  --tool-1: oklch(0.740 0.136 255); /* #6dadff */
  --tool-2: oklch(0.740 0.128 190); /* #00c4bd */
  --tool-3: oklch(0.740 0.150 45); /* #f78955 */
  --tool-4: oklch(0.740 0.150 300); /* #ba93fb */
  --tool-5: oklch(0.740 0.150 145); /* #68c36d */
  --tool-6: oklch(0.740 0.150 350); /* #f080b8 */
  /* Motion (see Motion section) */
  --beam-spark: oklch(0.95 0.045 208);
  --burst: color-mix(in oklch, var(--primary) 55%, transparent);
  --elevation-card: inset 0 1px 0 0 var(--highlight), 0 1px 2px 0 oklch(0 0 0 / 0.3);
  --elevation-pop: inset 0 1px 0 0 var(--highlight), 0 12px 32px -8px oklch(0 0 0 / 0.6), 0 2px 6px -2px oklch(0 0 0 / 0.4);
  --elevation-modal: inset 0 1px 0 0 var(--highlight), 0 24px 64px -12px oklch(0 0 0 / 0.7);
  --scrim: color-mix(in oklch, var(--background) 72%, transparent);
  --glow-primary: 0 0 0 1px color-mix(in oklch, var(--primary) 35%, transparent), 0 6px 24px -6px color-mix(in oklch, var(--primary) 45%, transparent);
  --glow-ai: 0 0 0 1px color-mix(in oklch, var(--ai) 35%, transparent), 0 6px 24px -6px var(--ai-glow);
  --gradient-surface: linear-gradient(180deg, oklch(1 0 0 / 0.035), oklch(1 0 0 / 0) 40%);
  --glow-hero: radial-gradient(60% 55% at 50% 0%, color-mix(in oklch, var(--primary) 16%, transparent), transparent 70%),
               radial-gradient(40% 40% at 85% 10%, color-mix(in oklch, var(--ai) 12%, transparent), transparent 70%);
  --layer-0: #8F84F0; --layer-1: #8394F5; --layer-2: #7AA4F7; --layer-3: #6BB6F0;
  --layer-4: #5CC6DE; --layer-5: #54CDBC; --layer-6: #5CD296; --layer-7: #8ED06A;
  --badge-0: #8F84F0; --badge-1: #8394F5; --badge-2: #7AA4F7; --badge-3: #6BB6F0;
  --badge-4: #5CC6DE; --badge-5: #54CDBC; --badge-6: #5CD296; --badge-7: #8ED06A; --on-badge: #0D1424;
  --tint: 12%;
}

/* ---------- the kit's signature classes (kit section 3; its @utility blocks as plain classes). Use sparingly (SKILL.md "Light"). ---------- */
.surface-lit { background-image: var(--gradient-surface); box-shadow: var(--elevation-card); }
.border-aura {
  border: 1px solid transparent;
  background: linear-gradient(var(--surface-1), var(--surface-1)) padding-box, var(--gradient-aura) border-box;
}
.border-signal {
  border: 1px solid transparent;
  background: linear-gradient(var(--surface-1), var(--surface-1)) padding-box, var(--gradient-signal) border-box;
}
.text-signal {   /* logo / wordmark only, never headings */
  background: var(--gradient-signal);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}
.glow-hero { background-image: var(--glow-hero); }
.bg-dots {
  background-image: radial-gradient(color-mix(in oklch, var(--foreground) 9%, transparent) 1px, transparent 1px);
  background-size: 22px 22px;
  mask-image: radial-gradient(70% 60% at 50% 30%, black, transparent);
}
.grain {
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='160' height='160'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='.9' numOctaves='3' stitchTiles='stitch'/><feColorMatrix values='0 0 0 0 1  0 0 0 0 1  0 0 0 0 1  0 0 0 .5 0'/></filter><rect width='100%' height='100%' filter='url(%23n)'/></svg>");
  opacity: 0.035;
  pointer-events: none;
  mix-blend-mode: overlay;
}
.display-hero {
  font-family: var(--font-display);
  font-size: clamp(2.5rem, 5.5vw, 4rem);
  line-height: 1.02;
  font-weight: 720;
  font-stretch: var(--display-stretch, 100%);
  letter-spacing: -0.035em;
  text-wrap: balance;
}
.display-section {
  font-family: var(--font-display);
  font-size: var(--text-3xl);
  line-height: 1.1;
  font-weight: 680;
  font-stretch: var(--display-stretch-2, 100%);
  letter-spacing: -0.025em;
  text-wrap: balance;
}
.title-wide { font-stretch: var(--title-stretch, 100%); letter-spacing: -0.02em; }
.text-thinking {   /* AI text while it is actively working */
  background: linear-gradient(90deg, var(--foreground) 0%, var(--ai-text) 40%, var(--foreground) 80%);
  background-size: 200% 100%;
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  animation: thinking 2.4s linear infinite;
}
@keyframes thinking { from { background-position: 100% 0; } to { background-position: -100% 0; } }
.nums { font-variant-numeric: tabular-nums slashed-zero; }
/* the live dot's pulse (kit: --animate-live) */
.animate-live { animation: var(--animate-live); }
@keyframes live {
  0%, 100% { box-shadow: 0 0 0 0 color-mix(in oklch, var(--success) 55%, transparent); }
  60%      { box-shadow: 0 0 0 6px transparent; }
}

/* ---------- motion (kit section 4). Every colour comes from the tokens above. Only the AI moves on its own (and the Explore
   banner, the owner's one exception, in app.css); the rest answers a click or a hover. The kit's ribbon glint is not used here. ---------- */
@property --beam-angle {
  syntax: "<angle>";
  initial-value: 0deg;
  inherits: false;
}

/* 1. Moving light around the chat box border */
.beam {
  --beam-speed: 6s;          /* idle: one lap every 6 seconds          */
  --beam-width: 2px;         /* thickness of the moving light          */
  --beam-glow: 0.6;          /* how much light spills outside          */
  --beam-radius: 14px;
  position: relative;
  isolation: isolate;
  display: flex;             /* inner box always fills the frame */
  border-radius: var(--beam-radius);
  padding: var(--beam-width);
  background: conic-gradient(from var(--beam-angle),
    var(--beam-rest) 0deg 190deg,
    var(--beam-tail) 262deg,
    var(--beam-head) 328deg,
    var(--beam-spark) 349deg,
    var(--beam-rest) 360deg);
  animation: beam-orbit var(--beam-speed) linear infinite;
}
.beam::before {               /* the glow that follows the light */
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  border-radius: inherit;
  background: inherit;
  filter: blur(10px);
  opacity: var(--beam-glow);
  animation: beam-orbit var(--beam-speed) linear infinite;
  pointer-events: none;
}
.beam > .beam-inner {
  flex: 1;
  min-width: 0;
  border-radius: calc(var(--beam-radius) - var(--beam-width));
  background: var(--chat-bg);
}
.beam:focus-within            { --beam-speed: 3.5s; --beam-glow: 0.8; }
.beam[data-state="thinking"]  { --beam-speed: 1.6s; --beam-glow: 1; }
@keyframes beam-orbit { to { --beam-angle: 360deg; } }

/* 2. Press: every clickable thing sinks a little */
.press {
  transition: transform var(--dur-fast) var(--ease-out-quart),
              box-shadow 160ms var(--ease-out-quart),
              background-color 160ms var(--ease-out-quart);
}
.press:active { transform: scale(0.97); }

/* 3. Ripple: light spreads from where you clicked (clickFx in app.js, Phase 2).
   The kit's `.fx:not(.absolute, .fixed, .sticky)` becomes a guard on the two controls whose badge overflows: they never get .fx. */
.fx { overflow: hidden; }
.fx:where(:not(.bell, .menu-btn)) { position: relative; }
.fx .ripple {
  position: absolute;
  border-radius: 50%;
  pointer-events: none;
  background: radial-gradient(circle, currentColor 0%, transparent 62%);  /* takes the button's text colour, so it shows on any button */
  transform: scale(0);
  opacity: 0.3;
  animation: ripple 560ms var(--ease-out-expo) forwards;
}
@keyframes ripple { to { transform: scale(1); opacity: 0; } }

/* 4. Glow burst: a ring of light pops out after the click */
.fx.is-burst { animation: burst 620ms var(--ease-out-expo); }
@keyframes burst {
  0%   { box-shadow: 0 0 0 0 var(--burst); }
  100% { box-shadow: 0 0 0 12px transparent; }
}

/* 5. Sheen: a stripe of light sweeps across on hover */
.sheen { overflow: hidden; }
.sheen:where(:not(.bell, .menu-btn)) { position: relative; }
.sheen::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(115deg, transparent 30%, var(--sheen) 50%, transparent 70%);
  transform: translateX(-130%);
  transition: transform 700ms var(--ease-out-quart);
  pointer-events: none;
}
.sheen:hover::after { transform: translateX(130%); }

/* 7. Ring light: the assistant's avatar glows like a lit microphone ring */
.ring-light {
  box-shadow: 0 0 0 2px var(--beam-head), 0 0 14px 2px var(--ai-glow), inset 0 0 8px var(--ai-glow);
}
.ring-light[data-speaking="true"] { animation: ring-pulse 1.4s ease-in-out infinite; }
@keyframes ring-pulse {
  0%, 100% { box-shadow: 0 0 0 2px var(--beam-head), 0 0 10px 1px var(--ai-glow), inset 0 0 6px var(--ai-glow); }
  50%      { box-shadow: 0 0 0 2px var(--beam-spark), 0 0 22px 5px var(--ai-glow), inset 0 0 10px var(--ai-glow); }
}

/* 8. Card hover: lifts 2px and the edge warms to the accent */
.lift {
  transition: transform var(--dur-base) var(--ease-out-quart), border-color var(--dur-base), box-shadow var(--dur-base);
}
.lift:hover {
  transform: translateY(-2px);
  border-color: var(--lift-edge);
  box-shadow: 0 10px 28px -12px var(--ai-glow);
}

/* 9. Send: the arrow flies out and comes back */
.send.is-sent svg { animation: send-fly 520ms var(--ease-in-out-cubic); }
@keyframes send-fly {
  0%   { transform: translateX(0); opacity: 1; }
  45%  { transform: translateX(18px); opacity: 0; }
  46%  { transform: translateX(-18px); opacity: 0; }
  100% { transform: translateX(0); opacity: 1; }
}

/* Respect people who turn motion off (Phase 6 adds the page-wide rule) */
@media (prefers-reduced-motion: reduce) {
  .beam, .beam::before, .ring-light[data-speaking="true"], .text-thinking, .animate-live { animation: none; }
  .beam { background: var(--beam-head); }
  .fx .ripple, .fx.is-burst, .send.is-sent svg { animation: none; }
  .sheen::after, .lift, .press { transition: none; }
  .lift:hover, .press:active { transform: none; }
}
