/**
 * xopc workstation — design tokens (see docs/design/ui-design-system.md).
 * Tailwind v4: semantic --color-* names map to bg-*, text-*, border-* utilities.
 * Neutrals + motion tuned toward Apple system UI (SF stack, grouped grays, soft elevation).
 */

@import "tailwindcss";

@custom-variant dark (&:where(.dark, .dark *));

@theme {
  /* macOS / iOS first: SF Pro via system fonts; sensible fallbacks elsewhere */
  --font-sans: -apple-system, BlinkMacSystemFont, "SF Pro Text", "SF Pro Display", system-ui,
    "Segoe UI", Roboto, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Noto Sans CJK SC",
    "Microsoft YaHei", 微软雅黑, sans-serif;
  --font-mono: ui-monospace, "SF Mono", SFMono-Regular, Menlo, Monaco, Consolas, monospace;

  /* Surfaces — light: Apple-style grouped background + white content */
  --color-surface-base: #f5f5f7;
  --color-surface-panel: #ffffff;
  --color-surface-hover: #e8e8ed;
  --color-surface-active: #dcdcde;

  /* Foreground — Apple label hierarchy (light) */
  --color-fg: #1d1d1f;
  --color-fg-muted: #6e6e73;
  --color-fg-subtle: #86868b;
  --color-fg-disabled: #aeaeb2;

  /* Borders */
  --color-edge-subtle: #ebebed;
  --color-edge: #d2d2d7;
  --color-edge-strong: #bcbcc0;

  /* Brand (unchanged — xopc accent) */
  --color-accent: #2563eb;
  --color-accent-hover: #1d4ed8;
  --color-accent-soft: #eff6ff;
  --color-accent-fg: #2563eb;

  /**
   * Checkbox checked fill (used with custom `appearance: none` + tick).
   * Light: graphite — clear on white without reading as a harsh black slab.
   */
  --color-checkbox-accent: #4a4a52;
  /** SVG tick on filled checkboxes (white stroke). */
  --checkbox-icon-tick: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' fill='none'%3E%3Cpath d='M2.5 6.2 5 8.7 9.5 3.8' stroke='%23ffffff' stroke-width='1.85' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");

  /* Semantic */
  --color-success: #059669;
  --color-success-soft: #d1fae5;
  --color-danger: #dc2626;
  --color-danger-soft: #fee2e2;
  --color-warning: #d97706;
  --color-warning-soft: #fef3c7;

  /* Modal / drawer dimming */
  --color-scrim: rgb(0 0 0 / 0.36);

  /* Radii — slightly rounder, closer to macOS controls */
  --radius-sm: 0.625rem;
  --radius-md: 0.75rem;
  --radius-lg: 0.875rem;
  --radius-xl: 1.125rem;
  --radius-pill: 9999px;

  /* Elevation — soft layered shadows (light); dark relies more on borders */
  --shadow-surface: 0 1px 2px rgb(0 0 0 / 0.04), 0 1px 6px rgb(0 0 0 / 0.06);
  --shadow-elevated: 0 2px 8px rgb(0 0 0 / 0.06), 0 4px 24px rgb(0 0 0 / 0.08);
  --shadow-float: 0 4px 16px rgb(0 0 0 / 0.1), 0 12px 40px rgb(0 0 0 / 0.08);
  --shadow-popover: 0 8px 32px rgb(0 0 0 / 0.12), 0 2px 12px rgb(0 0 0 / 0.08);

  /* Main column under AppShell <main> — docs/design/ui-design-system.md §13.1 Web */
  --max-width-app-main: 72rem;
  /** Chat column (message list + composer); aligned with app main width. */
  --max-width-chat: var(--max-width-app-main);
}

/* Dark — Apple-style elevated grays + rim light via borders (see design spec §2.3) */
html.dark {
  --color-surface-base: #1c1c1e;
  --color-surface-panel: #2c2c2e;
  --color-surface-hover: #3a3a3c;
  --color-surface-active: #48484a;

  --color-fg: #f5f5f7;
  --color-fg-muted: #a1a1a6;
  --color-fg-subtle: #8e8e93;
  --color-fg-disabled: #636366;

  --color-edge-subtle: #3a3a3c;
  --color-edge: #48484a;
  --color-edge-strong: #636366;

  --color-accent: #3b82f6;
  --color-accent-hover: #60a5fa;
  --color-accent-soft: rgb(30 58 138 / 0.55);
  --color-accent-fg: #60a5fa;

  /* Dark: mid neutral (not near-white) so a white tick stays legible without another blue hotspot. */
  --color-checkbox-accent: #6a6a72;

  --color-success: #34d399;
  --color-success-soft: rgb(6 78 59 / 0.5);
  --color-danger: #f87171;
  --color-danger-soft: rgb(127 29 29 / 0.5);
  --color-warning: #fbbf24;
  --color-warning-soft: rgb(113 63 18 / 0.5);

  --color-scrim: rgb(0 0 0 / 0.52);

  --shadow-surface: 0 0 0 1px rgb(255 255 255 / 0.06);
  --shadow-elevated: 0 8px 32px rgb(0 0 0 / 0.45);
  --shadow-float: 0 12px 48px rgb(0 0 0 / 0.55);
  --shadow-popover: 0 16px 48px rgb(0 0 0 / 0.5);
}

