# apps/web/src/index.css · gitcafe/t3code

[View on GitCafe](https://git.cafe/gitcafe/t3code/blob/cdd331b6c3f78bf24b039b09937b837d2d71a4e7/apps/web/src/index.css)

Repository: [gitcafe/t3code](https://git.cafe/gitcafe/t3code)

Visibility: public

Requested revision: cdd331b6c3f78bf24b039b09937b837d2d71a4e7

Requested commit: cdd331b6c3f78bf24b039b09937b837d2d71a4e7

Commit: cdd331b6c3f78bf24b039b09937b837d2d71a4e7

Blob: 73e56caaf4e6e870173611e450ed65e98df597f4

Size: 81776 bytes

[Immutable source](https://git.cafe/gitcafe/t3code/blob/cdd331b6c3f78bf24b039b09937b837d2d71a4e7/apps/web/src/index.css?format=markdown)

```
@import "tailwindcss";

@custom-variant dark (&:is(.dark, .dark *));
@custom-variant light (&:not(.dark, .dark *));
/* Window Controls Overlay: active when Electron exposes native titlebar control geometry. */
@custom-variant wco (&:is(.wco, .wco *));

/* Secondary hovering pointers reveal sidebar actions on touch-primary devices. */
@custom-variant any-hover {
  @media (any-hover: hover) {
    &:hover {
      @slot;
    }
  }
}

/* On mobile, morph the expanded hero composer into the compact docked
   composer while it moves; the rest of the app remains visually stationary. */
html[data-mobile-composer-route-transition="true"]::view-transition-old(root),
html[data-mobile-composer-route-transition="true"]::view-transition-new(root) {
  animation: none;
}

html[data-mobile-composer-route-transition="true"]::view-transition-group(t3-mobile-composer) {
  animation-duration: var(--mobile-composer-transition-duration);
  animation-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
}

html[data-mobile-composer-route-transition="true"]::view-transition-image-pair(t3-mobile-composer) {
  isolation: isolate;
}

html[data-mobile-composer-route-transition="true"]::view-transition-old(t3-mobile-composer) {
  animation: t3-mobile-composer-old var(--mobile-composer-transition-duration) linear both;
  mix-blend-mode: normal;
}

html[data-mobile-composer-route-transition="true"]::view-transition-new(t3-mobile-composer) {
  animation: t3-mobile-composer-new var(--mobile-composer-transition-duration) linear both;
  mix-blend-mode: normal;
}

/* The expanded and compact composers have different internal layouts. Use a
   brief crossfade while their shared wrapper moves so the layout change does
   not read as a single-frame cut. */
@keyframes t3-mobile-composer-old {
  0%,
  35% {
    opacity: 1;
  }
  65%,
  100% {
    opacity: 0;
  }
}

@keyframes t3-mobile-composer-new {
  0%,
  35% {
    opacity: 0;
  }
  65%,
  100% {
    opacity: 1;
  }
}

html[data-mobile-composer-route-transition="true"]::view-transition-group(t3-mobile-draft-headline) {
  animation-duration: var(--mobile-composer-transition-duration);
}

html[data-mobile-composer-route-transition="true"]::view-transition-old(t3-mobile-draft-headline) {
  animation: t3-mobile-draft-headline-exit var(--mobile-composer-transition-duration)
    cubic-bezier(0.4, 0, 1, 1) both;
  mix-blend-mode: normal;
}

@keyframes t3-mobile-draft-headline-exit {
  from {
    opacity: 1;
    transform: translateY(0);
  }
  to {
    opacity: 0;
    transform: translateY(-6px);
  }
}

:root {
  --app-scrollbar-width: 6px;
  --appearance-contrast-base: 100%;
  --appearance-contrast-boost: 0%;
  --appearance-contrast-border-boost: 0%;
  --appearance-contrast-target: black;
  --app-scrollbar-thumb: rgb(217 217 217);
  --app-scrollbar-thumb-hover: rgb(191 191 191);
  /*
   * Compact UI geometry. Keep these values semantic so sidebar, palette,
   * tooltip, and toolbar controls cannot quietly drift apart.
   */
  --control-radius: 0.5rem;
  --sidebar-content-inset: 0.5rem;
  --sidebar-control-gap: 0.5rem;
  --sidebar-icon-color: color-mix(
    in srgb,
    var(--contrast-sidebar-muted-foreground) 60%,
    var(--sidebar)
  );
  --sidebar-row-content-inset: 0.625rem;
  --command-shell-inset: 0.5rem;
  --command-content-inset: 1rem;
  --floating-content-inset: 0.75rem;
  /* App layer order: docked sheets, then the floating preview player (47–49, see
     previewMiniPlayerLayout.ts), then dialogs and popovers (50 and up). */
  --z-sheet: 46;
  --glass-blur: 12px;
  --glass-opacity: 80%;
  --glass-saturation: 1.14;
  --desktop-window-right-resize-inset: 0px;
  --workspace-topbar-height: 52px;
  --workspace-controls-top: 0px;
  --workspace-controls-left: calc(env(safe-area-inset-left) + 0.75rem);
  --workspace-controls-right: calc(env(safe-area-inset-right) + 0.75rem);
  --workspace-native-controls-inset: 0px;
  --workspace-titlebar-control-size: 1.75rem;
  --workspace-titlebar-control-gap: 0.75rem;
  --workspace-titlebar-scroll-fade-height: 1.5rem;
  --chat-content-max-width: 46rem;
  --thread-details-panel-width: 17.5rem;
  /* The prompt on phones: iOS zooms into any input under 16px on focus. */
  --font-size-prompt-touch: max(var(--font-size-prompt, 1rem), 16px);
  /* Horizontal gutter shared by the page header and the chat column, clear of
     the device's safe area. */
  --workspace-gutter: 0.75rem;
  --workspace-gutter-start: calc(env(safe-area-inset-left) + var(--workspace-gutter));
  --workspace-gutter-end: calc(env(safe-area-inset-right) + var(--workspace-gutter));

  @variant sm {
    --workspace-gutter: 1.25rem;
  }

  @variant dark {
    --appearance-contrast-target: white;
    --app-scrollbar-thumb: rgb(255 255 255 / 8%);
    --app-scrollbar-thumb-hover: rgb(255 255 255 / 12%);
    --glass-blur: 16px;
    --glass-saturation: 1.08;
  }
}

.wco {
  --workspace-topbar-height: max(40px, env(titlebar-area-height, 52px));
  --workspace-controls-top: env(titlebar-area-y, 0px);
  --workspace-controls-left: calc(env(titlebar-area-x, 0px) + 0.75rem);
  --workspace-controls-right: calc(
    100vw - env(titlebar-area-width, 100vw) - env(titlebar-area-x, 0px) + 0.75rem
  );
  --workspace-native-controls-inset: calc(
    100vw - env(titlebar-area-width, 100vw) - env(titlebar-area-x, 0px) + 0.75rem
  );
}

/* The font tokens are declared outside the inline theme so utilities reference
   the variables and Settings -> Appearance can override them at runtime. The
   default stacks are mirrored in `appearanceFonts.ts`. */
@theme {
  --font-sans: -apple-system, BlinkMacSystemFont, "Segoe UI", system-ui, sans-serif;
  --font-mono:
    ui-monospace, "SF Mono", "SFMono-Regular", Menlo, Consolas, "Liberation Mono", monospace;
}

@theme inline {
  /* Two steps below Tailwind's text-xs (12px) for dense UI: metadata rows,
     badges, counters, keyboard hints and diagnostics tables. 2xs is 11px,
     3xs is 10px. Provider icon overlays use 4xs (8px) and 5xs (7px) to fit
     their smaller badges. Registered with tailwind-merge in
     lib/utils.ts so cn() treats them as font sizes, not colours. */
  --text-2xs: 0.6875rem;
  --text-2xs--line-height: calc(1 / 0.6875);
  --text-3xs: 0.625rem;
  --text-3xs--line-height: calc(0.875 / 0.625);
  --text-4xs: 0.5rem;
  --text-4xs--line-height: 1;
  --text-5xs: 0.4375rem;
  --text-5xs--line-height: 1;
  /* Motion. drawer is the decelerating curve for surfaces that slide or pop in
     (composer context, pills). */
  --inset-shadow-control-highlight: 0 1px rgb(255 255 255 / 16%);
  --inset-shadow-control-pressed: 0 1px rgb(0 0 0 / 8%);
  --ease-drawer: cubic-bezier(0.32, 0.72, 0, 1);
  /* The composer's elevation: a soft drop pulled in under the surface, shared
     by the composer, its context strip and attached banners. */
  --shadow-composer: 0 12px 28px -18px rgb(0 0 0 / 40%);
  --shadow-composer-dark: 0 14px 32px -18px rgb(0 0 0 / 75%);
  /* Dark-mode shade where an attached surface meets the composer: 10px of
     shadow fading away from the seam. Inline, so the offsets resolve on the
     element. below: the context strip under the composer (1rem seam, faint
     white fill). above: an attached banner over it (its tint on top). */
  --background-image-composer-seam-below:
    linear-gradient(
      to bottom,
      transparent 0 1rem,
      rgb(0 0 0 / 18%) 1rem,
      transparent calc(1rem + 10px)
    ),
    linear-gradient(rgb(255 255 255 / 1%), rgb(255 255 255 / 1%));
  --background-image-composer-seam-above:
    linear-gradient(var(--chat-composer-attached-tint), var(--chat-composer-attached-tint)),
    linear-gradient(
      to top,
      transparent 0 var(--chat-composer-attachment-overlap),
      rgb(0 0 0 / 18%) var(--chat-composer-attachment-overlap),
      transparent calc(var(--chat-composer-attachment-overlap) + 10px)
    );
  --color-zinc-25: oklch(99.2% 0 0);
  --animate-skeleton: skeleton 2.4s infinite;
  /* Duty-cycled indicator animations: long holds with stepped ramps, so the
     compositor updates discrete frames instead of every vsync. */
  --animate-status-pulse: status-pulse 2s infinite;
  --animate-status-ping: status-ping 2s infinite;
  --color-warning-foreground: var(--warning-foreground);
  --color-warning: var(--warning);
  --color-warning-surface: var(--warning-surface);
  --color-error-foreground: var(--error-foreground);
  --color-tool-error-icon: var(--tool-error-icon);
  --color-error: var(--error);
  --color-error-surface: var(--error-surface);
  --color-update-foreground: var(--update-foreground);
  --color-update: var(--update);
  --color-update-surface: var(--update-surface);
  --color-success-foreground: var(--success-foreground);
  --color-success: var(--success);
  --color-diff-addition: var(--diff-addition);
  --color-diff-deletion: var(--diff-deletion);
  --color-diff-addition-foreground: var(--diff-addition-foreground);
  --color-diff-deletion-foreground: var(--diff-deletion-foreground);
  --color-info-foreground: var(--info-foreground);
  --color-info: var(--info);
  --color-destructive-foreground: var(--destructive-foreground);
  --color-ring: var(--ring);
  --color-input: var(--contrast-input);
  --color-border: var(--contrast-border);
  --color-destructive: var(--destructive);
  --color-accent-foreground: var(--contrast-accent-foreground);
  --color-accent: var(--accent);
  --color-muted-foreground: var(--contrast-muted-foreground);
  --color-muted: var(--muted);
  --color-placeholder: var(--contrast-placeholder);
  --color-secondary-label: var(--contrast-secondary-label);
  --color-icon-muted: var(--contrast-icon-muted);
  --color-secondary-foreground: var(--contrast-secondary-foreground);
  --color-secondary: var(--secondary);
  --color-primary-foreground: var(--primary-foreground);
  --color-primary: var(--primary);
  --color-popover-foreground: var(--contrast-popover-foreground);
  --color-popover: var(--popover);
  --color-card-foreground: var(--contrast-card-foreground);
  --color-card: var(--card);
  --color-code: var(--code-background);
  --color-code-foreground: var(--code-foreground);
  --color-foreground: var(--contrast-foreground);
  --color-background: var(--background);
  --color-surface-raised: var(--surface-raised);
  --color-message: var(--message-surface);
  --color-message-foreground: var(--contrast-message-foreground);
  --color-message-action: var(--message-action);
  --color-message-action-foreground: var(--message-action-foreground);
  --color-message-action-hover: var(--message-action-hover);
  --color-sidebar: var(--sidebar);
  --color-sidebar-foreground: var(--contrast-sidebar-foreground);
  --color-sidebar-muted-foreground: var(--contrast-sidebar-muted-foreground);
  --color-sidebar-control-surface: var(--sidebar-control-surface);
  --color-sidebar-row-hover: var(--sidebar-row-hover);
  --color-sidebar-row-active: var(--sidebar-row-active);
  --color-sidebar-row-selected: var(--sidebar-row-selected);
  --color-sidebar-border: var(--contrast-sidebar-border);
  --radius-sm: calc(var(--radius) - 4px);
  --radius-md: calc(var(--radius) - 2px);
  --radius-lg: var(--radius);
  --radius-xl: calc(var(--radius) + 4px);
  --radius-2xl: calc(var(--radius) + 8px);
  --radius-3xl: calc(var(--radius) + 12px);
  @keyframes skeleton {
    /* The single loading-bar breath used by every skeleton: one opacity pulse
       per container, stepped so however many bars sit under it, the compositor
       draws a handful of discrete frames per cycle rather than one per vsync —
       which on a 120Hz display is the difference between ~14 and ~288 updates. */
    0%,
    42% {
      opacity: 1;
      animation-timing-function: steps(4);
    }
    50%,
    92% {
      opacity: 0.55;
      animation-timing-function: steps(4);
    }
    100% {
      opacity: 1;
    }
  }
  @keyframes status-pulse {
    0%,
    40% {
      opacity: 1;
      animation-timing-function: steps(6);
    }
    50%,
    90% {
      opacity: 0.5;
      animation-timing-function: steps(6);
    }
    100% {
      opacity: 1;
    }
  }
  @keyframes status-ping {
    /* Burst first (immediate feedback for click ripples), then hold
       invisible for the rest of the cycle. Mirrors animate-ping's
       75%-scale start. */
    0% {
      opacity: 0.9;
      scale: 0.75;
      animation-timing-function: steps(8);
    }
    40%,
    100% {
      opacity: 0;
      scale: 2;
    }
  }
}

@utility surface-glass {
  background: color-mix(in srgb, var(--background) var(--glass-opacity), transparent);
  -webkit-backdrop-filter: blur(var(--glass-blur)) saturate(var(--glass-saturation));
  backdrop-filter: blur(var(--glass-blur)) saturate(var(--glass-saturation));

  @supports not ((-webkit-backdrop-filter: blur(1px)) or (backdrop-filter: blur(1px))) {
    background: var(--background) !important;
  }
}

@utility alert-glass {
  --alert-glass-tint: transparent;
  background:
    linear-gradient(
      color-mix(in srgb, var(--alert-glass-tint) 4%, transparent),
      color-mix(in srgb, var(--alert-glass-tint) 4%, transparent)
    ),
    color-mix(in srgb, var(--background) var(--glass-opacity), transparent) !important;
  -webkit-backdrop-filter: blur(var(--glass-blur)) saturate(var(--glass-saturation));
  backdrop-filter: blur(var(--glass-blur)) saturate(var(--glass-saturation));

  &[data-variant="error"] {
    --alert-glass-tint: var(--destructive);
  }

  &[data-variant="info"] {
    --alert-glass-tint: var(--info);
  }

  &[data-variant="success"] {
    --alert-glass-tint: var(--success);
  }

  &[data-variant="warning"] {
    --alert-glass-tint: var(--warning);
  }

  @supports not ((-webkit-backdrop-filter: blur(1px)) or (backdrop-filter: blur(1px))) {
    background: var(--background) !important;
  }
}

/* Paint find results without changing rendered markdown or copied text. */
::highlight(t3-thread-find) {
  color: var(--app-theme-search-match-foreground, oklch(0.216164 0.028283 77.423));
  background-color: var(--app-theme-search-match-background, oklch(0.915 0.11 85));

  @variant dark {
    color: var(--app-theme-search-match-foreground, oklch(0.970151 0 0));
    background-color: var(--app-theme-search-match-background, oklch(0.55 0.1 85));
  }
}

::highlight(t3-thread-find-active) {
  color: var(--app-theme-search-match-active-foreground, oklch(0.216164 0.028283 77.423));
  background-color: var(
    --app-theme-search-match-active-background,
    oklch(0.774202 0.151946 74.331)
  );
}

@utility dialog-glass {
  background: color-mix(in srgb, var(--background) var(--glass-opacity), transparent);
  -webkit-backdrop-filter: blur(var(--glass-blur)) saturate(var(--glass-saturation));
  backdrop-filter: blur(var(--glass-blur)) saturate(var(--glass-saturation));
  border-color: color-mix(in srgb, var(--contrast-foreground) 10%, transparent);
  box-shadow: 0 24px 64px -24px rgb(0 0 0 / 65%);

  @variant dark {
    border-color: color-mix(in srgb, var(--color-white) 8%, transparent);
    box-shadow:
      inset 0 1px rgb(255 255 255 / 4%),
      0 24px 72px -20px rgb(0 0 0 / 90%);
  }

  @supports not ((-webkit-backdrop-filter: blur(1px)) or (backdrop-filter: blur(1px))) {
    background: var(--popover) !important;
  }
}

@utility dialog-backdrop {
  background: color-mix(in srgb, var(--background) 60%, transparent);
  -webkit-backdrop-filter: blur(4px);
  backdrop-filter: blur(4px);

  @variant dark {
    background: color-mix(in srgb, var(--background) 64%, transparent);
  }
}

@utility dropdown-glass {
  background: color-mix(
    in srgb,
    var(--popover) 18%,
    color-mix(in srgb, var(--popover) var(--glass-opacity), transparent)
  );
  -webkit-backdrop-filter: blur(var(--glass-blur)) saturate(var(--glass-saturation));
  backdrop-filter: blur(var(--glass-blur)) saturate(var(--glass-saturation));
  border: 1px solid color-mix(in srgb, var(--contrast-foreground) 10%, transparent);

  @supports not ((-webkit-backdrop-filter: blur(1px)) or (backdrop-filter: blur(1px))) {
    background: var(--popover) !important;
  }
}

@utility topbar-scroll-fade {
  -webkit-mask-image:
    linear-gradient(
      to bottom,
      transparent 0%,
      rgb(0 0 0 / 10%) 10%,
      rgb(0 0 0 / 30%) 24%,
      rgb(0 0 0 / 58%) 42%,
      rgb(0 0 0 / 82%) 62%,
      rgb(0 0 0 / 96%) 82%,
      black 100%
    ),
    linear-gradient(black, black), linear-gradient(black, black);
  -webkit-mask-position: top, bottom, right;
  -webkit-mask-repeat: no-repeat;
  -webkit-mask-size:
    100% calc(var(--workspace-titlebar-scroll-fade-height) + 1px),
    100% calc(100% - var(--workspace-titlebar-scroll-fade-height)),
    var(--app-scrollbar-width) 100%;
  mask-image:
    linear-gradient(
      to bottom,
      transparent 0%,
      rgb(0 0 0 / 10%) 10%,
      rgb(0 0 0 / 30%) 24%,
      rgb(0 0 0 / 58%) 42%,
      rgb(0 0 0 / 82%) 62%,
      rgb(0 0 0 / 96%) 82%,
      black 100%
    ),
    linear-gradient(black, black), linear-gradient(black, black);
  mask-position: top, bottom, right;
  mask-repeat: no-repeat;
  mask-size:
    100% calc(var(--workspace-titlebar-scroll-fade-height) + 1px),
    100% calc(100% - var(--workspace-titlebar-scroll-fade-height)),
    var(--app-scrollbar-width) 100%;
}

/* Virtualizers own their native scroll element, so they cannot use ScrollArea's
   viewport fade. Keep the scrollbar lane opaque while sharing the same fade
   contract across those lists. */
@utility virtualized-scroll-fade {
  -webkit-mask-image: var(--virtualized-scroll-fade-mask), linear-gradient(black, black);
  mask-image: var(--virtualized-scroll-fade-mask), linear-gradient(black, black);
  -webkit-mask-position: left, right;
  mask-position: left, right;
  -webkit-mask-repeat: no-repeat;
  mask-repeat: no-repeat;
  -webkit-mask-size:
    calc(100% - var(--app-scrollbar-width)) 100%,
    var(--app-scrollbar-width) 100%;
  mask-size:
    calc(100% - var(--app-scrollbar-width)) 100%,
    var(--app-scrollbar-width) 100%;
}

/* Stage-channel art needs a mask and pseudo-element gradient, so keep the
   behavior composable without tying it to the global components layer. */
@utility sidebar-stage-backdrop {
  --stage-fade: var(--sidebar-stage-fade, var(--app-chrome-background));
  mask-image: linear-gradient(to bottom, black 0%, black 55%, transparent 92%);
  -webkit-mask-image: linear-gradient(to bottom, black 0%, black 55%, transparent 92%);

  &::after {
    content: "";
    position: absolute;
    inset: 0;
    background: linear-gradient(
      to bottom,
      transparent 0%,
      transparent 28%,
      color-mix(in srgb, var(--stage-fade) 10%, transparent) 40%,
      color-mix(in srgb, var(--stage-fade) 30%, transparent) 52%,
      color-mix(in srgb, var(--stage-fade) 58%, transparent) 64%,
      color-mix(in srgb, var(--stage-fade) 82%, transparent) 75%,
      color-mix(in srgb, var(--stage-fade) 96%, transparent) 85%,
      var(--stage-fade) 93%
    );
  }
}

@keyframes live-tool-shine {
  from {
    background-position:
      -4.5rem 0,
      0 0;
  }
  to {
    background-position:
      calc(100% + 4.5rem) 0,
      0 0;
  }
}

@utility live-tool-shine {
  @media (prefers-reduced-motion: no-preference) and (forced-colors: none) {
    color: transparent;
    background-image:
      linear-gradient(to right, transparent, var(--contrast-foreground), transparent),
      linear-gradient(var(--contrast-secondary-label), var(--contrast-secondary-label));
    background-size:
      4.5rem 100%,
      100% 100%;
    background-repeat: no-repeat;
    background-clip: text;
    animation: live-tool-shine 2.2s steps(30) infinite;
    animation-play-state: var(--visible-animation-state, paused);
  }
}

@utility visible-animate-spin {
  animation: var(--animate-spin);
  animation-play-state: var(--visible-animation-state, paused);
  will-change: var(--visible-animation-will-change, auto);
}

@keyframes live-activity-focus {
  from {
    transform: translateX(0);
  }
  to {
    transform: translateX(100%);
  }
}

@keyframes live-activity-focus-counter {
  from {
    transform: translateX(0);
  }
  to {
    transform: translateX(-100%);
  }
}

@utility live-activity-focus {
  --live-activity-focus-width: 4.5rem;

  right: auto;
  left: calc(-1 * var(--live-activity-focus-width));
  width: calc(100% + var(--live-activity-focus-width) + var(--live-activity-focus-width));
  -webkit-mask-image: linear-gradient(
    to right,
    transparent 0,
    rgb(0 0 0 / 12%) 0.675rem,
    rgb(0 0 0 / 55%) 1.575rem,
    black 2.25rem,
    rgb(0 0 0 / 55%) 2.925rem,
    rgb(0 0 0 / 12%) 3.825rem,
    transparent var(--live-activity-focus-width),
    transparent 100%
  );
  -webkit-mask-repeat: no-repeat;
  mask-image: linear-gradient(
    to right,
    transparent 0,
    rgb(0 0 0 / 12%) 0.675rem,
    rgb(0 0 0 / 55%) 1.575rem,
    black 2.25rem,
    rgb(0 0 0 / 55%) 2.925rem,
    rgb(0 0 0 / 12%) 3.825rem,
    transparent var(--live-activity-focus-width),
    transparent 100%
  );
  mask-repeat: no-repeat;
  animation: live-activity-focus 2.2s linear infinite;
  animation-play-state: var(--visible-animation-state, paused);
  will-change: var(--visible-animation-will-change, auto);

  @media (prefers-reduced-motion: reduce), (forced-colors: active) {
    animation: none;
    opacity: 0;
    will-change: auto;
  }
}

@utility live-activity-focus-counter {
  width: 100%;
  animation: live-activity-focus-counter 2.2s linear infinite;
  animation-play-state: var(--visible-animation-state, paused);
  will-change: var(--visible-animation-will-change, auto);

  @media (prefers-reduced-motion: reduce), (forced-colors: active) {
    animation: none;
    will-change: auto;
  }
}

@utility live-activity-focus-aligned {
  width: calc(100% - var(--live-activity-focus-width) - var(--live-activity-focus-width));
  margin-left: var(--live-activity-focus-width);
}

@property --assistant-citation-highlight-opacity {
  syntax: "<number>";
  inherits: true;
  initial-value: 0;
}

@layer base {
  ::highlight(t3-assistant-citation) {
    background-color: color-mix(
      in oklab,
      var(--primary) calc(var(--assistant-citation-highlight-opacity) * 100%),
      transparent
    );
  }
  ::highlight(t3-assistant-citation-comment) {
    background-color: color-mix(in oklab, var(--primary) 45%, transparent);
  }
  :root {
    /* Keep the original T3 Code artwork palettes as the defaults. Built-in
       themes override them with their own pigments in the components layer. */
    --stage-art-top: oklch(0.782169 0.123386 240.226);
    --stage-art-mid: oklch(0.616111 0.195824 259.735);
    --stage-art-bottom: oklch(0.441553 0.232394 265.474);
    --stage-art-highlight: oklch(0.951597 0.037289 215.482);
    --stage-art-secondary: oklch(0.794668 0.12136 235.46);
    --stage-art-tertiary: oklch(0.678991 0.170261 275.365);
    --stage-art-line: oklch(0.959666 0.029238 218.179);
    --stage-art-celeste-highlight: oklch(0.968763 0.045822 196.42);
    --stage-art-celeste-secondary: oklch(0.827395 0.126071 211.26);
    --stage-art-violet-highlight: oklch(0.895381 0.053248 286.447);
    --stage-art-grid-line: oklch(0.966822 0.01757 239.99);
    --stage-night-base-top: oklch(0.283792 0.117327 297.201);
    --stage-night-base-mid: oklch(0.227147 0.086086 277.99);
    --stage-night-base-bottom: oklch(0.200528 0.055699 261.216);
    --stage-night-top: var(--stage-night-base-top);
    --stage-night-mid: var(--stage-night-base-mid);
    --stage-night-bottom: var(--stage-night-base-bottom);
    --stage-night-highlight: oklch(0.707246 0.157418 252.091);
    --stage-night-secondary: oklch(0.600473 0.182225 277.296);
    --stage-night-tertiary: oklch(0.62583 0.210886 305.994);
    --stage-night-line: oklch(0.938794 0.029114 273.103);
    --stage-night-glow-highlight: oklch(0.553749 0.176543 271.958);
    --stage-night-glow-secondary: oklch(0.345571 0.117466 273.568);
    --stage-night-sparkle: oklch(0.880867 0.057747 269.011);

    @variant dark {
      --stage-art-top: oklch(0.581473 0.149124 256.9);
      --stage-art-mid: oklch(0.456509 0.159377 261.945);
      --stage-art-bottom: oklch(0.291327 0.136578 267.649);
    }
  }

  * {
    @apply border-border outline-ring/50;
  }
  :where([data-slot="menu-popup"], [data-slot="select-popup"], [data-slot="popover-popup"]):focus,
  :where(
    [data-slot="menu-popup"],
    [data-slot="select-popup"],
    [data-slot="popover-popup"]
  ):focus-visible {
    @apply outline-none ring-0;
  }
  html,
  body {
    background-color: var(--app-chrome-background);
  }
  body {
    @apply text-foreground relative;
  }
}

@layer components {
  /* AnimatedHeight owns resizing for its contents. Nested collapsibles must
     expose their final layout immediately, otherwise each animation frame
     restarts the parent's transition and the dialog trails behind its content. */
  [data-slot="animated-height"] [data-slot="collapsible-panel"] {
    height: auto !important;
    transition: none !important;
  }

  [data-slot="animated-height"] [data-slot="collapsible-panel"][data-closed] {
    display: none;
  }

  /* Each maintainer palette gives the same line art its own material: rose
     vellum, forest drafting paper, marine cyanotype, copper, and violet ink.
     These colors stay deliberately deep at the top edge so the white stage
     wordmark and controls retain contrast in both appearance modes. */
  html[data-theme-id="t3-chat"] {
    --stage-art-top: oklch(0.760675 0.141361 348.019);
    --stage-art-mid: oklch(0.588093 0.188832 353.138);
    --stage-art-bottom: oklch(0.383959 0.135096 348.656);
    --stage-art-highlight: oklch(0.949689 0.034241 339.171);
    --stage-art-secondary: oklch(0.763402 0.163836 352.525);
    --stage-art-tertiary: oklch(0.70819 0.180285 311.949);
    --stage-art-line: oklch(0.952158 0.034194 336.179);

    @variant dark {
      --stage-art-top: oklch(0.540689 0.143665 347.587);
      --stage-art-mid: oklch(0.396586 0.126592 347.6);
      --stage-art-bottom: oklch(0.249959 0.079694 340.523);
      --stage-art-highlight: oklch(0.921297 0.051708 343.229);
      --stage-art-secondary: oklch(0.667398 0.165674 352.549);
      --stage-art-tertiary: oklch(0.609315 0.163722 306.315);
      --stage-art-line: oklch(0.945349 0.036045 341.433);
    }
  }

  html[data-theme-id="grove"] {
    --stage-art-top: oklch(0.751465 0.112731 157.313);
    --stage-art-mid: oklch(0.567105 0.11099 158.859);
    --stage-art-bottom: oklch(0.367918 0.067635 160.558);
    --stage-art-highlight: oklch(0.976387 0.034353 161.456);
    --stage-art-secondary: oklch(0.80968 0.117071 158.817);
    --stage-art-tertiary: oklch(0.784102 0.108047 88.516);
    --stage-art-line: oklch(0.981098 0.027812 158.718);
    --stage-night-top: oklch(0.45805 0.079616 160.092);
    --stage-night-mid: oklch(0.368483 0.065631 162.719);
    --stage-night-bottom: oklch(0.264797 0.044397 168.088);
    --stage-night-highlight: oklch(0.912563 0.055173 158.974);
    --stage-night-secondary: oklch(0.665652 0.109731 156.599);
    --stage-night-tertiary: oklch(0.698651 0.103024 89.828);
    --stage-night-line: oklch(0.945336 0.041923 157.222);

    @variant dark {
      --stage-art-top: oklch(0.58719 0.09869 157.426);
      --stage-art-mid: oklch(0.454979 0.079031 159.756);
      --stage-art-bottom: oklch(0.297856 0.050355 161.167);
      --stage-art-highlight: oklch(0.952407 0.053872 158.44);
      --stage-art-secondary: oklch(0.732591 0.120606 155.853);
      --stage-art-tertiary: oklch(0.716282 0.116547 80.563);
      --stage-art-line: oklch(0.961577 0.035285 157.03);
      --stage-night-top: oklch(0.398632 0.065534 158.601);
      --stage-night-mid: oklch(0.290561 0.049694 160.456);
      --stage-night-bottom: oklch(0.210147 0.03173 169.818);
      --stage-night-highlight: oklch(0.866303 0.057526 156.796);
      --stage-night-secondary: oklch(0.586553 0.093722 157.365);
      --stage-night-tertiary: oklch(0.6364 0.101769 82.985);
      --stage-night-line: oklch(0.913292 0.035718 156.976);
    }
  }

  html[data-theme-id="ocean"] {
    --stage-art-top: oklch(0.792993 0.088072 220.421);
    --stage-art-mid: oklch(0.590296 0.116841 243.184);
    --stage-art-bottom: oklch(0.409123 0.093718 247.98);
    --stage-art-highlight: oklch(0.971217 0.023008 213.615);
    --stage-art-secondary: oklch(0.788391 0.090856 215.684);
    --stage-art-tertiary: oklch(0.76441 0.099607 187.893);
    --stage-art-line: oklch(0.976025 0.019647 212.543);

    @variant dark {
      --stage-art-top: oklch(0.59663 0.089167 233.427);
      --stage-art-mid: oklch(0.461094 0.084904 243.478);
      --stage-art-bottom: oklch(0.294818 0.05947 250.526);
      --stage-art-highlight: oklch(0.952907 0.032224 221.27);
      --stage-art-secondary: oklch(0.732079 0.09296 224.414);
      --stage-art-tertiary: oklch(0.720885 0.095495 190.903);
      --stage-art-line: oklch(0.961039 0.027355 219.756);
    }
  }

  html[data-theme-id="ember"] {
    --stage-art-top: oklch(0.782439 0.118806 52.569);
    --stage-art-mid: oklch(0.62863 0.15922 39.401);
    --stage-art-bottom: oklch(0.404251 0.117664 30.424);
    --stage-art-highlight: oklch(0.962469 0.02774 70.95);
    --stage-art-secondary: oklch(0.815735 0.11904 53.659);
    --stage-art-tertiary: oklch(0.69361 0.159346 24.787);
    --stage-art-line: oklch(0.970313 0.02052 67.583);
    --stage-night-top: oklch(0.470236 0.102322 39.355);
    --stage-night-mid: oklch(0.345367 0.080697 33.217);
    --stage-night-bottom: oklch(0.227386 0.056077 27.437);
    --stage-night-highlight: oklch(0.903891 0.059281 56.181);
    --stage-night-secondary: oklch(0.641705 0.126508 44.376);
    --stage-night-tertiary: oklch(0.538694 0.129931 25.865);
    --stage-night-line: oklch(0.926348 0.046029 58.73);

    @variant dark {
      --stage-art-top: oklch(0.597533 0.120694 43.455);
      --stage-art-mid: oklch(0.437763 0.101287 34.86);
      --stage-art-bottom: oklch(0.264269 0.055858 26.548);
      --stage-art-highlight: oklch(0.929214 0.042638 55.801);
      --stage-art-secondary: oklch(0.705592 0.137369 43.176);
      --stage-art-tertiary: oklch(0.629583 0.158322 24.088);
      --stage-art-line: oklch(0.945058 0.033906 58.824);
      --stage-night-top: oklch(0.392352 0.081287 36.444);
      --stage-night-mid: oklch(0.271305 0.056352 31.135);
      --stage-night-bottom: oklch(0.182126 0.028154 27.774);
      --stage-night-highlight: oklch(0.851007 0.061294 53.805);
      --stage-night-secondary: oklch(0.560789 0.10645 42.953);
      --stage-night-tertiary: oklch(0.476228 0.106656 24.165);
      --stage-night-line: oklch(0.884931 0.046607 56.556);
    }
  }

  html[data-theme-id="iris"] {
    --stage-art-top: oklch(0.738305 0.113454 298.926);
    --stage-art-mid: oklch(0.551826 0.159189 294.531);
    --stage-art-bottom: oklch(0.37147 0.133317 289.999);
    --stage-art-highlight: oklch(0.949472 0.029204 303.081);
    --stage-art-secondary: oklch(0.745085 0.125892 298.647);
    --stage-art-tertiary: oklch(0.73066 0.167815 340.964);
    --stage-art-line: oklch(0.960278 0.024064 306.969);

    @variant dark {
      --stage-art-top: oklch(0.57297 0.145973 295.185);
      --stage-art-mid: oklch(0.419499 0.13752 292.131);
      --stage-art-bottom: oklch(0.274235 0.095798 286.608);
      --stage-art-highlight: oklch(0.916698 0.047206 300.224);
      --stage-art-secondary: oklch(0.670994 0.13095 296.689);
      --stage-art-tertiary: oklch(0.679357 0.165376 340.439);
      --stage-art-line: oklch(0.940582 0.032921 299.076);
    }
  }

  :is(html[data-theme-id="t3-chat"], html[data-theme-id="ocean"], html[data-theme-id="iris"]) {
    --stage-night-top: color-mix(in oklch, var(--stage-art-top) 38%, var(--stage-night-base-top));
    --stage-night-mid: color-mix(in oklch, var(--stage-art-mid) 38%, var(--stage-night-base-mid));
    --stage-night-bottom: color-mix(
      in oklch,
      var(--stage-art-bottom) 38%,
      var(--stage-night-base-bottom)
    );
    --stage-night-highlight: var(--stage-art-highlight);
    --stage-night-secondary: color-mix(
      in oklch,
      var(--stage-art-secondary) 55%,
      var(--stage-night-mid)
    );
    --stage-night-tertiary: color-mix(
      in oklch,
      var(--stage-art-tertiary) 60%,
      var(--stage-night-top)
    );
    --stage-night-line: color-mix(in oklch, var(--stage-art-line) 82%, oklch(1 0 0));
  }

  :is(
    html[data-theme-id="t3-chat"],
    html[data-theme-id="grove"],
    html[data-theme-id="ocean"],
    html[data-theme-id="ember"],
    html[data-theme-id="iris"]
  ) {
    --stage-art-celeste-highlight: var(--stage-art-highlight);
    --stage-art-celeste-secondary: var(--stage-art-secondary);
    --stage-art-violet-highlight: var(--stage-art-highlight);
    --stage-art-grid-line: var(--stage-art-line);
    --stage-night-glow-highlight: var(--stage-night-highlight);
    --stage-night-glow-secondary: var(--stage-night-secondary);
    --stage-night-sparkle: var(--stage-night-line);
  }

  @keyframes settings-search-target-pulse {
    0%,
    100% {
      box-shadow: 0 0 0 0 transparent;
    }
    50% {
      box-shadow: 0 0 0 2px color-mix(in oklab, var(--color-primary) 70%, transparent);
    }
  }

  [data-settings-page-scroll] div.settings-search-target-pulse,
  [data-settings-page-scroll] section.settings-search-target-pulse > div:first-child {
    animation: settings-search-target-pulse 650ms ease-in-out 2;
    border-radius: 0.75rem;
  }

  /* The pulse is the destination indicator; without it (reduced motion), the
     focus outline takes over, so exactly one indicator shows at a time. */
  [data-settings-page-scroll] .settings-search-target-pulse:focus {
    outline: none;
  }

  .surface-subheader {
    @apply flex h-10 min-h-10 shrink-0 items-center border-b border-border/60 bg-background;
  }

  [data-preview-panel-mode="inline"] [data-right-panel-surface-content] [data-surface-subheader] {
    height: calc(var(--spacing) * 7);
    min-height: calc(var(--spacing) * 7);
    margin-bottom: calc(var(--spacing) * 3);
    border-bottom-color: transparent;
  }

  .chat-content-lane {
    margin-inline: auto;
    width: 100%;
    min-width: 0;
    max-width: var(--chat-content-max-width);
  }

  .messages-timeline-row-frame {
    padding-inline: 0;
  }

  .settings-slider {
    --settings-slider-progress: 0%;
    --settings-slider-fill-offset: 0.5rem;
    --settings-slider-fill-position: calc(
      var(--settings-slider-progress) + var(--settings-slider-fill-offset)
    );
    appearance: none;
    height: 1.5rem;
    background: transparent;
    cursor: pointer;
  }

  .settings-slider::-webkit-slider-runnable-track {
    height: 0.375rem;
    border-radius: 9999px;
    background: linear-gradient(
      to right,
      var(--primary) 0 var(--settings-slider-fill-position),
      color-mix(in srgb, var(--contrast-muted-foreground) 22%, transparent)
        var(--settings-slider-fill-position) 100%
    );
    box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--contrast-border) 55%, transparent);
  }

  .settings-slider::-moz-range-track {
    height: 0.375rem;
    border-radius: 9999px;
    background: color-mix(in srgb, var(--contrast-muted-foreground) 22%, transparent);
    box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--contrast-border) 55%, transparent);
  }

  .settings-slider::-moz-range-progress {
    height: 0.375rem;
    border-radius: 9999px;
    background: var(--primary);
  }

  .settings-slider::-webkit-slider-thumb {
    appearance: none;
    width: 1rem;
    height: 1rem;
    margin-top: -0.3125rem;
    border: 2px solid var(--primary);
    border-radius: 9999px;
    background: var(--background);
    box-shadow: 0 1px 2px color-mix(in srgb, var(--contrast-foreground) 12%, transparent);
    transition:
      transform 120ms ease,
      box-shadow 120ms ease;
  }

  .settings-slider::-moz-range-thumb {
    width: 1rem;
    height: 1rem;
    border: 2px solid var(--primary);
    border-radius: 9999px;
    background: var(--background);
    box-shadow: 0 1px 2px color-mix(in srgb, var(--contrast-foreground) 12%, transparent);
    transition:
      transform 120ms ease,
      box-shadow 120ms ease;
  }

  .settings-slider:hover::-webkit-slider-thumb {
    transform: scale(1.08);
    box-shadow: 0 1px 3px color-mix(in srgb, var(--contrast-foreground) 20%, transparent);
  }

  .settings-slider:hover::-moz-range-thumb {
    transform: scale(1.08);
    box-shadow: 0 1px 3px color-mix(in srgb, var(--contrast-foreground) 20%, transparent);
  }

  .settings-slider:active::-webkit-slider-thumb {
    transform: scale(0.94);
  }

  .settings-slider:active::-moz-range-thumb {
    transform: scale(0.94);
  }

  .settings-slider:focus-visible {
    outline: none;
  }

  .settings-slider:focus-visible::-webkit-slider-thumb {
    box-shadow:
      0 0 0 3px var(--background),
      0 0 0 5px var(--ring);
  }

  .settings-slider:focus-visible::-moz-range-thumb {
    box-shadow:
      0 0 0 3px var(--background),
      0 0 0 5px var(--ring);
  }

  @media (forced-colors: active) {
    .settings-slider {
      appearance: auto;
      accent-color: Highlight;
    }

    .settings-slider::-webkit-slider-runnable-track,
    .settings-slider::-webkit-slider-thumb {
      all: revert;
    }

    .settings-slider::-moz-range-track,
    .settings-slider::-moz-range-progress,
    .settings-slider::-moz-range-thumb {
      all: revert;
    }
  }
}

/* Safe-area inset utilities for surfaces that opt into edge-to-edge rendering.
   Insets resolve to 0 when the browser already constrains the layout viewport
   to the safe area. */
@utility pt-safe {
  padding-top: max(env(safe-area-inset-top), 0px);
}
@utility pb-safe {
  padding-bottom: max(env(safe-area-inset-bottom), 0px);
}
@utility pl-safe {
  padding-left: max(env(safe-area-inset-left), 0px);
}
@utility pr-safe {
  padding-right: max(env(safe-area-inset-right), 0px);
}

/* Grain texture for chrome surfaces that float above the body (see the
   --surface-grain note). Layered over the element's background-color, so it
   composes with bg-* utilities. */
@utility surface-grain {
  background-image: var(--surface-grain);
  background-repeat: repeat;
  background-size: var(--surface-grain-size);
}

/* Suppress all transitions during theme changes */
.no-transitions,
.no-transitions *,
.no-transitions *::before,
.no-transitions *::after {
  transition-duration: 0s !important;
  animation-duration: 0s !important;
}

:root {
  color-scheme: light;
  --radius: 0.625rem;
  --background: var(--color-zinc-25);
  --app-chrome-background: var(--background);
  --toolbar-background: var(--app-chrome-background);
  --toolbar-foreground: var(--foreground);
  --toolbar-border: var(--border);
  --toolbar-control: var(--popover);
  --toolbar-control-foreground: var(--foreground);
  --toolbar-control-hover: var(--accent);
  --surface-raised: color-mix(in srgb, var(--card) 20%, transparent);
  --foreground: var(--color-zinc-800);
  --card: var(--color-white);
  --card-foreground: var(--color-zinc-800);
  --popover: var(--color-white);
  --popover-foreground: var(--color-zinc-800);
  --primary: oklch(0.488 0.217 264);
  --primary-foreground: var(--color-white);
  --secondary: var(--color-zinc-50);
  --secondary-foreground: var(--color-zinc-800);
  --muted: var(--color-zinc-50);
  --muted-foreground: var(--color-zinc-500);
  --placeholder: var(--muted-foreground);
  --secondary-label: var(--muted-foreground);
  --icon-muted: var(--muted-foreground);
  --message-surface: var(--accent);
  --message-foreground: var(--foreground);
  --message-action: var(--primary);
  --message-action-foreground: var(--primary-foreground);
  --message-action-hover: color-mix(in srgb, var(--primary) 90%, var(--background));
  --accent: var(--color-zinc-100);
  --accent-foreground: var(--color-zinc-900);
  --error: var(--color-red-500);
  --error-foreground: var(--color-red-700);
  --tool-error-icon: var(--error);
  --error-surface: color-mix(in srgb, var(--error) 8%, transparent);
  --destructive: var(--error);
  --border: var(--color-zinc-200);
  --input: var(--color-zinc-300);
  --ring: var(--primary);
  --destructive-foreground: var(--error-foreground);
  --info: var(--color-blue-500);
  --info-foreground: var(--color-blue-700);
  --success: var(--color-emerald-500);
  --success-foreground: var(--color-emerald-700);
  --warning: var(--color-amber-500);
  --warning-foreground: var(--color-amber-700);
  --warning-surface: color-mix(in srgb, var(--warning) 8%, transparent);
  --update: var(--primary);
  --update-foreground: var(--primary);
  --update-surface: color-mix(in srgb, var(--update) 12%, transparent);
  /* Keep every sidebar primitive on the same light surface hierarchy, including
     portaled mobile sheets and settings navigation outside the app sidebar. */
  --sidebar: var(--color-zinc-50);
  --sidebar-foreground: var(--foreground);
  --sidebar-muted-foreground: var(--muted-foreground);
  --sidebar-control-surface: var(--color-zinc-100);
  --sidebar-row-hover: var(--color-zinc-25);
  --sidebar-row-active: var(--color-white);
  --sidebar-row-selected: var(--color-white);
  --sidebar-border: var(--border);
  --sidebar-stage-fade: var(--sidebar);
  --code-background: color-mix(in srgb, var(--card) 90%, var(--background));
  --code-foreground: var(--foreground);
  --terminal-background: var(--background);
  --terminal-foreground: var(--foreground);
  --terminal-cursor: rgb(38 56 78);
  --terminal-selection-background: rgb(37 63 99 / 20%);

  @variant dark {
    color-scheme: dark;
    /* Keep controls and floating surfaces close to the neutral-black canvas.
       Borders and hover states provide separation without milky gray fills. */
    --background: var(--color-neutral-950);
    --surface-raised: color-mix(in srgb, var(--background) 97%, var(--color-white));
    --foreground: var(--color-neutral-100);
    --card: color-mix(in srgb, var(--background) 97%, var(--color-white));
    --card-foreground: var(--color-neutral-100);
    --popover: color-mix(in srgb, var(--background) 97%, var(--color-white));
    --popover-foreground: var(--color-neutral-100);
    --primary: oklch(0.571 0.21 264);
    --secondary: --alpha(var(--color-white) / 3%);
    --secondary-foreground: var(--color-neutral-100);
    --muted: --alpha(var(--color-white) / 3%);
    --muted-foreground: color-mix(in srgb, var(--color-neutral-500) 90%, var(--color-white));
    --accent: --alpha(var(--color-white) / 4%);
    --accent-foreground: var(--color-neutral-100);
    --error: color-mix(in srgb, var(--color-red-500) 90%, var(--color-white));
    --error-foreground: var(--color-red-400);
    --tool-error-icon: #fca5a5;
    --error-surface: color-mix(in srgb, var(--error) 16%, transparent);
    --border: --alpha(var(--color-white) / 6%);
    --input: --alpha(var(--color-white) / 8%);
    --info-foreground: var(--color-blue-400);
    --success-foreground: var(--color-emerald-400);
    --warning-foreground: var(--color-amber-400);
    --warning-surface: color-mix(in srgb, var(--warning) 16%, transparent);
    --update-foreground: var(--color-blue-400);
    --update-surface: color-mix(in srgb, var(--update) 18%, transparent);
    --sidebar: var(--card);
    --sidebar-control-surface: var(--muted);
    --sidebar-row-hover: var(--accent);
    --sidebar-row-active: var(--accent);
    --sidebar-row-selected: var(--muted);
    --sidebar-stage-fade: var(--card);
    --terminal-cursor: rgb(180 203 255);
    --terminal-selection-background: rgb(180 203 255 / 25%);
  }
}

/* Keep both sidebar implementations (default and legacy) on the same quiet
   zinc hierarchy: zinc-50 navigation, zinc-25 hover, and white selected/raised
   surfaces. */
[data-app-sidebar] {
  --background: var(--color-zinc-25);
  --foreground: var(--color-zinc-800);
  --card: var(--color-white);
  --card-foreground: var(--color-zinc-800);
  --accent: var(--color-zinc-100);
  --accent-foreground: var(--color-zinc-900);
  --muted: var(--color-zinc-50);
  --muted-foreground: var(--color-zinc-500);
  --border: var(--color-zinc-200);
  --input: var(--color-zinc-300);
  --sidebar: var(--color-zinc-50);
  --sidebar-foreground: var(--color-zinc-800);
  --sidebar-muted-foreground: var(--color-zinc-500);
  --sidebar-control-surface: var(--color-zinc-100);
  --sidebar-row-hover: var(--color-zinc-25);
  --sidebar-row-active: var(--color-white);
  --sidebar-row-selected: var(--color-white);
  --sidebar-border: var(--color-zinc-200);
  --sidebar-stage-fade: var(--sidebar);

  @variant dark {
    --background: #000;
    --foreground: #f1f3f7;
    --card: #000;
    --card-foreground: var(--foreground);
    --accent: #191a1d;
    --accent-foreground: #f7f9ff;
    --muted: #0a0a0a;
    --muted-foreground: #a3a3a3;
    --border: rgb(255 255 255 / 8%);
    --input: rgb(255 255 255 / 18%);
    --sidebar: var(--card);
    --sidebar-foreground: var(--foreground);
    --sidebar-muted-foreground: var(--muted-foreground);
    --sidebar-control-surface: var(--muted);
    --sidebar-row-hover: color-mix(in srgb, var(--contrast-foreground) 8%, transparent);
    --sidebar-row-active: color-mix(in srgb, var(--contrast-foreground) 11%, transparent);
    --sidebar-row-selected: color-mix(in srgb, var(--contrast-foreground) 7%, transparent);
    --sidebar-border: var(--border);
    --sidebar-stage-fade: var(--card);
  }
}

/* Theme files are expressed in app color roles and mapped to the existing
   semantic surface tokens here. Keep this block after the sidebar-version
   compatibility overrides so both navigation implementations receive the
   same palette. Success, info, provider, and channel identity colors remain
   independent; error, warning, and update roles are themeable below. */
/* The non-empty marker adds enough specificity to outrank the generated root
   dark variant without reintroducing raw `.dark` selectors. */
html[data-theme-id]:not([data-theme-id=""]) {
  --background: var(--app-theme-canvas);
  --app-chrome-background: var(--app-theme-chrome);
  --toolbar-background: var(--app-theme-toolbar);
  --toolbar-foreground: var(--app-theme-toolbar-foreground);
  --toolbar-border: var(--app-theme-toolbar-border);
  --toolbar-control: var(--app-theme-toolbar-control);
  --toolbar-control-foreground: var(--app-theme-toolbar-control-foreground);
  --toolbar-control-hover: var(--app-theme-toolbar-control-hover);
  --surface-raised: var(--app-theme-surface-raised);
  --foreground: var(--app-theme-text);
  --card: var(--app-theme-surface);
  --card-foreground: var(--app-theme-text);
  --popover: var(--app-theme-surface-overlay);
  --popover-foreground: var(--app-theme-text);
  /* Solid controls (CTAs, switches, sliders, the send button) all share the
     theme's action color so every "act now" affordance reads consistently;
     the accent keeps driving surfaces, selection, and focus. Palettes without
     a distinct action color make these identical. */
  --primary: var(--app-theme-message-action);
  --primary-foreground: var(--app-theme-message-action-foreground);
  --secondary: var(--app-theme-secondary);
  --secondary-foreground: var(--app-theme-secondary-foreground);
  --muted: var(--app-theme-muted);
  --muted-foreground: var(--app-theme-muted-foreground);
  --placeholder: var(--app-theme-placeholder);
  --secondary-label: var(--app-theme-secondary-label);
  --icon-muted: var(--app-theme-icon-muted);
  --accent: var(--app-theme-accent-surface);
  --accent-foreground: var(--app-theme-accent-surface-foreground);
  --message-surface: var(--app-theme-message-surface);
  --message-foreground: var(--app-theme-message-foreground);
  --message-action: var(--app-theme-message-action);
  --message-action-foreground: var(--app-theme-message-action-foreground);
  --message-action-hover: var(--app-theme-message-action-hover);
  --error: var(--app-theme-error);
  --error-foreground: var(--app-theme-error-foreground);
  --tool-error-icon: var(--error-foreground);
  --error-surface: var(--app-theme-error-surface);
  --destructive: var(--error);
  --destructive-foreground: var(--error-foreground);
  --warning: var(--app-theme-warning);
  --warning-foreground: var(--app-theme-warning-foreground);
  --warning-surface: var(--app-theme-warning-surface);
  --update: var(--app-theme-update);
  --update-foreground: var(--app-theme-update-foreground);
  --update-surface: var(--app-theme-update-surface);
  --border: var(--app-theme-border);
  --input: var(--app-theme-input);
  --ring: var(--app-theme-focus);
  --sidebar: var(--app-theme-sidebar);
  --sidebar-foreground: var(--app-theme-sidebar-foreground);
  --sidebar-muted-foreground: var(--app-theme-sidebar-muted-foreground);
  --sidebar-control-surface: var(--app-theme-sidebar-control-surface);
  --sidebar-row-hover: var(--app-theme-sidebar-row-hover);
  --sidebar-row-active: var(--app-theme-sidebar-row-active);
  --sidebar-row-selected: var(--app-theme-sidebar-row-selected);
  --sidebar-border: var(--app-theme-sidebar-border);
  --sidebar-stage-fade: var(--app-theme-sidebar);
  --code-background: var(--app-theme-code-background);
  --code-foreground: var(--app-theme-code-foreground);
  --terminal-background: var(--app-theme-terminal-background);
  --terminal-foreground: var(--app-theme-terminal-foreground);
  --terminal-cursor: var(--app-theme-terminal-cursor);
  --terminal-selection-background: var(--app-theme-terminal-selection-background);
}

/* Theme-token dependency probes are restored synchronously, before paint. Keep
   transitions from observing the temporary sentinel color in between. */
html[data-theme-token-probe],
html[data-theme-token-probe] *,
html[data-theme-token-probe] *::before,
html[data-theme-token-probe] *::after {
  transition: none !important;
}

#theme-inspector-spotlight {
  position: fixed;
  z-index: 100;
  inset: 0;
  width: 100vw;
  height: 100dvh;
  overflow: visible;
  pointer-events: none;
}

[data-slot="popover-positioner"]:has([data-theme-editor-panel]),
[data-slot="tooltip-positioner"]:has([data-theme-editor-panel]) {
  z-index: 120;
}

.theme-inspector-spotlight-dimmer {
  fill: rgb(2 3 8 / 54%);
}

.theme-inspector-spotlight-glow {
  fill: color-mix(in oklab, var(--ring) 9%, transparent);
  stroke: color-mix(in oklab, var(--ring) 72%, white);
  stroke-width: 2px;
  opacity: 0.92;
  vector-effect: non-scaling-stroke;
}

#theme-inspector-hover {
  position: fixed;
  z-index: 101;
  pointer-events: none;
  background: color-mix(in oklab, var(--ring) 7%, transparent);
  border: 1px solid color-mix(in oklab, var(--ring) 70%, white);
  box-shadow:
    0 0 0 3px color-mix(in oklab, var(--ring) 16%, transparent),
    0 0 18px color-mix(in oklab, var(--ring) 38%, transparent);
}

#theme-inspector-hover [data-theme-inspector-hover-label] {
  position: absolute;
  left: 0;
  max-width: 12rem;
  overflow: hidden;
  padding: 0.2rem 0.45rem;
  border: 1px solid color-mix(in oklab, var(--ring) 48%, var(--contrast-border));
  border-radius: 0.4rem;
  background: var(--popover);
  box-shadow: 0 4px 16px rgb(0 0 0 / 24%);
  color: var(--contrast-popover-foreground);
  font-size: 0.6875rem;
  font-weight: 600;
  line-height: 1rem;
  text-overflow: ellipsis;
  white-space: nowrap;
}

#theme-inspector-hover[data-placement="above"] [data-theme-inspector-hover-label] {
  bottom: calc(100% + 0.35rem);
}

#theme-inspector-hover[data-placement="below"] [data-theme-inspector-hover-label] {
  top: calc(100% + 0.35rem);
}

/* Workspace actions use a small, separate chrome hierarchy. Keeping these
   roles explicit prevents the thread toolbar from falling back to the default
   dark-mode whites while preserving the same theme file across clients. */
html[data-theme-id] [data-chat-header] {
  background-color: var(--toolbar-background);
  color: var(--contrast-toolbar-foreground);
}

html[data-theme-id] [data-chat-header] [data-slot="button"],
html[data-theme-id] [data-chat-header] [data-slot="menu-trigger"],
html[data-theme-id] [data-chat-header] [data-toolbar-control] {
  --control-icon-color: var(--contrast-toolbar-control-foreground);
  background-color: var(--toolbar-control);
  border-color: var(--contrast-toolbar-border);
  color: var(--contrast-toolbar-control-foreground);
}

/* The panel layout toggles stay ghost: they render both inside the header and
   in the titlebar strip, so filling them would make them change appearance as
   the panel opens. They only take the themed foreground; hover and pressed
   keep the base ghost accent. The tooltip trigger's data-slot wins over the
   toggle's when the trigger renders the toggle, so match both. */
html[data-theme-id] [data-panel-layout-controls] [data-slot="toggle"],
html[data-theme-id] [data-panel-layout-controls] [data-slot="tooltip-trigger"],
html[data-theme-id] [data-workspace-titlebar-controls] [data-slot="toggle"],
html[data-theme-id] [data-workspace-titlebar-controls] [data-slot="tooltip-trigger"] {
  --control-icon-color: var(--contrast-toolbar-foreground);
  color: var(--contrast-toolbar-foreground);
}

html[data-theme-id] [data-panel-layout-controls] [data-slot="toggle"]:disabled,
html[data-theme-id] [data-panel-layout-controls] [data-slot="tooltip-trigger"]:disabled,
html[data-theme-id] [data-workspace-titlebar-controls] [data-slot="toggle"]:disabled,
html[data-theme-id] [data-workspace-titlebar-controls] [data-slot="tooltip-trigger"]:disabled {
  --control-icon-color: color-mix(
    in oklab,
    var(--contrast-toolbar-foreground) 55%,
    var(--toolbar-background)
  );
  color: color-mix(in oklab, var(--contrast-toolbar-foreground) 55%, var(--toolbar-background));
}

html[data-theme-id] [data-chat-header] [data-slot="button"]:hover,
html[data-theme-id] [data-chat-header] [data-slot="button"][data-pressed],
html[data-theme-id] [data-chat-header] [data-slot="menu-trigger"]:hover,
html[data-theme-id] [data-chat-header] [data-slot="menu-trigger"][data-pressed],
html[data-theme-id] [data-chat-header] [data-toolbar-control]:hover,
html[data-theme-id] [data-chat-header] [data-toolbar-control][data-pressed] {
  background-color: var(--toolbar-control-hover);
}

html[data-theme-id] [data-chat-header] [data-slot="separator"] {
  background-color: var(--contrast-toolbar-border);
}

/* Chat code blocks join the other code surfaces on the code tokens. The
   default look keeps its secondary/input tints; themed palettes tint those
   surfaces with the accent, which fights syntax highlighting. */
html[data-theme-id] :is(.chat-markdown, .composer-tiptap) .chat-markdown-codeblock {
  background-color: var(--code-background);
  border-color: var(--contrast-border);
  color: var(--code-foreground);
}

html[data-theme-id] .chat-markdown pre {
  background-color: var(--code-background);
  color: var(--code-foreground);
}

html[data-theme-id] :is(.chat-markdown, .composer-tiptap) .chat-markdown-codeblock pre {
  background-color: transparent;
}

html[data-theme-id] :is(.chat-markdown, .composer-tiptap) .chat-markdown-codeblock-header {
  color: color-mix(in srgb, var(--code-foreground) 72%, transparent);
}

/* T3 Chat renders inline code and compact chat artifacts with its translucent
   secondary surface flattened over the light chat canvas. The raw muted and
   secondary tokens are substantially darker than those visible pixels. */
html[data-theme-id="t3-chat"] {
  @variant light {
    & .chat-markdown :not(pre) > code,
    & [data-changed-files-state],
    & [data-changed-files-header] {
      background-color: var(--message-surface);
    }

    & .chat-markdown :not(pre) > code,
    & [data-changed-files-state] {
      border-color: transparent;
    }

    & .chat-markdown :not(pre) > code {
      color: var(--contrast-message-foreground);
    }
  }
}

html[data-theme-id] [data-app-sidebar] {
  --background: var(--app-theme-canvas);
  --foreground: var(--app-theme-text);
  --card: var(--app-theme-surface);
  --card-foreground: var(--app-theme-text);
  --accent: var(--app-theme-accent-surface);
  --accent-foreground: var(--app-theme-accent-surface-foreground);
  --muted: var(--app-theme-muted);
  --muted-foreground: var(--app-theme-muted-foreground);
  --border: var(--app-theme-border);
  --input: var(--app-theme-input);
  --sidebar: var(--app-theme-sidebar);
  --sidebar-foreground: var(--app-theme-sidebar-foreground);
  --sidebar-muted-foreground: var(--app-theme-sidebar-muted-foreground);
  --sidebar-control-surface: var(--app-theme-sidebar-control-surface);
  --sidebar-row-hover: var(--app-theme-sidebar-row-hover);
  --sidebar-row-active: var(--app-theme-sidebar-row-active);
  --sidebar-row-selected: var(--app-theme-sidebar-row-selected);
  --sidebar-border: var(--app-theme-sidebar-border);
  --sidebar-stage-fade: var(--app-theme-sidebar);
  border-color: color-mix(in srgb, var(--contrast-sidebar-foreground) 10%, transparent);

  @variant dark {
    border-color: color-mix(in srgb, var(--contrast-sidebar-foreground) 8%, transparent);
  }
}

/* T3 Chat's panel divider is deliberately pink, and its resize affordance
   keeps that color while hovered. Do not neutralize this branded edge. */
html[data-theme-id="t3-chat"] [data-app-sidebar] {
  @variant dark {
    border-color: var(--contrast-sidebar-border);
  }
}

/* Recompute contrast wherever a subtree owns its own semantic color palette. */
:root,
[data-app-sidebar] {
  --contrast-toolbar-foreground: color-mix(
    in oklab,
    color-mix(
      in oklab,
      var(--toolbar-foreground) var(--appearance-contrast-base),
      var(--toolbar-background)
    ),
    var(--appearance-contrast-target) var(--appearance-contrast-boost)
  );
  --contrast-toolbar-border: color-mix(
    in srgb,
    color-mix(in srgb, var(--toolbar-border) var(--appearance-contrast-base), transparent),
    var(--toolbar-foreground) var(--appearance-contrast-border-boost)
  );
  --contrast-toolbar-control-foreground: color-mix(
    in oklab,
    color-mix(
      in oklab,
      var(--toolbar-control-foreground) var(--appearance-contrast-base),
      var(--toolbar-control)
    ),
    var(--appearance-contrast-target) var(--appearance-contrast-boost)
  );
  --contrast-input: color-mix(
    in srgb,
    color-mix(in srgb, var(--input) var(--appearance-contrast-base), transparent),
    var(--foreground) var(--appearance-contrast-border-boost)
  );
  --contrast-border: color-mix(
    in srgb,
    color-mix(in srgb, var(--border) var(--appearance-contrast-base), transparent),
    var(--foreground) var(--appearance-contrast-border-boost)
  );
  --contrast-foreground: color-mix(
    in oklab,
    color-mix(in oklab, var(--foreground) var(--appearance-contrast-base), var(--background)),
    var(--appearance-contrast-target) var(--appearance-contrast-boost)
  );
  --contrast-muted-foreground: color-mix(
    in oklab,
    color-mix(in oklab, var(--muted-foreground) var(--appearance-contrast-base), var(--background)),
    var(--appearance-contrast-target) var(--appearance-contrast-boost)
  );
  --contrast-placeholder: color-mix(
    in oklab,
    color-mix(in oklab, var(--placeholder) var(--appearance-contrast-base), var(--background)),
    var(--appearance-contrast-target) var(--appearance-contrast-boost)
  );
  --contrast-secondary-label: color-mix(
    in oklab,
    color-mix(in oklab, var(--secondary-label) var(--appearance-contrast-base), var(--background)),
    var(--appearance-contrast-target) var(--appearance-contrast-boost)
  );
  --contrast-icon-muted: color-mix(
    in oklab,
    color-mix(in oklab, var(--icon-muted) var(--appearance-contrast-base), var(--background)),
    var(--appearance-contrast-target) var(--appearance-contrast-boost)
  );
  --contrast-card-foreground: color-mix(
    in oklab,
    color-mix(in oklab, var(--card-foreground) var(--appearance-contrast-base), var(--card)),
    var(--appearance-contrast-target) var(--appearance-contrast-boost)
  );
  --contrast-popover-foreground: color-mix(
    in oklab,
    color-mix(in oklab, var(--popover-foreground) var(--appearance-contrast-base), var(--popover)),
    var(--appearance-contrast-target) var(--appearance-contrast-boost)
  );
  --contrast-accent-foreground: color-mix(
    in oklab,
    color-mix(in oklab, var(--accent-foreground) var(--appearance-contrast-base), var(--accent)),
    var(--appearance-contrast-target) var(--appearance-contrast-boost)
  );
  --contrast-secondary-foreground: color-mix(
    in oklab,
    color-mix(
      in oklab,
      var(--secondary-foreground) var(--appearance-contrast-base),
      var(--secondary)
    ),
    var(--appearance-contrast-target) var(--appearance-contrast-boost)
  );
  --contrast-message-foreground: color-mix(
    in oklab,
    color-mix(
      in oklab,
      var(--message-foreground) var(--appearance-contrast-base),
      var(--message-surface)
    ),
    var(--appearance-contrast-target) var(--appearance-contrast-boost)
  );
  --contrast-sidebar-foreground: color-mix(
    in oklab,
    color-mix(in oklab, var(--sidebar-foreground) var(--appearance-contrast-base), var(--sidebar)),
    var(--appearance-contrast-target) var(--appearance-contrast-boost)
  );
  --contrast-sidebar-muted-foreground: color-mix(
    in oklab,
    color-mix(
      in oklab,
      var(--sidebar-muted-foreground) var(--appearance-contrast-base),
      var(--sidebar)
    ),
    var(--appearance-contrast-target) var(--appearance-contrast-boost)
  );
  --contrast-sidebar-border: color-mix(
    in srgb,
    color-mix(in srgb, var(--sidebar-border) var(--appearance-contrast-base), transparent),
    var(--sidebar-foreground) var(--appearance-contrast-border-boost)
  );
}

body {
  /* Reference the theme token (not a literal stack) so the Settings ->
     Appearance runtime override of --font-sans reaches all interface text. */
  font-family: var(--font-sans);
  margin: 0;
  padding: 0;
}

html,
body {
  min-height: calc(100svh + env(safe-area-inset-top));
  overscroll-behavior: none;
}

body {
  height: 100%;
  overflow: hidden;
}

#root {
  height: 100%;
  width: 100%;
  max-width: 100%;
  overflow-x: hidden;
  overflow-x: clip;
  overflow-y: hidden;
  overscroll-behavior-y: none;
  padding-top: max(env(safe-area-inset-top), 0px);
  padding-right: var(--desktop-window-right-resize-inset);
}

.electron-windows {
  --desktop-window-right-resize-inset: 6px;
}

/* App-chrome grain. Baked into each surface's own background (behind
   content) rather than a fixed overlay on top: a full-viewport overlay
   forces the compositor to re-blend every frame any animation produces,
   which multiplied idle GPU cost. The overlay's 0.035 opacity lives in the
   SVG rect instead. Surfaces that float over the body (e.g. the inset main
   card) must opt in via the surface-grain utility, or they lose the
   grain's subtle brightening and stand out against the body. */
:root {
  --surface-grain: url("data:image/svg+xml,%3Csvg viewBox='0 0 256 256' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)' opacity='0.035'/%3E%3C/svg%3E");
  --surface-grain-size: 256px 256px;
}

/* The live T3 Chat texture is a 128px grayscale tile with a constant 7/255
   alpha. Keep our procedural texture cheap while matching that scale and
   strength for the branded preset. */
html[data-theme-id="t3-chat"] {
  --surface-grain: url("data:image/svg+xml,%3Csvg viewBox='0 0 128 128' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)' opacity='0.02745'/%3E%3C/svg%3E");
  --surface-grain-size: 128px 128px;
}

body {
  background-image: var(--surface-grain);
  background-repeat: repeat;
  background-size: var(--surface-grain-size);
}

pre,
code {
  font-family: var(--font-mono);
}

/* Code blocks in chat carry the size preference. Scoped to chat markdown
   rather than every pre: a global rule would beat text-size utilities and
   inherited sizes on unrelated pre surfaces (terminal previews, approvals).
   Inline code stays relative to its sentence so it never towers over prose;
   diffs and file previews take the size through --diffs-font-size. */
.chat-markdown .chat-markdown-shiki .shiki,
:is(.chat-markdown, .composer-tiptap) pre code {
  font-size: var(--font-size-code, inherit);
}

/* @pierre/diffs surfaces (diffs, file previews, annotatable code, search
   lines) render inside shadow roots but consult these hooks with their own
   literal stacks as fallback. Custom properties inherit across the shadow
   boundary, so defining them once here routes every code surface through the
   appearance font tokens. */
:root {
  --diffs-font-family: var(--font-mono);
  --diffs-header-font-family: var(--font-sans);
}

/* Window drag region (frameless titlebar) */
.drag-region {
  -webkit-app-region: drag;
}

/* Electron 44 inherits app-region. Reset children to the initial value so they
   do not add drag rectangles over fixed controls. Explicit `none` is treated
   as `no-drag` and breaks titlebar dragging; `initial` emits no rectangle.
   The base layer lets explicit drag/no-drag utilities take precedence. */
@layer base {
  .drag-region > * {
    -webkit-app-region: initial;
  }
}

.drag-region button,
.drag-region input,
.drag-region textarea,
.drag-region select,
.drag-region a {
  -webkit-app-region: no-drag;
}

/* Scrollbar styling */
::-webkit-scrollbar {
  width: var(--app-scrollbar-width);
}

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

::-webkit-scrollbar-thumb {
  background: var(--app-scrollbar-thumb);
  border-radius: 3px;
}

::-webkit-scrollbar-thumb:hover {
  background: var(--app-scrollbar-thumb-hover);
}

/* Chat markdown rendering */

.chat-markdown > :first-child {
  margin-top: 0;
}

.chat-markdown > :last-child {
  margin-bottom: 0;
}

.chat-markdown p,
.chat-markdown ul,
.chat-markdown ol,
.chat-markdown blockquote,
.chat-markdown pre,
.chat-markdown .chat-markdown-table-container,
.composer-tiptap ul,
.composer-tiptap ol {
  margin: 0.65rem 0;
}

:is(.chat-markdown, .composer-tiptap) h1,
:is(.chat-markdown, .composer-tiptap) h2,
:is(.chat-markdown, .composer-tiptap) h3,
:is(.chat-markdown, .composer-tiptap) h4,
:is(.chat-markdown, .composer-tiptap) h5,
:is(.chat-markdown, .composer-tiptap) h6 {
  margin: 1.25rem 0 0.5rem;
  font-weight: 600;
  line-height: 1.3;
  color: var(--contrast-foreground);
}

:is(.chat-markdown, .composer-tiptap) h1 {
  font-size: 1.25rem;
}

:is(.chat-markdown, .composer-tiptap) h2 {
  font-size: 1.125rem;
}

:is(.chat-markdown, .composer-tiptap) h3 {
  font-size: 1rem;
}

:is(.chat-markdown, .composer-tiptap) h4,
:is(.chat-markdown, .composer-tiptap) h5,
:is(.chat-markdown, .composer-tiptap) h6 {
  font-size: 0.875rem;
}

:is(.chat-markdown, .composer-tiptap) h6 {
  color: var(--contrast-muted-foreground);
}

:is(.chat-markdown, .composer-tiptap) ul {
  /* Reset for nested uls under a widened ol. --list-gutter is an inherited
     custom property, so without this a task-list under a multi-digit ordered
     list would inherit the outer gutter instead of its own default. */
  --list-gutter: 1.25rem;
  padding-left: 1.25rem;
  list-style-type: disc;
}

/* --list-gutter defaults to the same 1.25rem as .chat-markdown ul, but
   ChatMarkdown's `ol` renderer widens it (via inline style) for lists whose
   widest marker has multiple characters so it isn't clipped by list-style-position:
   outside painting the marker past the padding box. Reset it here too so a
   nested ol without its own widened marker doesn't inherit the outer one. */
:is(.chat-markdown, .composer-tiptap) ol {
  --list-gutter: 1.25rem;
  padding-left: var(--list-gutter, 1.25rem);
  list-style-type: decimal;
}

:is(.chat-markdown, .composer-tiptap) ol > li::marker {
  font-variant-numeric: tabular-nums;
}

/* The composer shows the marker the source has, `3)` or a nested `7.`, not the
   browser counter. Browsers without ::marker content fall back to `start`. */
.composer-tiptap ol > li[data-marker]::marker {
  content: attr(data-marker) " ";
}

:is(.chat-markdown, .composer-tiptap) ul ul {
  list-style-type: circle;
}

:is(.chat-markdown, .composer-tiptap) ul ul ul {
  list-style-type: square;
}

.chat-markdown ol ol {
  list-style-type: lower-alpha;
}

.chat-markdown ol ol ol {
  list-style-type: lower-roman;
}

.chat-markdown li + li {
  margin-top: 0.25rem;
}

/* GitHub-style task lists: the checkbox replaces the list marker. */
.chat-markdown li.task-list-item {
  list-style-type: none;
}

.chat-markdown li.task-list-item input[type="checkbox"] {
  margin: 0 0.35em 0.15em calc(-1 * var(--list-gutter, 1.25rem));
  vertical-align: middle;
}

/* Markdown assumes inline images — GitHub comments lay button images out in a row — and the
   Tailwind preflight's block-level img would stack them one per line. */
.chat-markdown img {
  display: inline-block;
}

.chat-markdown a {
  text-decoration: none;
}

/* File links are Chips and own their color and focus ring. */
.chat-markdown a:not(.chat-markdown-file-link) {
  color: var(--info-foreground);
}

.chat-markdown a:not(.chat-markdown-file-link):hover,
.chat-markdown a:not(.chat-markdown-file-link):focus-visible {
  background-image: radial-gradient(circle, currentcolor 0.75px, transparent 1px);
  background-position: left bottom;
  background-repeat: repeat-x;
  background-size: 4px 2px;
}

:is(.chat-markdown, .composer-tiptap) blockquote {
  border-left: 2px solid var(--contrast-border);
  padding-left: 0.8rem;
  color: var(--contrast-muted-foreground);
}

/* A quote in the composer is text the user is still writing; muting it reads
   as disabled in an input, so the border alone carries the quote. */
.composer-tiptap blockquote {
  margin: 0.65rem 0;
  color: var(--foreground);
}

/* Preflight already draws the 1px rule, as it does in chat; only the block
   spacing needs to match. */
.composer-tiptap hr {
  margin: 0.65rem 0;
}

/* A heading at the top of a draft should not push the first line down. */
.composer-tiptap :is(h1, h2, h3, h4, h5, h6):first-child {
  margin-top: 0;
}

.chat-markdown section[data-footnotes] {
  margin-top: 1.25rem;
  border-top: 1px solid var(--contrast-border);
  padding-top: 0.75rem;
  color: var(--contrast-muted-foreground);
  font-size: 0.75rem;
}

.chat-markdown section[data-footnotes] ol {
  margin: 0;
}

.chat-markdown section[data-footnotes] li + li {
  margin-top: 0.35rem;
}

.chat-markdown a[data-footnote-ref],
.chat-markdown a[data-footnote-backref] {
  display: inline-flex;
  min-width: 1rem;
  align-items: center;
  justify-content: center;
  border-radius: 0.25rem;
  text-decoration: none;
  font-size: 0.6875rem;
  font-weight: 600;
}

.chat-markdown :not(pre) > code {
  border: 1px solid var(--contrast-border);
  border-radius: 0.375rem;
  background: var(--muted);
  padding: 0.1rem 0.35rem;
  color: var(--contrast-foreground);
  font-size: 0.75rem;
}

.chat-markdown pre {
  max-width: 100%;
  overflow-x: auto;
  border: 1px solid var(--contrast-border);
  border-radius: 0.75rem;
  background: var(--muted);
  padding: 0.8rem 0.9rem;
  scrollbar-width: thin;
  scrollbar-color: color-mix(in srgb, var(--contrast-border) 78%, transparent) transparent;
}

.chat-markdown pre code {
  border: none;
  background: transparent;
  padding: 0;
}

.chat-markdown pre::-webkit-scrollbar {
  height: 7px;
}

.chat-markdown pre::-webkit-scrollbar-thumb {
  border-radius: 999px;
  background: color-mix(in srgb, var(--contrast-border) 78%, transparent);
}

:is(.chat-markdown, .composer-tiptap) .chat-markdown-codeblock-header {
  color: color-mix(in srgb, var(--contrast-foreground) 72%, transparent);
}

:is(.chat-markdown, .composer-tiptap) .chat-markdown-codeblock pre {
  margin: 0;
  border: none;
  border-radius: 0;
  background: transparent;
}

:is(.chat-markdown, .composer-tiptap) .chat-markdown-codeblock[data-wrap="true"] pre {
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}

:is(.chat-markdown, .composer-tiptap) .chat-markdown-shiki .shiki {
  background: transparent !important;
}

/* Paragraphs and code blocks arrive in chunks while a response streams. Fade
   each new block in so the chunk does not pop. @starting-style only applies
   when an element is first inserted, and the rule is gated on data-streaming,
   so opening a finished thread never replays the fade. Opacity only, one
   shot, no layout change. */
@media (prefers-reduced-motion: no-preference) {
  .chat-markdown[data-streaming] > *,
  .chat-markdown[data-streaming] .chat-markdown-shiki {
    transition: opacity 600ms ease-out;

    @starting-style {
      opacity: 0;
    }
  }
}

/* Diagnostics-style tables: row separators only, uppercase headers, and a
   scroll-fade container for horizontal overflow. The root chat-markdown
   wrapping rules (overflow-wrap: anywhere) would let columns shrink to single
   characters and defeat the overflow — restore word-boundary wrapping so the
   min column width is the longest word. */
.chat-markdown table {
  width: 100%;
  min-width: max-content;
  border-collapse: collapse;
  overflow-wrap: normal;
  word-break: normal;
  font-size: 0.75rem;
}

.chat-markdown th,
.chat-markdown td {
  padding: 0.45rem 0.75rem;
  text-align: left;
}

.chat-markdown thead th {
  border-bottom: 1px solid color-mix(in srgb, var(--contrast-border) 60%, transparent);
  padding-block: 0.55rem;
  font-weight: 600;
  white-space: nowrap;
}

.chat-markdown tbody td {
  border-bottom: 1px solid color-mix(in srgb, var(--contrast-border) 60%, transparent);
}

/* Collapsed (default): single-line cells truncate so arbitrary chat content
   cannot blow the column out; the footer toggle expands cells to wrap. */
.chat-markdown .chat-markdown-table-container[data-expanded="false"] th,
.chat-markdown .chat-markdown-table-container[data-expanded="false"] td {
  overflow: hidden;
  max-width: 24rem;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.chat-markdown .chat-markdown-table-container[data-expanded="true"] td {
  max-width: 24rem;
  overflow-wrap: anywhere;
}

:root {
  --diff-addition: var(--success);
  --diff-deletion: var(--destructive);
  --diff-addition-foreground: light-dark(var(--color-emerald-600), var(--color-emerald-400));
  --diff-deletion-foreground: light-dark(var(--color-red-600), var(--color-red-400));
}

/* Chat width setting. Comfortable keeps the default --chat-content-max-width,
   which sizes the timeline lane, the composer, and ChatCanvas's width probe. */
:root[data-chat-width="wide"] {
  --chat-content-max-width: 72rem;
}

:root[data-chat-width="full"] {
  --chat-content-max-width: 100%;
}

:root[data-diff-color-scheme="blue-orange"] {
  --diff-addition: light-dark(var(--color-blue-600), var(--color-blue-400));
  --diff-deletion: light-dark(var(--color-orange-600), var(--color-orange-400));
  --diff-addition-foreground: var(--diff-addition);
  --diff-deletion-foreground: var(--diff-deletion);
  --diffs-addition-color-override: var(--diff-addition);
  --diffs-deletion-color-override: var(--diff-deletion);
  --trees-status-added-override: var(--diff-addition);
  --trees-status-deleted-override: var(--diff-deletion);
  --trees-status-untracked-override: var(--diff-addition);
  --trees-git-added-color-override: var(--diff-addition);
  --trees-git-deleted-color-override: var(--diff-deletion);
  --trees-git-untracked-color-override: var(--diff-addition);
}

.diff-render-surface diffs-container {
  border: 0;
  border-radius: 0;
  overflow: clip;
  background: var(--code-background);
  color: var(--code-foreground);
}

/* Pierre's find panel and match highlights read these. */
.diff-render-surface {
  --diffs-search-panel-bg: var(--popover);
  --diffs-search-panel-fg: var(--popover-foreground);
  --diffs-search-panel-accent: var(--primary);
  --diffs-search-panel-font: var(--font-sans);
}

/* Pierre's file renderer owns its own surface tokens. Keep the root of a file
   preview on the same themeable code surface as the diff panel. */
.diff-render-surface diffs-container,
.file-preview-virtualizer diffs-container {
  --diffs-bg: var(--code-background) !important;
  --diffs-light-bg: var(--code-background) !important;
  --diffs-dark-bg: var(--code-background) !important;
  background-color: var(--code-background) !important;
  color: var(--code-foreground) !important;
}

.ultrathink-frame {
  --ultrathink-spectrum: linear-gradient(
    120deg,
    #ff6b6b 0%,
    #f59e0b 18%,
    #22c55e 36%,
    #14b8a6 54%,
    #3b82f6 72%,
    #ec4899 90%,
    #ff6b6b 100%
  );
  position: relative;
}

.ultrathink-frame::before {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  padding: 2px;
  background-image: var(--ultrathink-spectrum);
  background-size: 220% 220%;
  background-position: 0% 50%;
  pointer-events: none;
  filter: saturate(0.82) brightness(0.92);
  -webkit-mask:
    linear-gradient(#000 0 0) content-box,
    linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
  mask:
    linear-gradient(#000 0 0) content-box,
    linear-gradient(#000 0 0);
  mask-composite: exclude;
}

.ultrathink-frame > * {
  position: relative;
}

.ultrathink-chroma {
  filter: saturate(1.2);
}

@keyframes preview-loading-progress {
  from {
    transform: scaleX(0.04);
  }

  to {
    transform: scaleX(0.9);
  }
}

.preview-loading-progress {
  opacity: 0;
  transform: scaleX(1);
  transition:
    transform 150ms ease-out,
    opacity 150ms ease-out 220ms;
}

.preview-loading-progress[data-loading="true"] {
  opacity: 1;
  animation: preview-loading-progress 5.3s cubic-bezier(0.1, 0.5, 0.2, 1) forwards;
}

@media (prefers-reduced-motion: reduce) {
  .preview-loading-progress,
  .preview-loading-progress[data-loading="true"] {
    transition: none;
    animation: none;
  }

  .preview-loading-progress[data-loading="true"] {
    transform: scaleX(0.9);
  }
}

/* Let the sortable rows open label clearance before painting the dividers.
   This runs once per pickup; rows retain dnd-kit's normal 200ms transitions. */
.sidebar-drag-boundary-label {
  animation: sidebar-drag-label-reveal 200ms step-end;
}

@keyframes sidebar-drag-label-reveal {
  from {
    visibility: hidden;
  }
  to {
    visibility: visible;
  }
}

/* Rich text composer (Tiptap). The stored prompt stays markdown; only the
   surface renders styled text. Markers (** * ` ~~) appear as non-editable
   widgets while the caret is on styled text. */
.composer-tiptap {
  position: relative;
}

.composer-tiptap p {
  margin: 0;
}

.composer-tiptap:focus,
.composer-tiptap .ProseMirror:focus {
  outline: none;
}

.composer-tiptap :not(pre) > code {
  font-family: var(--font-mono);
  font-size: 0.92em;
  background: color-mix(in oklab, var(--muted-foreground) 12%, transparent);
  border-radius: 0.3em;
  padding: 0.05em 0.25em;
}

.composer-rich-marker {
  color: var(--muted-foreground);
  opacity: 0.75;
  font-weight: 400;
  font-style: normal;
  text-decoration: none;
  user-select: none;
  pointer-events: none;
}

/* Selected chips (node selection from arrowing into or clicking a chip). */
.composer-tiptap .ProseMirror-selectednode {
  outline: 2px solid var(--ring);
  outline-offset: 1px;
  border-radius: 6px;
}

.composer-tiptap .composer-chip-range-selected {
  position: relative;
}

.composer-tiptap.ProseMirror-focused .composer-chip-range-selected::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: 6px;
  background: Highlight;
  opacity: 0.3;
  pointer-events: none;
}

