hermes-agent/apps/desktop/src/styles.css
Brooklyn Nicholson cbc1d901ba chore: uptick
2026-06-02 23:44:51 -05:00

1040 lines
33 KiB
CSS

@import 'tailwindcss';
@plugin '@tailwindcss/typography';
@import 'tw-shimmer';
@import 'katex/dist/katex.min.css';
@import '@vscode/codicons/dist/codicon.css';
@custom-variant dark (&:is(.dark *));
@font-face {
font-family: 'Collapse';
font-style: normal;
font-weight: 700;
font-display: swap;
src: url('../../../node_modules/@nous-research/ui/dist/fonts/Collapse-Bold.woff2') format('woff2');
}
@theme inline {
--color-background: var(--dt-background);
--color-foreground: var(--dt-foreground);
--color-card: var(--dt-card);
--color-card-foreground: var(--dt-card-foreground);
--color-muted: var(--dt-muted);
--color-muted-foreground: var(--dt-muted-foreground);
--color-popover: var(--dt-popover);
--color-popover-foreground: var(--dt-popover-foreground);
--color-primary: var(--dt-primary);
--color-primary-foreground: var(--dt-primary-foreground);
--color-secondary: var(--dt-secondary);
--color-secondary-foreground: var(--dt-secondary-foreground);
--color-accent: var(--dt-accent);
--color-accent-foreground: var(--dt-accent-foreground);
--color-border: var(--dt-border);
--color-input: var(--dt-input);
--color-ring: var(--dt-ring);
--color-destructive: var(--dt-destructive);
--color-destructive-foreground: var(--dt-destructive-foreground);
--color-midground: var(--dt-midground);
--color-midground-foreground: var(--dt-midground-foreground);
--font-sans: var(--dt-font-sans);
--font-mono: var(--dt-font-mono);
--spacing-mul: var(--dt-spacing-mul, 1);
--radius-xs: calc(var(--radius-scalar) * 0.125rem);
--radius-sm: calc(var(--radius-scalar) * 0.5rem);
--radius-md: calc(var(--radius-scalar) * 0.625rem);
--radius-lg: calc(var(--radius-scalar) * 0.75rem);
--radius-xl: calc(var(--radius-scalar) * 1rem);
--radius-2xl: calc(var(--radius-scalar) * 1.5rem);
--radius-3xl: calc(var(--radius-scalar) * 2rem);
--radius-4xl: calc(var(--radius-scalar) * 2.5rem);
--color-sidebar-ring: var(--sidebar-ring);
--color-sidebar-border: var(--sidebar-border);
--color-sidebar-accent-foreground: var(--sidebar-accent-foreground);
--color-sidebar-accent: var(--sidebar-accent);
--color-sidebar-primary-foreground: var(--sidebar-primary-foreground);
--color-sidebar-primary: var(--sidebar-primary);
--color-sidebar-foreground: var(--sidebar-foreground);
--color-sidebar: var(--sidebar);
--shadow-ink: var(--dt-foreground);
--shadow-xs: 0 0.0625rem 0.125rem color-mix(in srgb, #000 5%, transparent);
--shadow-sm:
0 0 0 0.0625rem color-mix(in srgb, var(--dt-foreground) 6%, transparent),
0 0.125rem 0.5rem color-mix(in srgb, #000 4%, transparent);
--shadow-md:
0 0 0 0.0625rem color-mix(in srgb, var(--dt-foreground) 8%, transparent),
0 0.25rem 1rem color-mix(in srgb, #000 8%, transparent),
0 1rem 2rem -1.5rem color-mix(in srgb, #000 18%, transparent);
--shadow-lg:
inset 0 0.0625rem 0 color-mix(in srgb, #fff 28%, transparent),
0 0 0 0.0625rem color-mix(in srgb, var(--dt-foreground) 8%, transparent),
0 0.75rem 2rem color-mix(in srgb, #000 12%, transparent);
--shadow-header:
0 0.0625rem 0 color-mix(in srgb, var(--dt-foreground) 7%, transparent),
0 0.625rem 1.5rem -1.25rem color-mix(in srgb, #000 16%, transparent);
--shadow-composer: 0 0.0625rem 0.125rem color-mix(in srgb, #000 5%, transparent);
--shadow-composer-focus:
0 0 0 0.125rem color-mix(in srgb, var(--dt-composer-ring) calc(10% * var(--composer-ring-strength)), transparent),
0 0 0 0.0625rem color-mix(in srgb, var(--dt-composer-ring) calc(22% * var(--composer-ring-strength)), transparent),
0 0.25rem 0.875rem color-mix(in srgb, #000 8%, transparent),
0 0.75rem 2rem -1.25rem color-mix(in srgb, #000 14%, transparent);
}
@layer base {
:root {
color-scheme: light;
--theme-foreground: #17171a;
--theme-primary: #0053fd;
--theme-secondary: color-mix(in srgb, #0053fd 7%, #ffffff);
--theme-accent-soft: color-mix(in srgb, #0053fd 10%, #ffffff);
--theme-midground: #0053fd;
--theme-warm: #cf806d;
--theme-background-seed: #f8faff;
--theme-sidebar-seed: #f3f7ff;
--theme-card-seed: #ffffff;
--theme-elevated-seed: #ffffff;
--theme-bubble-seed: color-mix(in srgb, #0053fd 6%, #ffffff);
--theme-neutral-chrome: #f3f3f3;
--theme-neutral-sidebar: #f3f3f3;
--theme-neutral-card: #fcfcfc;
--theme-mix-chrome: 92%;
--theme-mix-sidebar: 100%;
--theme-mix-card: 22%;
--theme-mix-elevated: 28%;
--theme-mix-bubble: 0%;
--theme-fill-primary-accent-mix: 16%;
--theme-fill-secondary-accent-mix: 11%;
--theme-fill-tertiary-accent-mix: 8%;
--theme-fill-quaternary-accent-mix: 5%;
--theme-fill-quinary-accent-mix: 3%;
--theme-stroke-primary-accent-mix: 24%;
--theme-stroke-secondary-accent-mix: 16%;
--theme-stroke-tertiary-accent-mix: 10%;
--theme-stroke-quaternary-accent-mix: 6%;
--theme-row-hover-accent-mix: 4%;
--theme-row-active-accent-mix: 8%;
--theme-control-hover-accent-mix: 6%;
--theme-control-active-accent-mix: 8%;
--ui-base: var(--theme-foreground);
--ui-accent: var(--theme-midground);
--ui-accent-secondary: var(--theme-primary);
--ui-warm: var(--theme-warm);
--ui-red: #cf2d56;
--ui-orange: #db704b;
--ui-yellow: #c08532;
--ui-green: #1f8a65;
--ui-cyan: #4c7f8c;
--ui-blue: #0053fd;
--ui-purple: #9e94d5;
--ui-bg-chrome: color-mix(
in srgb,
var(--theme-background-seed) var(--theme-mix-chrome),
var(--theme-neutral-chrome)
);
--ui-bg-sidebar: color-mix(
in srgb,
var(--theme-sidebar-seed) var(--theme-mix-sidebar),
var(--theme-neutral-sidebar)
);
--ui-bg-editor: color-mix(in srgb, var(--theme-card-seed) var(--theme-mix-card), var(--theme-neutral-card));
--ui-bg-elevated: color-mix(
in srgb,
var(--theme-elevated-seed) var(--theme-mix-elevated),
var(--theme-neutral-card)
);
--ui-bg-card: color-mix(in srgb, var(--ui-accent) 4%, color-mix(in srgb, var(--ui-base) 4%, transparent));
--ui-bg-input: #fcfcfc;
--ui-bg-primary: color-mix(
in srgb,
var(--ui-accent) var(--theme-fill-primary-accent-mix),
color-mix(in srgb, var(--ui-base) 10%, transparent)
);
--ui-bg-secondary: color-mix(
in srgb,
var(--ui-accent) var(--theme-fill-secondary-accent-mix),
color-mix(in srgb, var(--ui-base) 7%, transparent)
);
--ui-bg-tertiary: color-mix(
in srgb,
var(--ui-accent) var(--theme-fill-tertiary-accent-mix),
color-mix(in srgb, var(--ui-base) 5%, transparent)
);
--ui-bg-quaternary: color-mix(
in srgb,
var(--ui-accent) var(--theme-fill-quaternary-accent-mix),
color-mix(in srgb, var(--ui-base) 4%, transparent)
);
--ui-bg-quinary: color-mix(
in srgb,
var(--ui-accent) var(--theme-fill-quinary-accent-mix),
color-mix(in srgb, var(--ui-base) 3%, transparent)
);
--ui-row-hover-background: color-mix(
in srgb,
var(--ui-accent) var(--theme-row-hover-accent-mix),
color-mix(in srgb, var(--ui-base) 3%, transparent)
);
--ui-row-active-background: color-mix(
in srgb,
var(--ui-accent) var(--theme-row-active-accent-mix),
color-mix(in srgb, var(--ui-base) 5%, transparent)
);
--ui-control-hover-background: color-mix(
in srgb,
var(--ui-accent) var(--theme-control-hover-accent-mix),
color-mix(in srgb, var(--ui-base) 4%, transparent)
);
--ui-control-active-background: color-mix(
in srgb,
var(--ui-accent) var(--theme-control-active-accent-mix),
color-mix(in srgb, var(--ui-base) 5%, transparent)
);
--ui-text-primary: color-mix(in srgb, var(--ui-base) 94%, transparent);
--ui-text-secondary: color-mix(in srgb, var(--ui-base) 74%, transparent);
--ui-text-tertiary: color-mix(in srgb, var(--ui-base) 54%, transparent);
--ui-text-quaternary: color-mix(in srgb, var(--ui-base) 36%, transparent);
--ui-stroke-primary: color-mix(
in srgb,
var(--ui-accent) var(--theme-stroke-primary-accent-mix),
color-mix(in srgb, var(--ui-base) 10%, transparent)
);
--ui-stroke-secondary: color-mix(
in srgb,
var(--ui-accent) var(--theme-stroke-secondary-accent-mix),
color-mix(in srgb, var(--ui-base) 7%, transparent)
);
--ui-stroke-tertiary: color-mix(
in srgb,
var(--ui-accent) var(--theme-stroke-tertiary-accent-mix),
color-mix(in srgb, var(--ui-base) 5%, transparent)
);
--ui-stroke-quaternary: color-mix(
in srgb,
var(--ui-accent) var(--theme-stroke-quaternary-accent-mix),
color-mix(in srgb, var(--ui-base) 3%, transparent)
);
--ui-sash-hover-border: color-mix(in srgb, var(--ui-accent) 18%, var(--ui-stroke-tertiary));
--ui-sash-hover-background: color-mix(in srgb, var(--ui-accent) 6%, transparent);
--ui-surface-background: var(--ui-bg-editor);
--ui-sidebar-surface-background: var(--ui-bg-sidebar);
--ui-chat-surface-background: var(--ui-bg-chrome);
--ui-editor-surface-background: var(--ui-bg-chrome);
--ui-chat-bubble-background: color-mix(
in srgb,
var(--theme-bubble-seed) var(--theme-mix-bubble),
var(--theme-neutral-card)
);
--ui-chat-bubble-opaque-background: var(--ui-bg-editor);
--ui-inline-code-background: color-mix(in srgb, #141414 5%, transparent);
--ui-inline-code-border: color-mix(in srgb, #141414 8%, transparent);
--ui-inline-code-foreground: color-mix(in srgb, #141414 88%, transparent);
--ui-selection-background: color-mix(in srgb, #ffd24a 55%, transparent);
--dt-background: var(--ui-bg-chrome);
--dt-foreground: var(--ui-text-primary);
--dt-card: var(--ui-bg-editor);
--dt-card-foreground: var(--ui-text-primary);
--dt-muted: var(--ui-bg-tertiary);
--dt-muted-foreground: var(--ui-text-tertiary);
--dt-popover: color-mix(in srgb, var(--ui-bg-elevated) 96%, transparent);
--dt-popover-foreground: var(--ui-text-primary);
--dt-primary: var(--theme-primary);
--dt-primary-foreground: #fcfcfc;
--dt-secondary: var(--theme-secondary);
--dt-secondary-foreground: var(--ui-text-secondary);
--dt-accent: var(--theme-accent-soft);
--dt-accent-foreground: var(--ui-text-primary);
--dt-border: var(--ui-stroke-secondary);
--dt-input: var(--ui-stroke-primary);
--dt-ring: var(--ui-stroke-primary);
--dt-midground: var(--theme-midground);
--dt-composer-ring: var(--ui-base);
--dt-destructive: #cf2d56;
--dt-destructive-foreground: #ffffff;
--dt-sidebar-bg: var(--ui-bg-sidebar);
--dt-sidebar-border: var(--ui-stroke-secondary);
--dt-user-bubble: var(--ui-chat-bubble-background);
--dt-user-bubble-border: var(--ui-stroke-tertiary);
--dt-font-sans: 'Segoe WPC', 'Segoe UI', -apple-system, BlinkMacSystemFont, 'SF Pro Text', system-ui, sans-serif;
--dt-font-mono: 'Cascadia Code', 'JetBrains Mono', 'SF Mono', ui-monospace, Menlo, Consolas, monospace;
--dt-base-size: 1rem;
--dt-line-height: 1.5;
--dt-letter-spacing: 0;
--dt-spacing-mul: 1;
--radius: 0.75rem;
--radius-scalar: 0.6;
/* Space under last message vs overlay composer — driven by the measured composer height (see composer/index.tsx). */
--thread-last-message-clearance: calc(var(--composer-measured-height) + 2rem);
--composer-shell-pad-block-end: 0.625rem;
--message-text-indent: 0.75rem;
--conversation-text-font-size: 0.8125rem;
--conversation-tool-font-size: var(--conversation-text-font-size);
--conversation-caption-font-size: 0.75rem;
--conversation-line-height: 1.125rem;
--conversation-caption-line-height: 1rem;
--conversation-turn-gap: 0.375rem;
--sticky-human-top: 0.23rem;
--file-tree-row-height: 1.375rem;
--composer-width: 48.75rem;
--composer-control-size: 1.75rem;
--composer-control-primary-size: 1.875rem;
--composer-control-gap: 0.25rem;
--composer-row-gap: 0.25rem;
--composer-ring-strength: 1;
--composer-surface-pad-x: 0.5rem;
--composer-surface-pad-y: 0.3125rem;
--composer-input-min-height: 1.625rem;
--composer-input-max-height: 9.375rem;
--composer-input-inline-min-width: 8rem;
--composer-fallback-height: 2.75rem;
--composer-measured-height: calc(0.5rem + var(--composer-shell-pad-block-end) + var(--composer-fallback-height));
--composer-surface-measured-height: var(--composer-fallback-height);
--thread-viewport-height: max(
0rem,
calc(100% - var(--composer-measured-height) + var(--composer-surface-measured-height))
);
--vsq: min(0.5vh, 0.5vw);
--image-preview-max-width: 34rem;
--image-preview-height: clamp(16.25rem, calc(var(--vsq) * 100), 26.25rem);
--sidebar-width: 14.8125rem;
--chat-min-width: 28rem;
--titlebar-control-size: 1.25rem;
--titlebar-control-height: 1.375rem;
--sidebar-content-inline-padding: 1rem;
--sidebar: var(--dt-sidebar-bg);
--sidebar-foreground: var(--dt-foreground);
--sidebar-primary: var(--dt-primary);
--sidebar-primary-foreground: var(--dt-primary-foreground);
--sidebar-accent: var(--ui-control-active-background);
--sidebar-accent-foreground: var(--dt-accent-foreground);
--sidebar-border: var(--dt-sidebar-border);
--sidebar-ring: var(--dt-ring);
--sidebar-edge-border: color-mix(in srgb, var(--ui-base) 7.5%, transparent);
--chrome-action-hover: var(--ui-control-hover-background);
--midground: var(--dt-midground);
--background: var(--dt-background);
--foreground: var(--dt-foreground);
--warm-glow: color-mix(in srgb, var(--ui-warm) 32%, color-mix(in srgb, var(--ui-accent) 6%, transparent));
/* `--noise-opacity-mul` is set per-mode by `applyTheme()`. */
--noise-opacity-mul: 1;
--backdrop-invert-mul: 1;
}
:root.dark {
/* Per-mode mix knobs — overridden inline by `applyTheme()` per skin. */
--theme-mix-chrome: 74%;
--theme-mix-card: 38%;
--theme-mix-elevated: 46%;
--theme-mix-bubble: 46%;
--theme-neutral-chrome: #0d0d0e;
--theme-neutral-sidebar: #0a0a0b;
--theme-neutral-card: #161618;
/* Dark-only accent palette overrides. */
--ui-red: #e75e78;
--ui-green: #55a583;
--ui-cyan: #6f9ba6;
--sidebar-edge-border: color-mix(in srgb, var(--ui-base) 12%, transparent);
--composer-ring-strength: 1.3;
--backdrop-invert-mul: 0;
--ui-inline-code-background: color-mix(in srgb, #ffffff 7%, transparent);
--ui-inline-code-border: color-mix(in srgb, #ffffff 10%, transparent);
--ui-inline-code-foreground: color-mix(in srgb, #ffffff 88%, transparent);
--ui-selection-background: color-mix(in srgb, #ffd24a 38%, transparent);
}
* {
box-sizing: border-box;
border-color: var(--dt-border);
}
html,
body,
#root {
height: 100%;
}
html {
font-size: var(--dt-base-size, 0.875rem);
}
body {
margin: 0;
background: var(--ui-chat-surface-background);
color: var(--dt-foreground);
font-family: var(--dt-font-sans);
font-size: 0.8125rem;
line-height: var(--dt-line-height, 1.55);
letter-spacing: var(--dt-letter-spacing, 0);
overflow: hidden;
-webkit-user-select: none;
user-select: none;
-webkit-font-smoothing: antialiased;
}
button,
textarea {
font: inherit;
}
:where(
a,
.underline,
[class~='hover:underline'],
[class~='focus:underline'],
[class~='focus-visible:underline'],
[class~='group-hover:underline'],
[class~='peer-hover:underline']
) {
text-decoration-color: color-mix(in srgb, currentColor 20%, transparent);
text-underline-offset: 0.25rem;
}
*::selection {
background: var(--ui-selection-background);
color: inherit;
}
}
.dither {
background: repeating-conic-gradient(currentColor 0% 25%, transparent 0% 50%) 0 0 / 0.125rem 0.125rem;
}
:root:not([style*='--theme-asset-bg:']) .theme-default-filler {
display: block;
}
:root[style*='--theme-asset-bg:'] .theme-default-filler {
display: none;
}
@layer utilities {
[class*='rounded-full'],
[class*=':rounded-full'] {
border-radius: calc(var(--radius-scalar) * 9999rem);
}
}
@keyframes arc-border {
0% {
background-position: 15% 15%;
}
100% {
background-position: 75% 75%;
}
}
.arc-border {
--arc-c0: color-mix(in srgb, var(--dt-foreground) 0%, transparent);
--arc-c1: var(--dt-midground);
--arc-c2: var(--dt-background);
--arc-angle: 160deg;
--arc-width: 0.078125rem;
--arc-inset: -0.125rem;
--arc-duration: 2.23s;
pointer-events: none;
position: absolute;
overflow: hidden;
border-radius: inherit;
inset: var(--arc-inset);
padding: var(--arc-width);
mask:
linear-gradient(#000 0 0) content-box,
linear-gradient(#000 0 0);
-webkit-mask-composite: xor;
mask-composite: exclude;
}
:root.dark .arc-border {
--arc-c1: var(--dt-foreground);
}
.arc-border::before {
content: '';
position: absolute;
inset: 0;
border-radius: inherit;
background: linear-gradient(
var(--arc-angle),
transparent 0%,
var(--arc-c0) 15%,
var(--arc-c1) 20%,
var(--arc-c2) 25%,
transparent 35%,
transparent 40%,
var(--arc-c0) 55%,
var(--arc-c1) 60%,
var(--arc-c2) 65%,
transparent 75%,
transparent 80%,
var(--arc-c0) 95%,
var(--arc-c1) 100%
);
background-size: 300% 300%;
animation: arc-border var(--arc-duration) linear infinite;
}
@media (prefers-reduced-motion: reduce) {
.arc-border::before {
animation: none;
}
}
button {
-webkit-app-region: no-drag;
}
[data-slot='button'] {
box-shadow: none;
transition-duration: 100ms;
}
[data-slot='button'][data-variant='outline'],
[data-slot='button'][data-variant='secondary'] {
border-color: var(--ui-stroke-secondary);
background: var(--ui-bg-tertiary);
color: var(--ui-text-primary);
}
[data-slot='button'][data-variant='ghost'] {
color: var(--ui-text-secondary);
}
[data-slot='button'][data-variant='outline']:hover,
[data-slot='button'][data-variant='secondary']:hover,
[data-slot='button'][data-variant='ghost']:hover {
background: var(--chrome-action-hover);
color: var(--ui-text-primary);
}
[data-slot='dropdown-menu-content'],
[data-slot='select-content'],
[data-slot='dialog-content'] {
border-color: var(--ui-stroke-secondary);
background: color-mix(in srgb, var(--ui-bg-elevated) 96%, transparent);
box-shadow: var(--shadow-md);
backdrop-filter: blur(0.75rem) saturate(1.08);
-webkit-backdrop-filter: blur(0.75rem) saturate(1.08);
}
[data-slot='dropdown-menu-item']:focus,
[data-slot='dropdown-menu-checkbox-item']:focus,
[data-slot='dropdown-menu-radio-item']:focus {
background: var(--ui-bg-tertiary);
color: var(--ui-text-primary);
}
input,
textarea,
[contenteditable]:not([contenteditable='false']),
[data-slot='aui_user-message-root'],
[data-slot='aui_assistant-message-content'],
[data-selectable-text='true'],
[data-selectable-text='true'] * {
-webkit-user-select: text;
user-select: text;
}
button,
[role='button'] {
-webkit-user-select: none;
user-select: none;
}
img,
picture,
video,
canvas,
svg {
-webkit-user-select: none;
user-select: none;
}
img,
video,
canvas {
-webkit-user-drag: none;
}
/* Shared input chrome — mirrors composer hover/focus FX. Unlayered to beat Tailwind utilities. */
.desktop-input-chrome {
--ring-pct: 18%;
--ring-fall: var(--dt-input);
background: color-mix(in srgb, var(--dt-card) 68%, transparent);
border-color: color-mix(
in srgb,
var(--dt-composer-ring) calc(var(--ring-pct) * var(--composer-ring-strength)),
var(--ring-fall)
);
box-shadow: var(--shadow-composer);
transition:
background-color 200ms ease-out,
border-color 200ms ease-out,
box-shadow 200ms ease-out;
}
.desktop-input-chrome:hover {
--ring-pct: 30%;
background: color-mix(in srgb, var(--dt-card) 86%, transparent);
}
.desktop-input-chrome:focus {
--ring-pct: 45%;
--ring-fall: transparent;
background: var(--dt-card);
box-shadow: var(--shadow-composer-focus);
outline: none;
}
.desktop-input-chrome[aria-invalid='true'] {
border-color: var(--dt-destructive);
}
.desktop-input-chrome[aria-invalid='true']:focus {
box-shadow:
0 0 0 0.125rem color-mix(in srgb, var(--dt-destructive) 18%, transparent),
0 0 0 0.0625rem color-mix(in srgb, var(--dt-destructive) 34%, transparent),
0 0.1875rem 0.625rem color-mix(in srgb, var(--dt-destructive) 12%, transparent);
}
@layer components {
.scrollbar-dt,
.scrollbar-dt * {
scrollbar-width: thin;
scrollbar-color: color-mix(in srgb, var(--dt-midground) 18%, transparent) transparent;
}
.scrollbar-dt::-webkit-scrollbar,
.scrollbar-dt *::-webkit-scrollbar {
width: 0.5rem;
height: 0.5rem;
}
.scrollbar-dt::-webkit-scrollbar-track,
.scrollbar-dt::-webkit-scrollbar-corner,
.scrollbar-dt *::-webkit-scrollbar-track,
.scrollbar-dt *::-webkit-scrollbar-corner {
background: transparent;
}
.scrollbar-dt::-webkit-scrollbar-thumb,
.scrollbar-dt *::-webkit-scrollbar-thumb {
background: color-mix(in srgb, var(--dt-midground) 18%, transparent);
border-radius: 9999rem;
border: 0.125rem solid transparent;
background-clip: padding-box;
}
.scrollbar-dt::-webkit-scrollbar-thumb:hover,
.scrollbar-dt *::-webkit-scrollbar-thumb:hover {
background: color-mix(in srgb, var(--dt-midground) 40%, transparent);
background-clip: padding-box;
}
.scrollbar-dt::-webkit-scrollbar-button,
.scrollbar-dt *::-webkit-scrollbar-button {
display: none;
}
/* Variant for portaled overlays (Radix DropdownMenu, Popover, etc.) that
render under document.body, outside the `.scrollbar-dt` scope on
#root. Same visual treatment, applied directly to the overlay
container so its (and only its) internal scrollbar is themed. */
.dt-portal-scrollbar {
scrollbar-width: thin;
scrollbar-color: color-mix(in srgb, var(--dt-midground) 28%, transparent) transparent;
}
.dt-portal-scrollbar::-webkit-scrollbar {
width: 0.375rem;
height: 0.375rem;
}
.dt-portal-scrollbar::-webkit-scrollbar-track,
.dt-portal-scrollbar::-webkit-scrollbar-corner {
background: transparent;
}
.dt-portal-scrollbar::-webkit-scrollbar-thumb {
background: color-mix(in srgb, var(--dt-midground) 28%, transparent);
border-radius: 9999rem;
border: 0.0625rem solid transparent;
background-clip: padding-box;
}
.dt-portal-scrollbar::-webkit-scrollbar-thumb:hover {
background: color-mix(in srgb, var(--dt-midground) 50%, transparent);
background-clip: padding-box;
}
.dt-portal-scrollbar::-webkit-scrollbar-button {
display: none;
}
}
/* Bottom clearance lives on [data-slot='aui_composer-clearance'] —
virtualized items unmount, so :nth-last-child can't fire reliably. */
[data-slot='aui_assistant-message-content'] {
padding-left: var(--message-text-indent);
font-size: var(--conversation-text-font-size);
line-height: 1.5;
}
[data-slot='aui_assistant-message-root'] {
width: 100%;
}
[data-slot='aui_assistant-message-content'] .aui-md,
[data-slot='aui_assistant-message-content'] .aui-md :where(p, li, blockquote, table, pre) {
font-size: inherit;
}
/* Streamed prose hangs slightly indented from the tool/todo column so the
reading column reads as a "reply" within the conversation gutter. Tools,
todos, and thinking blocks keep the existing --message-text-indent so they
remain flush with the user message text above them. */
[data-slot='aui_assistant-message-content'] > .aui-md {
padding-inline-start: var(--md-text-indent, 0.5rem);
}
[data-slot='aui_user-message-root'] {
top: var(--sticky-human-top);
}
[data-slot='aui_user-message-root'],
[data-slot='aui_edit-composer-root'] {
font-size: var(--conversation-text-font-size);
}
/* Sticky human bubbles clamp to ~2 lines with a soft bottom fade so a long
prompt doesn't dominate the viewport while you read the response stuck
beneath it. The clamp lifts on hover / focus (clicking the bubble opens the
edit composer, which already shows the full text). --human-msg-full is the
measured content height (set in UserMessage) so expand/collapse animates to
the real height instead of overshooting the cap. */
.sticky-human-clamp {
max-height: calc(2 * var(--dt-line-height) * var(--conversation-text-font-size) + 0.15rem);
overflow: hidden;
transition: max-height 0.08s cubic-bezier(0.4, 0, 0.2, 1);
}
.sticky-human-clamp[data-clamped='true'] {
-webkit-mask-image: linear-gradient(to bottom, #000 55%, transparent);
mask-image: linear-gradient(to bottom, #000 55%, transparent);
}
.composer-human-message:hover .sticky-human-clamp,
.composer-human-message:focus-within .sticky-human-clamp {
max-height: min(var(--human-msg-full, 24rem), 24rem);
overflow-y: auto;
-webkit-mask-image: none;
mask-image: none;
}
/* The thread renders items in natural document flow (padding spacers, not
transforms) and @tanstack/react-virtual already adjusts scrollTop itself
when an off-screen turn is measured and its real height differs from the
220px estimate. The browser's native scroll anchoring (overflow-anchor:
auto) would adjust scrollTop for that SAME size delta, so the two
double-correct and the view lurches — most visibly on Windows mouse wheels,
whose coarse notches mount/measure several under-estimated turns per tick.
Opt out of native anchoring so only the virtualizer compensates. */
[data-slot='aui_thread-viewport'] {
overflow-anchor: none;
}
[data-slot='aui_thread-content'] {
max-width: var(--composer-width);
padding-inline: 1.5rem;
}
[data-slot='aui_intro'] {
align-items: center;
justify-content: center;
padding-bottom: var(--composer-measured-height);
text-align: center;
}
[data-slot='aui_intro'] > div {
max-width: min(var(--composer-width), 82vw);
}
[data-slot='aui_intro'] p:last-child {
max-width: 34rem;
margin-inline: auto;
color: var(--ui-text-tertiary);
font-size: 0.875rem;
line-height: 1.45;
}
.fit-text {
display: flex;
font-size: var(--fit-text-min, 1rem);
container-type: inline-size;
--captured-length: initial;
--support-sentinel: var(--captured-length, 9999px);
}
.fit-text > [aria-hidden='true'] {
visibility: hidden;
}
.fit-text > :not([aria-hidden='true']) {
flex-grow: 1;
container-type: inline-size;
--captured-length: 100cqi;
--available-space: var(--captured-length);
}
.fit-text > :not([aria-hidden='true']) > * {
display: block;
inline-size: var(--available-space);
line-height: var(--fit-text-line-height, 1);
--support-sentinel: inherit;
--captured-length: 100cqi;
--ratio: tan(atan2(var(--available-space), var(--available-space) - var(--captured-length)));
--font-size: clamp(
var(--fit-text-min, 1em),
1em * var(--ratio),
var(--fit-text-max, infinity * 1px) - var(--support-sentinel)
);
font-size: var(--font-size);
}
@container (inline-size > 0) {
.fit-text > :not([aria-hidden='true']) > * {
white-space: nowrap;
}
}
@property --captured-length {
syntax: '<length>';
initial-value: 0px;
inherits: true;
}
@property --captured-length2 {
syntax: '<length>';
initial-value: 0px;
inherits: true;
}
[data-slot='composer-root'] {
width: min(var(--composer-width), calc(100% - 2rem));
padding-bottom: var(--composer-shell-pad-block-end);
}
[data-slot='composer-root'] > .pointer-events-none {
background: linear-gradient(
to bottom,
transparent,
color-mix(in srgb, var(--ui-chat-surface-background) 88%, transparent)
) !important;
}
[data-slot='composer-surface'] {
border-color: var(--ui-stroke-secondary) !important;
box-shadow: var(--shadow-composer) !important;
}
[data-slot='composer-fade'] {
min-height: 2.375rem;
}
[data-slot='composer-rich-input'] {
color: var(--ui-text-primary);
font-size: 0.8125rem;
}
[data-slot='composer-rich-input']:empty::before {
color: var(--ui-text-tertiary) !important;
}
[data-slot='composer-root']:focus-within [data-slot='composer-surface'] > [aria-hidden='true'] {
background: var(--ui-chat-bubble-background) !important;
}
/* Tool/thinking blocks now live at message-text alignment (no leading
chevron column to escape into), so their headers and bodies share a
common left edge with the model's text. */
[data-slot='aui_assistant-message-content'] > [data-slot='tool-block'],
[data-slot='aui_assistant-message-content'] > [data-slot='aui_thinking-disclosure'] {
width: 100%;
max-width: 100%;
}
[data-slot='aui_assistant-message-content'] .aui-md [data-streamdown='code-block'] code {
max-width: none;
font-family: inherit;
font-size: inherit;
padding: 0;
border-radius: 0;
background: transparent;
color: inherit;
overflow-x: visible;
overflow-wrap: inherit;
vertical-align: baseline;
word-break: inherit;
white-space: inherit;
}
/* Streamdown's adapter wraps code fences in a `data-streamdown="code-block"`
container with its own card chrome. We render our own <CodeCard>, so this
strips the upstream chrome down to a layout-only passthrough. */
[data-slot='aui_assistant-message-content'] .aui-md [data-streamdown='code-block'] {
contain: none;
overflow: visible;
margin-block: 0.375rem !important;
padding: 0 !important;
gap: 0 !important;
border: 0 !important;
border-radius: 0 !important;
background: transparent !important;
color: inherit;
}
[data-slot='aui_assistant-message-content'] .aui-md [data-streamdown='code-block']:has(.aui-prose-fence) {
margin-block: 0 !important;
}
[data-slot='aui_assistant-message-content'] .aui-md :not(pre) > code {
border: 0.0625rem solid var(--ui-inline-code-border);
background: var(--ui-inline-code-background);
color: var(--ui-inline-code-foreground);
}
[data-slot='aui_assistant-message-content'] .aui-md :where(.aui-shiki, .aui-shiki > pre) {
margin: 0 !important;
}
[data-slot='aui_assistant-message-content'] .aui-md .aui-md-table {
border-spacing: 0;
}
[data-slot='aui_assistant-message-content'] .aui-md .aui-md-table > table,
[data-slot='aui_assistant-message-content'] .aui-md .aui-md-table thead,
[data-slot='aui_assistant-message-content'] .aui-md .aui-md-table tbody,
[data-slot='aui_assistant-message-content'] .aui-md .aui-md-table tr,
[data-slot='aui_assistant-message-content'] .aui-md .aui-md-table th,
[data-slot='aui_assistant-message-content'] .aui-md .aui-md-table td {
margin: 0 !important;
margin-block-start: 0 !important;
margin-block-end: 0 !important;
}
/* Tool / thinking blocks are scaffolding around the model's reply, so we
keep them transparent and fade them slightly. The reading column (prose)
stays at full strength; scaffolding lifts back to full opacity on
hover/focus so it stays legible when the user actually wants to read it. */
[data-slot='tool-block'],
[data-slot='aui_thinking-disclosure'] {
background: transparent !important;
}
[data-slot='aui_assistant-message-content'] > :is([data-slot='tool-block'], [data-slot='aui_thinking-disclosure']) {
opacity: 0.67;
transition: opacity 120ms ease-out;
}
[data-slot='aui_assistant-message-content']
> :is([data-slot='tool-block'], [data-slot='aui_thinking-disclosure']):is(:hover, :focus-within) {
opacity: 1;
}
/* Conversation block rhythm. Consecutive tool calls stay tight so a step
sequence reads as one action group; the gap between any scaffolding
block and adjacent prose bumps up so the model's reply visually
separates from its scaffolding. */
[data-slot='tool-block'] + [data-slot='tool-block'] {
margin-top: 0.375rem;
}
[data-slot='tool-block']:has(> :nth-child(2)) + [data-slot='tool-block'] {
margin-top: 0.625rem;
}
[data-slot='aui_assistant-message-content']
:is([data-slot='tool-block'], [data-slot='aui_thinking-disclosure'])
+ .aui-md,
[data-slot='aui_assistant-message-content']
.aui-md
+ :is([data-slot='tool-block'], [data-slot='aui_thinking-disclosure']) {
margin-top: 1rem;
}
[data-slot='aui_assistant-message-content'] [data-slot='aui_thinking-disclosure'] + [data-slot='tool-block'],
[data-slot='aui_assistant-message-content'] [data-slot='tool-block'] + [data-slot='aui_thinking-disclosure'] {
margin-top: 0.75rem;
}
[data-slot='aui_assistant-message-content'] > [data-slot='tool-block']:first-child {
margin-top: 0;
}
/* Message action bars — flat icon hits with default dim; only the hovered/focused control is full-strength. */
[data-slot='aui_msg-actions'] button {
border: 0;
border-radius: 0;
background: transparent;
box-shadow: none;
padding: 0;
gap: 0;
height: auto;
width: auto;
min-height: 0;
min-width: 0;
flex-shrink: 0;
cursor: pointer;
color: var(--color-muted-foreground);
opacity: 0.5;
}
[data-slot='aui_msg-actions'] button:disabled {
cursor: default;
}
[data-slot='aui_msg-actions'] button:hover {
background: transparent;
color: var(--color-foreground);
opacity: 1;
}
[data-slot='aui_msg-actions'] button:active {
background: transparent;
}
[data-slot='aui_msg-actions'] button:focus-visible {
opacity: 1;
}
[data-slot='aui_msg-actions'] button svg {
width: 0.875rem;
height: 0.875rem;
}
/* Live thinking preview window. Pairs with the ResizeObserver in
ThinkingDisclosure that pins scrollTop to the bottom — older lines fade
into the top mask while the latest tokens settle in below. */
.thinking-preview {
-webkit-mask-image: linear-gradient(to bottom, transparent 0%, black 28%, black 100%);
mask-image: linear-gradient(to bottom, transparent 0%, black 28%, black 100%);
}