@layer base {
  * {
    box-sizing: border-box;
  }

  html {
    height: 100%;
    overflow: hidden;
    font-family: var(--font-sans);
    background-color: var(--color-surface-base);
    color: var(--color-fg);
    color-scheme: light dark;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
    text-rendering: optimizeLegibility;
    -webkit-text-size-adjust: 100%;
    text-size-adjust: 100%;
    font-size: 100%;
  }

  /* UI text scale — rem-based layout follows root (settings → appearance). */
  html[data-font-scale='compact'] {
    font-size: 87.5%;
  }

  html[data-font-scale='large'] {
    font-size: 112.5%;
  }

  body {
    margin: 0;
    height: 100%;
    min-height: 100%;
    overflow: hidden;
    /* Slightly smaller UI body than 16px root — matches dense workstation + SF conventions */
    font-size: 0.9375rem;
    line-height: 1.47059;
    letter-spacing: -0.006em;
  }

  #root {
    display: flex;
    min-height: 0;
    height: 100%;
    flex-direction: column;
    overflow: hidden;
  }

  ::selection {
    background: var(--color-accent-soft);
    color: var(--color-accent-fg);
  }

  :focus-visible {
    outline: 2px solid var(--color-accent);
    outline-offset: 2px;
  }

  /**
   * Focus ring corner shape — not on plain text inputs.
   * Applying border-radius on :focus-visible to inputs changes the box geometry and causes
   * caret / IME rendering to flicker (often a thin dark line at the text origin) in WebKit/Blink.
   */
  :focus-visible:not(input):not(textarea) {
    border-radius: var(--radius-sm);
  }

  :focus:not(:focus-visible) {
    outline: none;
  }

  /**
   * Native `<input>` / `<textarea>` — strip global focus ring; pages use border/ring utilities.
   * (Same rationale as `<select>` below.)
   */
  input:focus,
  input:focus-visible,
  textarea:focus,
  textarea:focus-visible {
    outline: none;
    outline-offset: 0;
    box-shadow: none;
  }

  /**
   * Native `<select>` — UA + global :focus-visible both draw an outer ring; strip it.
   * Focus styling comes from `.ui-select` (border only) or page-specific classes.
   */
  select:focus,
  select:focus-visible {
    outline: none;
    outline-offset: 0;
    box-shadow: none;
  }

  /**
   * Global `<input type="checkbox">` — custom control so checked state is a clear tick on a
   * themed fill (avoids WebKit/Blink accent-color reading as a flat black/gray tile).
   */
  input[type='checkbox'] {
    appearance: none;
    -webkit-appearance: none;
    display: inline-block;
    vertical-align: middle;
    flex-shrink: 0;
    width: 1rem;
    height: 1rem;
    cursor: pointer;
    border: 1px solid var(--color-edge);
    border-radius: 0.25rem;
    background-color: var(--color-surface-panel);
    background-repeat: no-repeat;
    background-position: center;
    background-size: 0.7rem 0.7rem;
    transition:
      border-color 0.15s ease,
      background-color 0.15s ease,
      box-shadow 0.15s ease;
  }

  input[type='checkbox']:hover:not(:disabled) {
    border-color: var(--color-edge-strong);
  }

  input[type='checkbox']:checked {
    background-color: var(--color-checkbox-accent);
    border-color: var(--color-checkbox-accent);
    background-image: var(--checkbox-icon-tick);
  }

  input[type='checkbox']:focus-visible {
    outline: 2px solid var(--color-accent);
    outline-offset: 2px;
  }

  input[type='checkbox']:disabled {
    cursor: not-allowed;
    opacity: 0.5;
  }
}

