@import 'tailwindcss'; @import 'tw-shimmer'; /*---break--- */ @custom-variant dark (&:is(.dark *)); /** * @theme inline bridges runtime CSS variables (--dt-*) set by the * ThemeProvider into Tailwind utility tokens. Every time the theme * switches, ThemeProvider writes new --dt-* values onto :root and * all Tailwind utilities (bg-background, text-muted-foreground, …) * update automatically — no class rewrite needed. */ @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); --font-sans: var(--dt-font-sans); --font-mono: var(--dt-font-mono); --spacing-mul: var(--dt-spacing-mul, 1); --radius-sm: max(0rem, calc(var(--radius) - 0.25rem)); --radius-md: max(0rem, calc(var(--radius) - 0.125rem)); --radius-lg: var(--radius); --radius-xl: calc(var(--radius) + 0.25rem); --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 — derived from the foreground so it warms/cools with the theme. */ --shadow-ink: var(--dt-foreground); --shadow-sidebar: 0.0625rem 0 0.125rem 0 color-mix(in srgb, #000 4%, transparent), 0.5rem 0 1.5rem -1rem color-mix(in srgb, #000 5%, transparent), 1.25rem 0 3rem -2rem color-mix(in srgb, #000 6%, transparent); --shadow-header: 0 0.5rem 0.875rem -0.375rem color-mix(in srgb, var(--dt-background) 96%, transparent), 0 1.25rem 2rem -0.875rem color-mix(in srgb, var(--dt-background) 82%, transparent), 0 2rem 3rem -1.5rem color-mix(in srgb, var(--dt-background) 55%, transparent); --shadow-composer: 0 0 0 0.0625rem color-mix(in srgb, var(--shadow-ink) 4%, transparent), 0 0.0625rem 0.25rem color-mix(in srgb, var(--shadow-ink) 3%, transparent); --shadow-composer-focus: 0 0 0 0.125rem color-mix(in srgb, var(--dt-ring) 14%, transparent), 0 0 0 0.0625rem color-mix(in srgb, var(--dt-ring) 26%, transparent), 0 0.1875rem 0.625rem color-mix(in srgb, var(--shadow-ink) 4%, transparent); --shadow-user-message: 0 0.0625rem 0.125rem color-mix(in srgb, var(--shadow-ink) 6%, transparent), 0 0.25rem 0.75rem color-mix(in srgb, var(--shadow-ink) 4%, transparent); } @layer base { :root { color-scheme: dark; /* Fallback values (Claude Light theme) — ThemeProvider overwrites on mount. */ --dt-background: #f7f7f7; --dt-foreground: #242424; --dt-card: #ffffff; --dt-card-foreground: #242424; --dt-muted: #f0f0ef; --dt-muted-foreground: #737373; --dt-popover: #ffffff; --dt-popover-foreground: #242424; --dt-primary: #cf806d; --dt-primary-foreground: #ffffff; --dt-secondary: #f1f1f0; --dt-secondary-foreground: #2d2d2d; --dt-accent: #eeeeed; --dt-accent-foreground: #242424; --dt-border: #dfdfdc; --dt-input: #ddddda; --dt-ring: #b97969; --dt-destructive: #b94a3a; --dt-destructive-foreground: #ffffff; --dt-sidebar-bg: #fafafa; --dt-sidebar-border: #e2e2df; --dt-user-bubble: #f2f2f1; --dt-user-bubble-border: #dededb; --dt-font-sans: -apple-system, BlinkMacSystemFont, 'SF Pro Text', 'Segoe UI', system-ui, sans-serif; --dt-font-mono: 'SF Mono', ui-monospace, 'Cascadia Code', Menlo, Consolas, monospace; --dt-base-size: 0.9375rem; --dt-line-height: 1.55; --dt-letter-spacing: 0; --dt-spacing-mul: 1; --radius: 0.75rem; /* Thread ViewportFooter — gap from last msg → composer (scroll only) */ --thread-composer-clearance: 8rem; /* Composer geometry — single source of truth for shell + controls. */ --composer-shell-pad-block-end: 2.5rem; --composer-inline-clearance: clamp(1rem, 5vw, 4rem); --composer-min-width: 34rem; --composer-target-width: 68%; --composer-max-width: 56rem; --composer-control-size: 2rem; --composer-control-gap: 0.375rem; --composer-row-gap: 0.375rem; --composer-surface-pad-x: 0.5rem; --composer-surface-pad-y: 0.375rem; --composer-input-min-height: 2rem; --composer-input-max-height: 9.375rem; --composer-input-inline-min-width: 8rem; --composer-fallback-height: 2.75rem; --vsq: min(0.5vh, 0.5vw); --image-preview-max-width: 34rem; --image-preview-height: clamp(16.25rem, calc(var(--vsq) * 100), 26.25rem); /* Shell layout */ --sidebar-width: 14rem; --chat-min-width: 24rem; --shell-gap: 0.625rem; --titlebar-control-size: 1.25rem; --titlebar-control-height: 1.375rem; --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(--dt-accent); --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(--dt-sidebar-border) 42%, transparent); } :root.dark { --sidebar-edge-border: color-mix(in srgb, var(--dt-sidebar-border) 78%, transparent); --shadow-sidebar: 0.0625rem 0 0.125rem 0 color-mix(in srgb, #000 82%, transparent), 0.75rem 0 1.75rem -1rem color-mix(in srgb, #000 72%, transparent), 1.5rem 0 3rem -1.75rem color-mix(in srgb, #000 62%, transparent); } * { box-sizing: border-box; border-color: var(--dt-border); } html, body, #root { height: 100%; } html { font-size: var(--dt-base-size, 0.9375rem); } body { margin: 0; background: var(--dt-background); color: var(--dt-foreground); font-family: var(--dt-font-sans); 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; } } button { -webkit-app-region: no-drag; } 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; } * { scrollbar-width: thin; scrollbar-color: color-mix(in srgb, var(--dt-muted-foreground) 32%, transparent) transparent; } *::-webkit-scrollbar { width: 0.5rem; height: 0.5rem; } *::-webkit-scrollbar-track, *::-webkit-scrollbar-corner { background: transparent; } *::-webkit-scrollbar-thumb { background: color-mix(in srgb, var(--dt-muted-foreground) 32%, transparent); border-radius: 9999px; border: 0.125rem solid transparent; background-clip: padding-box; } *::-webkit-scrollbar-thumb:hover { background: color-mix(in srgb, var(--dt-muted-foreground) 55%, transparent); background-clip: padding-box; } *::-webkit-scrollbar-button { display: none; } /* * Previously applied `content-visibility: auto` + `contain-intrinsic-size` to * message roots for virtualization-lite perf. REMOVED because it interacts * badly with a stick-to-bottom scroller: * * 1. Session loads, messages render at their real heights. * 2. Scroller pins to `scrollHeight - clientHeight`. * 3. A few seconds later the browser's content-visibility heuristic kicks * in for off-screen messages and collapses them to the 10rem intrinsic * placeholder — shrinking total scrollHeight by a large margin. * 4. The browser clamps scrollTop to the new (smaller) scrollHeight, and * the user's viewport "scrolls up by a weird %" a few seconds after * the session loads. Feels like a scroll bug; actually CSS. * * If we want perf here again, the correct path is a real virtualizer (e.g. * react-virtuoso) with stable item sizing — not a CSS heuristic. */ .aui-md img { display: block; width: auto; height: auto; max-width: min(100%, var(--image-preview-max-width)); max-height: var(--image-preview-height); object-fit: contain; border: 0.0625rem solid color-mix(in srgb, var(--dt-border) 70%, transparent); border-radius: 1.125rem; box-shadow: 0 0.0625rem 0.125rem color-mix(in srgb, #000 4%, transparent), 0 0.625rem 1.5rem color-mix(in srgb, #000 5%, transparent); } .aui-md [data-slot='aui_markdown-image'] { max-width: min(100%, var(--image-preview-max-width)); } .aui-md { overflow-wrap: anywhere; } .hermes-preview-webview { display: flex; } [data-slot='composer-root'] { width: clamp(var(--composer-min-width), var(--composer-target-width), var(--composer-max-width)); max-width: calc(100% - var(--composer-inline-clearance)); transform: translateX(-50%); } /* Thread scroll container (from use-stick-to-bottom). * `scroll-behavior: auto` is critical: use-stick-to-bottom writes scrollTop * directly and temporarily forces this to 'auto' during its programmatic * scrolls, but we default it to 'auto' anyway so no smooth-scroll fight can * ever happen. We leave overflow-anchor at the browser default ('auto'); the * library handles follow-mode imperatively. */ [data-slot='aui_thread-content'] { scroll-behavior: auto; } .aui-md a, .aui-md code { overflow-wrap: anywhere; word-break: break-word; } .aui-md p:has(> img:only-child) { margin-block: 0.75rem; } .aui-md p:has(> [data-slot='aui_markdown-image']:only-child) { margin-block: 0.75rem; } /** * Markdown rhythm. Streamdown's wrapper
blocks `> *` selectors and * its bundled `space-y-4` lives in node_modules (unscanned by Tailwind v4), * so we drive everything from descendant selectors against tags. Each * block gets a uniform `margin-bottom`; headings add `margin-top` for * section breaks. Margin collapse picks the larger neighbor — producing * "more above headings, less below" without per-pair rules. */ .aui-md p, .aui-md ul, .aui-md ol, .aui-md blockquote, .aui-md pre, .aui-md table, .aui-md [data-streamdown='code-block'], .aui-md div:has(> table) { margin: 0 0 1rem; } /* Streamdown wraps every fenced block in
* with `flex flex-col gap-2 p-2 border bg-sidebar rounded-xl my-4`. Our own * CodeHeader + SyntaxHighlighter already supply the chrome, so undo the * library's wrapper to keep the header flush with the code body. */ .aui-md [data-streamdown='code-block'], [data-streamdown='code-block'] { padding: 0 !important; gap: 0 !important; border: 0 !important; background: transparent !important; border-radius: 0 !important; margin: 1rem 0 !important; } .aui-md [data-streamdown='code-block'] > *, [data-streamdown='code-block'] > * { margin: 0 !important; } .aui-md h1 { margin: 1.6rem 0 0.55rem; } .aui-md h2 { margin: 1.4rem 0 0.5rem; } .aui-md h3 { margin: 1.15rem 0 0.45rem; } .aui-md h4 { margin: 0.95rem 0 0.4rem; } .aui-md hr { margin: 1.5rem 0; } /* `padding-left` keeps outside-position list markers in the gutter. */ .aui-md ul, .aui-md ol { padding-left: 1.75rem; } /* Tight inter-bullet gap; loose items override below. */ .aui-md li + li { margin-top: 0.375rem; } /* Inside a bullet, hug nested blocks to the lead text. */ .aui-md li > p { margin-bottom: 0.4rem; } .aui-md li > ul, .aui-md li > ol { margin-top: 0.4rem; } /* Loose list items (CommonMark wraps each in

when any sibling has a block child) need visible separation — the tight rhythm collapses against a trailing heavy block like a code fence. */ .aui-md li:has(> p) { margin-bottom: 0.85rem; } .aui-md li:has(> p):last-child { margin-bottom: 0; } /* Trim edge margins at the container, list items, and blockquotes. */ .aui-md > :first-child, .aui-md > * > :first-child, .aui-md li > :first-child, .aui-md blockquote > :first-child { margin-top: 0; } .aui-md > :last-child, .aui-md > * > :last-child, .aui-md li > :last-child, .aui-md blockquote > :last-child { margin-bottom: 0; }