/* Rich-text task lists render as real checkboxes. Tiptap's TaskItem NodeView
   builds the <li> imperatively with only a data-checked attribute (no
   data-type), so items are targeted that way. Indentation comes from list
   nesting (two spaces per level from Tab), matching the stored Markdown. */
.composer-tiptap ul[data-type="taskList"] {
  list-style: none;
  margin: 0;
  padding: 0;
}

.composer-tiptap ul[data-type="taskList"] ul[data-type="taskList"] {
  padding-left: 1.375rem;
}

.composer-tiptap li[data-checked] {
  display: flex;
  align-items: flex-start;
  gap: 0.5rem;
  margin: 0;
  padding: 0;
}

.composer-tiptap li[data-checked] > label {
  display: flex;
  align-items: center;
  flex: none;
  height: 1lh;
  cursor: pointer;
}

.composer-tiptap li[data-checked] > label input[type="checkbox"] {
  display: block;
  margin: 0;
  width: 0.95rem;
  height: 0.95rem;
  cursor: pointer;
}

.composer-tiptap li[data-checked] > div {
  flex: 1 1 auto;
  min-width: 0;
}

.composer-tiptap li[data-checked] > div > p {
  margin: 0;
}

@layer components {
  .chat-composer-lane {
    padding-inline-start: calc(
      env(safe-area-inset-left) + 0.75rem + var(--chat-lane-inset-start, 0px)
    );
    padding-inline-end: calc(
      env(safe-area-inset-right) + 0.75rem + var(--chat-lane-inset-end, 0px)
    );
  }
  [data-chat-canvas] .messages-timeline-scroll {
    padding-inline-start: calc(
      0.75rem + var(--chat-lane-inset-start, 0px) - var(--chat-timeline-gutter, 0px)
    );
    padding-inline-end: calc(
      0.75rem + var(--chat-lane-inset-end, 0px) - var(--chat-timeline-gutter, 0px)
    );
  }
  .chat-scroll-to-bottom {
    inset-inline-start: var(--chat-lane-inset-start, 0px);
    inset-inline-end: var(--chat-lane-inset-end, 0px);
  }
  @media (min-width: 640px) {
    .chat-composer-lane {
      padding-inline-start: calc(
        env(safe-area-inset-left) + 1.25rem + var(--chat-lane-inset-start, 0px)
      );
      padding-inline-end: calc(
        env(safe-area-inset-right) + 1.25rem + var(--chat-lane-inset-end, 0px)
      );
    }
    [data-chat-canvas] .messages-timeline-scroll {
      padding-inline-start: calc(
        1.25rem + var(--chat-lane-inset-start, 0px) - var(--chat-timeline-gutter, 0px)
      );
      padding-inline-end: calc(
        1.25rem + var(--chat-lane-inset-end, 0px) - var(--chat-timeline-gutter, 0px)
      );
    }
  }
}

```