@layer components {
  /**
   * Explicit checkbox utility — inherits global checkbox styling (do not re-apply `border-*`
   * here or it overrides `:checked` from the base layer).
   */
  .ui-checkbox {
    @apply size-4 shrink-0 cursor-pointer rounded;
  }

  .ui-checkbox:disabled {
    @apply cursor-not-allowed opacity-50;
  }

  /**
   * Native `<select>` — soft border, light hover; focus uses border only (no ring / outer shadow).
   */
  .ui-select {
    @apply rounded-lg border border-edge-subtle bg-surface-panel px-3 py-2 text-sm font-normal leading-snug text-fg;
    @apply cursor-pointer transition-[border-color,background-color] duration-150 ease-out;
    @apply hover:border-edge hover:bg-surface-hover/45;
    @apply focus:outline-none focus-visible:outline-none;
    @apply focus:ring-0 focus-visible:ring-0 focus-visible:ring-offset-0 focus-visible:shadow-none;
    @apply focus-visible:border-edge;
  }

  html.dark .ui-select {
    @apply border-edge-subtle bg-surface-panel;
  }

  html.dark .ui-select:hover {
    @apply border-edge bg-surface-hover/55;
  }

  .ui-select:disabled {
    @apply cursor-not-allowed opacity-50;
  }

  /**
   * Chat composer — selected skill token (light: cream + olive; dark: muted).
   */
  .chat-skill-pill {
    @apply inline-flex max-w-full shrink-0 items-center rounded-full px-2.5 py-0.5 align-baseline text-[0.9375rem] font-medium leading-5;
    background-color: #f5f5e6;
    color: #8a8a2e;
  }

  html.dark .chat-skill-pill {
    background-color: rgb(45 45 36);
    color: rgb(196 196 122);
  }

  /** Slash commands from palette (`/help`, `/new`, …) — composer + user bubble. */
  .chat-command-pill {
    @apply inline-flex max-w-full shrink-0 items-center rounded-full px-2.5 py-0.5 align-baseline text-[0.9375rem] font-medium leading-5;
    background-color: color-mix(in oklab, var(--color-accent-soft) 88%, transparent);
    color: var(--color-accent-fg);
  }

  html.dark .chat-command-pill {
    background-color: color-mix(in oklab, var(--color-accent-soft) 55%, transparent);
    color: var(--color-accent-fg);
  }

  .chat-file-pill {
    display: inline-flex;
    align-items: center;
    gap: 0.125rem;
    padding: 0.0625rem 0.375rem;
    border-radius: 0.25rem;
    background: var(--color-accent-soft);
    color: var(--color-accent-fg);
    font-size: 0.8125rem;
    font-weight: 500;
    white-space: nowrap;
    user-select: none;
    cursor: default;
    vertical-align: baseline;
  }

  .composer-input {
    position: relative;
    white-space: pre-wrap;
    overflow-wrap: anywhere;
    word-break: break-word;
  }

  .composer-input-empty:before {
    content: attr(data-placeholder);
    color: var(--color-fg-disabled);
    pointer-events: none;
  }
}

/*
 * Sidebar rail: width transition only at md+ (see SidebarColumn). Narrow viewports use
 * transform on the fixed drawer — animating width here would reflow the main column every frame.
 * translateZ(0) promotes a layer so width animation stutters less on some GPUs.
 */
.app-sidebar-push {
  transform: translateZ(0);
}

@media (min-width: 768px) {
  .app-sidebar-push {
    transition: width 280ms cubic-bezier(0.22, 1, 0.36, 1);
  }

  .app-sidebar-expanded-width {
    width: var(--sidebar-expanded-px, 16rem);
  }
}

.app-sidebar-push.sidebar-width-resizing {
  transition: none !important;
}

@media (prefers-reduced-motion: reduce) {
  .app-sidebar-push {
    transition: none;
  }
}

/* Settings full-page left rail: own `--settings-rail-px` (narrower min/max than app sidebar). */
@media (min-width: 768px) {
  .settings-page-rail {
    transform: translateZ(0);
    width: var(--settings-rail-px, 14.25rem);
    transition: width 280ms cubic-bezier(0.22, 1, 0.36, 1);
  }
}

.settings-page-rail.settings-page-rail-resizing {
  transition: none !important;
}

@media (prefers-reduced-motion: reduce) {
  .settings-page-rail {
    transition: none;
  }
}

/* Project files (right) rail: width from `--workspace-panel-px` (md+), matches sidebar drag pattern. */
@media (min-width: 768px) {
  .app-workspace-panel-expanded-width {
    transform: translateZ(0);
    width: var(--workspace-panel-px, 20rem);
    max-width: var(--workspace-panel-px, 20rem);
    transition: width 200ms cubic-bezier(0.4, 0, 0.2, 1);
  }
}

.app-workspace-panel-expanded-width.workspace-panel-rail-resizing {
  transition: none !important;
}

@media (prefers-reduced-motion: reduce) {
  .app-workspace-panel-expanded-width {
    transition: none;
  }
}

/*
 * Page-level enter animation — triggered when the top-level route segment changes
 * (AppShell re-keys the Outlet wrapper on routeKey). Keeps the shell layout stable
 * while the incoming page content fades + lifts in. Duration 200ms matches the
 * design system size / displacement-motion spec (§8.2). translateZ(0) avoids sub-pixel jitter.
 */
@keyframes page-enter {
  from {
    opacity: 0;
    transform: translateY(4px) translateZ(0);
  }
  to {
    opacity: 1;
    transform: translateY(0) translateZ(0);
  }
}

.page-enter {
  animation: page-enter 200ms cubic-bezier(0.25, 0.1, 0.25, 1) both;
}

/* Full-screen settings: slightly longer, softer ease to reduce a “snap” vs main chrome. */
.page-enter--gentle {
  animation-duration: 280ms;
  animation-timing-function: cubic-bezier(0.22, 1, 0.36, 1);
}

@media (prefers-reduced-motion: reduce) {
  .page-enter {
    animation: none;
  }

  .page-enter--gentle {
    animation: none;
  }
}

@keyframes settings-sheet-enter {
  from {
    opacity: 0.85;
    transform: translateX(0.5rem);
  }
  to {
    opacity: 1;
    transform: translateX(0);
  }
}

@media (prefers-reduced-motion: no-preference) {
  .settings-sheet-enter {
    animation: settings-sheet-enter 250ms ease-out both;
  }
}

@media (prefers-reduced-motion: reduce) {
  .settings-sheet-enter {
    animation: none;
  }
}

/*
 * Theme (light/dark): smooth cross-fade instead of an instant snap (View Transitions API).
 * Browsers without support keep an immediate switch; `prefers-reduced-motion` disables animation.
 */
@media (prefers-reduced-motion: no-preference) {
  ::view-transition-old(root),
  ::view-transition-new(root) {
    animation-duration: 0.42s;
    animation-timing-function: cubic-bezier(0.25, 0.1, 0.25, 1);
  }
}

/*
 * Light-green palette (internal id: emerald) — void-black canvas, green accent, terminal-native radii.
 * Applied via html[data-color-scheme="emerald"] (light) and html.dark[data-color-scheme="emerald"] (dark).
 */
html[data-color-scheme='emerald'] {
  --color-surface-base: #f0fdf4;
  --color-surface-panel: #ffffff;
  --color-surface-hover: #dcfce7;
  --color-surface-active: #bbf7d0;

  --color-fg: #052e16;
  --color-fg-muted: #166534;
  --color-fg-subtle: #15803d;
  --color-fg-disabled: #86efac;

  --color-edge-subtle: #bbf7d0;
  --color-edge: #86efac;
  --color-edge-strong: #4ade80;

  --color-accent: #059669;
  --color-accent-hover: #047857;
  --color-accent-soft: #d1fae5;
  --color-accent-fg: #047857;

  --color-checkbox-accent: #059669;

  --color-success: #059669;
  --color-success-soft: #d1fae5;
  --color-danger: #dc2626;
  --color-danger-soft: #fee2e2;
  --color-warning: #d97706;
  --color-warning-soft: #fef3c7;

  --radius-sm: 0.25rem;
  --radius-md: 0.375rem;
  --radius-lg: 0.5rem;
  --radius-xl: 0.75rem;
}

html.dark[data-color-scheme='emerald'] {
  --color-surface-base: #000000;
  --color-surface-panel: #0a0a0a;
  --color-surface-hover: #111111;
  --color-surface-active: #1a1a1a;

  --color-fg: #d1fae5;
  --color-fg-muted: #6ee7b7;
  --color-fg-subtle: #34d399;
  --color-fg-disabled: #065f46;

  --color-edge-subtle: #0d2818;
  --color-edge: #134e2a;
  --color-edge-strong: #166534;

  --color-accent: #10b981;
  --color-accent-hover: #34d399;
  --color-accent-soft: rgb(6 78 59 / 0.6);
  --color-accent-fg: #34d399;

  --color-checkbox-accent: #10b981;

  --color-success: #34d399;
  --color-success-soft: rgb(6 78 59 / 0.5);
  --color-danger: #f87171;
  --color-danger-soft: rgb(127 29 29 / 0.5);
  --color-warning: #fbbf24;
  --color-warning-soft: rgb(113 63 18 / 0.5);

  --color-scrim: rgb(0 0 0 / 0.72);

  --shadow-surface: 0 0 0 1px rgb(16 185 129 / 0.1);
  --shadow-elevated: 0 8px 32px rgb(0 0 0 / 0.8), 0 0 0 1px rgb(16 185 129 / 0.07);
  --shadow-float: 0 12px 48px rgb(0 0 0 / 0.9), 0 0 0 1px rgb(16 185 129 / 0.06);
  --shadow-popover: 0 16px 48px rgb(0 0 0 / 0.85), 0 0 0 1px rgb(16 185 129 / 0.12);

  --radius-sm: 0.25rem;
  --radius-md: 0.375rem;
  --radius-lg: 0.5rem;
  --radius-xl: 0.75rem;
}

/*
 * Monochrome SaaS — white canvas, near-black CTAs, gray cards; Inter-first stack.
 * html[data-color-scheme="mono"] / html.dark[data-color-scheme="mono"]
 */
html[data-color-scheme='mono'] {
  --font-sans: "Inter", ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
    "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Noto Sans CJK SC", "Microsoft YaHei", 微软雅黑,
    sans-serif;

  /* Canvas + card surfaces (#ffffff / #f8f9fa / #f5f5f5 / #e5e7eb) */
  --color-surface-base: #ffffff;
  --color-surface-panel: #f5f5f5;
  --color-surface-hover: #f8f9fa;
  --color-surface-active: #e5e7eb;

  --color-fg: #111111;
  --color-fg-muted: #6b7280;
  --color-fg-subtle: #898989;
  --color-fg-disabled: #d1d5db;

  --color-edge-subtle: #f3f4f6;
  --color-edge: #e5e7eb;
  --color-edge-strong: #d1d5db;

  /* Primary actions = near-black; sparse “brand” blue only where accent-fg reads as link tint */
  --color-accent: #111111;
  --color-accent-hover: #242424;
  --color-accent-soft: #f3f4f6;
  --color-accent-fg: #111111;

  /* Mono light: near-primary text; tick breaks the “solid tile” look vs bare native fill. */
  --color-checkbox-accent: #242424;

  --color-success: #10b981;
  --color-success-soft: #d1fae5;
  --color-danger: #ef4444;
  --color-danger-soft: #fee2e2;
  --color-warning: #f59e0b;
  --color-warning-soft: #fef3c7;

  --color-scrim: rgb(0 0 0 / 0.4);

  --shadow-surface: 0 1px 2px rgb(0 0 0 / 0.05);
  --shadow-elevated: 0 4px 12px rgb(0 0 0 / 0.08);
  --shadow-float: 0 4px 16px rgb(0 0 0 / 0.08), 0 12px 32px rgb(0 0 0 / 0.06);
  --shadow-popover: 0 8px 24px rgb(0 0 0 / 0.1), 0 2px 8px rgb(0 0 0 / 0.06);

  --radius-sm: 0.375rem;
  --radius-md: 0.5rem;
  --radius-lg: 0.75rem;
  --radius-xl: 1rem;
}

html[data-color-scheme='mono'] body {
  letter-spacing: -0.01em;
}

html.dark[data-color-scheme='mono'] {
  --font-sans: "Inter", ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
    "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Noto Sans CJK SC", "Microsoft YaHei", 微软雅黑,
    sans-serif;

  --color-surface-base: #101010;
  --color-surface-panel: #1a1a1a;
  --color-surface-hover: #262626;
  --color-surface-active: #333333;

  --color-fg: #fafafa;
  --color-fg-muted: #a1a1aa;
  --color-fg-subtle: #71717a;
  --color-fg-disabled: #52525b;

  --color-edge-subtle: #262626;
  --color-edge: #333333;
  --color-edge-strong: #404040;

  --color-accent: #737373;
  --color-accent-hover: #8a8a8a;
  --color-accent-soft: rgb(255 255 255 / 0.08);
  --color-accent-fg: #e4e4e7;

  /* Dark mono: mid gray fill + white tick (avoids light-gray “cement block”). */
  --color-checkbox-accent: #71717a;

  --color-success: #34d399;
  --color-success-soft: rgb(6 78 59 / 0.45);
  --color-danger: #f87171;
  --color-danger-soft: rgb(127 29 29 / 0.45);
  --color-warning: #fbbf24;
  --color-warning-soft: rgb(113 63 18 / 0.45);

  --color-scrim: rgb(0 0 0 / 0.65);

  --shadow-surface: 0 0 0 1px rgb(255 255 255 / 0.06);
  --shadow-elevated: 0 8px 28px rgb(0 0 0 / 0.55);
  --shadow-float: 0 12px 40px rgb(0 0 0 / 0.6);
  --shadow-popover: 0 16px 48px rgb(0 0 0 / 0.55);

  --radius-sm: 0.375rem;
  --radius-md: 0.5rem;
  --radius-lg: 0.75rem;
  --radius-xl: 1rem;
}

/*
 * Clay-inspired — cream canvas (#fffaf0), near-black ink CTAs, generous radii, Inter stack.
 * html[data-color-scheme="clay"] / html.dark[data-color-scheme="clay"]
 */
html[data-color-scheme='clay'] {
  --font-sans: "Inter", ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
    "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Noto Sans CJK SC", "Microsoft YaHei", 微软雅黑,
    sans-serif;

  --color-surface-base: #fffaf0;
  --color-surface-panel: #ffffff;
  --color-surface-hover: #faf5e8;
  --color-surface-active: #f5f0e0;

  --color-fg: #0a0a0a;
  --color-fg-muted: #6a6a6a;
  --color-fg-subtle: #9a9a9a;
  --color-fg-disabled: #c8c4bc;

  --color-edge-subtle: #f0ebe0;
  --color-edge: #e5e5e5;
  --color-edge-strong: #d8d3c8;

  --color-accent: #0a0a0a;
  --color-accent-hover: #1a1a1a;
  --color-accent-soft: #f5f0e0;
  --color-accent-fg: #1a3a3a;

  --color-checkbox-accent: #0a0a0a;

  --color-success: #22c55e;
  --color-success-soft: #dcfce7;
  --color-danger: #ef4444;
  --color-danger-soft: #fee2e2;
  --color-warning: #f59e0b;
  --color-warning-soft: #fef3c7;

  --color-scrim: rgb(10 10 10 / 0.36);

  --shadow-surface: none;
  --shadow-elevated: 0 2px 8px rgb(10 10 10 / 0.04);
  --shadow-float: 0 4px 16px rgb(10 10 10 / 0.06);
  --shadow-popover: 0 8px 24px rgb(10 10 10 / 0.08);

  --radius-sm: 0.375rem;
  --radius-md: 0.75rem;
  --radius-lg: 1rem;
  --radius-xl: 1.5rem;
}

html[data-color-scheme='clay'] body {
  letter-spacing: -0.01em;
}

html.dark[data-color-scheme='clay'] {
  --font-sans: "Inter", ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
    "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Noto Sans CJK SC", "Microsoft YaHei", 微软雅黑,
    sans-serif;

  --color-surface-base: #0a1a1a;
  --color-surface-panel: #1a2a2a;
  --color-surface-hover: #243636;
  --color-surface-active: #2e4040;

  --color-fg: #fffaf0;
  --color-fg-muted: #a4d4c5;
  --color-fg-subtle: #6a8a80;
  --color-fg-disabled: #4a5a56;

  --color-edge-subtle: #1f2f2f;
  --color-edge: #2a3a3a;
  --color-edge-strong: #3a4a4a;

  --color-accent: #ffb084;
  --color-accent-hover: #ffc9a8;
  --color-accent-soft: rgb(26 58 58 / 0.55);
  --color-accent-fg: #ffb084;

  --color-checkbox-accent: #a4d4c5;

  --color-success: #34d399;
  --color-success-soft: rgb(6 78 59 / 0.45);
  --color-danger: #f87171;
  --color-danger-soft: rgb(127 29 29 / 0.45);
  --color-warning: #fbbf24;
  --color-warning-soft: rgb(113 63 18 / 0.45);

  --color-scrim: rgb(0 0 0 / 0.65);

  --shadow-surface: 0 0 0 1px rgb(164 212 197 / 0.08);
  --shadow-elevated: 0 8px 28px rgb(0 0 0 / 0.55);
  --shadow-float: 0 12px 40px rgb(0 0 0 / 0.6);
  --shadow-popover: 0 16px 48px rgb(0 0 0 / 0.55);

  --radius-sm: 0.375rem;
  --radius-md: 0.75rem;
  --radius-lg: 1rem;
  --radius-xl: 1.5rem;
}

::-webkit-scrollbar {
  width: 6px;
  height: 6px;
}

::-webkit-scrollbar-track {
  background: transparent;
}

::-webkit-scrollbar-thumb {
  background: var(--color-edge-strong);
  border-radius: 9999px;
}

::-webkit-scrollbar-thumb:hover {
  background: var(--color-fg-subtle);
}

/**
 * Chat message list: stable gutter + thin thumb.
 * Without stable gutter, overflow-y:auto toggles the scrollbar width during streaming;
 * the column narrows/widens, text reflows, height crosses the overflow threshold → scrollbar flicker.
 */
.chat-messages {
  scrollbar-gutter: stable;
  scrollbar-width: thin;
  scrollbar-color: color-mix(in srgb, var(--color-edge-strong) 58%, transparent) transparent;
  overscroll-behavior-y: contain;
  /* Inset from the end edge so right-aligned user bubbles sit clear of the scrollbar thumb
   * (overlay scrollbars and thick WebKit thumbs can still read as covering content without this). */
  padding-inline-end: 0.5rem;
}

/**
 * Chat markdown bubbles: keep long lines / code / tables from widening the main column
 * (avoids horizontal scrollbars on the message list while streaming).
 */
.markdown-content {
  min-width: 0;
  max-width: 100%;
}

.markdown-content .markdown-body {
  min-width: 0;
  max-width: 100%;
  overflow-wrap: anywhere;
  word-break: break-word;
}

.markdown-content .markdown-body pre {
  max-width: 100%;
  min-width: 0;
  box-sizing: border-box;
}

.markdown-content .markdown-code-block {
  max-width: 100%;
  min-width: 0;
  box-sizing: border-box;
}

.markdown-content .markdown-body pre code.hljs {
  max-width: 100%;
  box-sizing: border-box;
}

.markdown-content .markdown-body table {
  max-width: 100%;
  table-layout: fixed;
}

.markdown-content .markdown-body th,
.markdown-content .markdown-body td {
  word-break: break-word;
  overflow-wrap: anywhere;
}

html.dark .chat-messages {
  scrollbar-color: color-mix(in srgb, var(--color-edge) 72%, transparent) transparent;
}

.chat-messages::-webkit-scrollbar {
  width: 10px;
}

.chat-messages::-webkit-scrollbar-track {
  background: transparent;
}

.chat-messages::-webkit-scrollbar-thumb {
  border-radius: 9999px;
  border: 3px solid transparent;
  background-clip: content-box;
  background-color: color-mix(in srgb, var(--color-edge-strong) 50%, transparent);
}

.chat-messages::-webkit-scrollbar-thumb:hover {
  background-color: color-mix(in srgb, var(--color-fg-subtle) 38%, transparent);
}

html.dark .chat-messages::-webkit-scrollbar-thumb {
  background-color: color-mix(in srgb, var(--color-edge) 55%, transparent);
}

html.dark .chat-messages::-webkit-scrollbar-thumb:hover {
  background-color: color-mix(in srgb, var(--color-fg-muted) 45%, transparent);
}

/**
 * App shell left nav: keep overflow scroll but hide the scrollbar (wheel / trackpad / touch unchanged).
 */
.app-sidebar-nav-scroll {
  -ms-overflow-style: none;
  scrollbar-width: none;
}

.app-sidebar-nav-scroll::-webkit-scrollbar {
  display: none;
  width: 0;
  height: 0;
}

/* Mobile nav drawer: push-in from left (Radix Dialog sets data-state on overlay + content). */
@keyframes xopc-overlay-in {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}

@keyframes xopc-drawer-in {
  from {
    transform: translate3d(-100%, 0, 0);
  }
  to {
    transform: translate3d(0, 0, 0);
  }
}

/* Dialog overlay and content animations */
@keyframes xopc-dialog-overlay-in {
  from { opacity: 0; }
  to { opacity: 1; }
}
@keyframes xopc-dialog-overlay-out {
  from { opacity: 1; }
  to { opacity: 0; }
}

/* Opacity only — do not animate `transform` here: it overrides Tailwind centering
 * (`left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2`) and causes the modal to jump
 * (e.g. drift to a corner) when the animation ends. */
@keyframes xopc-dialog-content-in {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}
@keyframes xopc-dialog-content-out {
  from {
    opacity: 1;
  }
  to {
    opacity: 0;
  }
}

/* Fullscreen dialog (e.g. chat attachment preview): never translate — `inset-0` + translate drifts off-screen */
@keyframes xopc-dialog-fullscreen-in {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}
@keyframes xopc-dialog-fullscreen-out {
  from {
    opacity: 1;
  }
  to {
    opacity: 0;
  }
}

/* Flex-centered pane: parent handles position; animation must not apply translate(-50%,-50%) */
@keyframes xopc-dialog-pane-in {
  from {
    opacity: 0;
    transform: scale(0.96);
  }
  to {
    opacity: 1;
    transform: scale(1);
  }
}
@keyframes xopc-dialog-pane-out {
  from {
    opacity: 1;
    transform: scale(1);
  }
  to {
    opacity: 0;
    transform: scale(0.96);
  }
}

/* Drawer (right-side panel) animations */
@keyframes xopc-drawer-right-in {
  from {
    opacity: 0.92;
    transform: translate3d(100%, 0, 0);
  }
  to {
    opacity: 1;
    transform: translate3d(0, 0, 0);
  }
}
@keyframes xopc-drawer-right-out {
  from {
    opacity: 1;
    transform: translate3d(0, 0, 0);
  }
  to {
    opacity: 0.92;
    transform: translate3d(100%, 0, 0);
  }
}

/* Animation classes for Radix Dialog */
.xopc-dialog-overlay[data-state='open'] {
  animation: xopc-dialog-overlay-in 0.2s ease-out both;
}
.xopc-dialog-overlay[data-state='closed'] {
  animation: xopc-dialog-overlay-out 0.15s ease-in both;
}

.xopc-dialog-content[data-state='open'] {
  animation: xopc-dialog-content-in 0.25s cubic-bezier(0.32, 0.72, 0, 1) both;
}
.xopc-dialog-content[data-state='closed'] {
  animation: xopc-dialog-content-out 0.2s ease-in both;
}

.xopc-dialog-content-fullscreen[data-state='open'] {
  animation: xopc-dialog-fullscreen-in 0.25s cubic-bezier(0.32, 0.72, 0, 1) both;
}
.xopc-dialog-content-fullscreen[data-state='closed'] {
  animation: xopc-dialog-fullscreen-out 0.2s ease-in both;
}

.xopc-dialog-content-pane[data-state='open'] {
  animation: xopc-dialog-pane-in 0.25s cubic-bezier(0.32, 0.72, 0, 1) both;
}
.xopc-dialog-content-pane[data-state='closed'] {
  animation: xopc-dialog-pane-out 0.2s ease-in both;
}

.xopc-drawer-right[data-state='open'] {
  animation: xopc-drawer-right-in 0.38s cubic-bezier(0.22, 1, 0.36, 1) both;
}
.xopc-drawer-right[data-state='closed'] {
  animation: xopc-drawer-right-out 0.24s cubic-bezier(0.4, 0, 1, 1) both;
}

.xopc-mobile-nav-overlay[data-state='open'] {
  animation: xopc-overlay-in 0.2s ease-out both;
}
.xopc-mobile-nav-overlay[data-state='closed'] {
  animation: xopc-dialog-overlay-out 0.15s ease-in both;
}

.xopc-mobile-nav-content[data-state='open'] {
  animation: xopc-drawer-in 0.28s cubic-bezier(0.32, 0.72, 0, 1) both;
}

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}

/* ── Dreaming overlay animations ─────────────────────────────────────── */

@keyframes dreaming-overlay-enter {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}

@keyframes dreaming-overlay-exit {
  from {
    opacity: 1;
  }
  to {
    opacity: 0;
  }
}

@keyframes dreaming-pill-enter {
  from {
    opacity: 0;
    transform: translateY(12px) translateX(-50%);
  }
  to {
    opacity: 1;
    transform: translateY(0) translateX(-50%);
  }
}

@keyframes dreaming-pulse-dot {
  0%,
  100% {
    opacity: 0.4;
    transform: scale(0.8);
  }
  50% {
    opacity: 1;
    transform: scale(1.2);
  }
}

.dreaming-overlay-enter {
  animation: dreaming-overlay-enter 0.6s cubic-bezier(0.22, 1, 0.36, 1) both;
}

.dreaming-overlay-exit {
  animation: dreaming-overlay-exit 0.8s cubic-bezier(0.4, 0, 1, 1) both;
}

.dreaming-pill-enter {
  animation: dreaming-pill-enter 0.5s cubic-bezier(0.22, 1, 0.36, 1) 0.3s both;
}

.dreaming-pulse-dot {
  display: inline-block;
  width: 6px;
  height: 6px;
  border-radius: 9999px;
  background: currentColor;
  animation: dreaming-pulse-dot 2s ease-in-out infinite;
}
