@tailwind base; @tailwind components; @tailwind utilities; /* Design tokens — HSL form, sourced from shadcn/ui's "neutral" palette. */ @layer base { :root { color-scheme: light; --background: 0 0% 100%; --foreground: 240 3% 12%; --card: 0 0% 100%; --card-foreground: 240 3% 12%; --popover: 0 0% 100%; --popover-foreground: 240 3% 12%; --primary: 240 4% 16%; --primary-foreground: 0 0% 98%; --secondary: 0 0% 96.1%; --secondary-foreground: 0 0% 9%; --muted: 0 0% 96.1%; --muted-foreground: 0 0% 45.1%; --accent: 0 0% 96.1%; --accent-foreground: 0 0% 9%; --destructive: 0 84.2% 60.2%; --destructive-foreground: 0 0% 98%; --border: 0 0% 89.8%; --input: 0 0% 89.8%; --ring: 0 0% 3.9%; --radius: 0.4375rem; --sidebar: 0 0% 98.5%; --sidebar-foreground: 0 0% 3.9%; --sidebar-accent: 0 0% 95.8%; --sidebar-accent-foreground: 0 0% 9%; --sidebar-border: 0 0% 89.8%; --scrollbar-thumb: hsl(var(--muted-foreground) / 0.26); --scrollbar-thumb-hover: hsl(var(--muted-foreground) / 0.42); } .dark { color-scheme: dark; --background: 0 0% 10%; --foreground: 240 4% 96%; --card: 0 0% 12%; --card-foreground: 240 4% 96%; --popover: 0 0% 12%; --popover-foreground: 240 4% 96%; --primary: 240 5% 98%; --primary-foreground: 0 0% 9%; --secondary: 0 0% 12%; --secondary-foreground: 0 0% 98%; --muted: 0 0% 13%; --muted-foreground: 0 0% 60%; --accent: 0 0% 15%; --accent-foreground: 0 0% 98%; --destructive: 0 62.8% 30.6%; --destructive-foreground: 0 0% 98%; --border: 0 0% 18%; --input: 0 0% 18%; --ring: 0 0% 83.1%; --sidebar: 0 0% 11.5%; --sidebar-foreground: 0 0% 98%; --sidebar-accent: 0 0% 15.5%; --sidebar-accent-foreground: 0 0% 98%; --sidebar-border: 0 0% 18%; --scrollbar-thumb: hsl(var(--muted-foreground) / 0.28); --scrollbar-thumb-hover: hsl(var(--muted-foreground) / 0.44); } } @layer base { * { @apply border-border; } html, body, #root { @apply h-full; } body { @apply bg-background text-foreground font-sans antialiased; } * { scrollbar-color: var(--scrollbar-thumb) transparent; scrollbar-width: thin; } *::-webkit-scrollbar { width: 8px; height: 8px; } *::-webkit-scrollbar-track { background: transparent; } *::-webkit-scrollbar-thumb { background-color: var(--scrollbar-thumb); border-radius: 9999px; } *::-webkit-scrollbar-thumb:hover { background-color: var(--scrollbar-thumb-hover); } *::-webkit-scrollbar-corner { background: transparent; } ::selection { @apply bg-primary/15; } } @layer utilities { .host-drag-region { -webkit-app-region: drag; } .host-no-drag { -webkit-app-region: no-drag; } html.native-host, html.native-host body, html.native-host #root { background: transparent; } html.native-host body { overflow: hidden; } .host-window-shell, .host-sidebar-glass { --host-glass-spot: hsl(var(--background) / 0.42); --host-glass-start: hsl(var(--sidebar) / 0.5); --host-glass-end: hsl(var(--sidebar) / 0.3); background: radial-gradient( circle at 18% 0%, var(--host-glass-spot), transparent 34rem ), linear-gradient( 180deg, var(--host-glass-start), var(--host-glass-end) ); background-attachment: fixed, fixed; -webkit-backdrop-filter: saturate(185%) blur(34px); backdrop-filter: saturate(185%) blur(34px); } .host-sidebar-glass { background: hsl(var(--sidebar) / 0.94); -webkit-backdrop-filter: saturate(145%) blur(18px); backdrop-filter: saturate(145%) blur(18px); box-shadow: inset -1px 0 0 hsl(var(--border) / 0.32), inset 1px 0 0 hsl(var(--background) / 0.52), 14px 0 32px -30px rgb(0 0 0 / 0.22); } .dark .host-window-shell, .dark .host-sidebar-glass { --host-glass-spot: hsl(var(--foreground) / 0.06); --host-glass-start: hsl(var(--sidebar) / 0.48); --host-glass-end: hsl(var(--sidebar) / 0.3); } .dark .host-sidebar-glass { background: hsl(var(--sidebar) / 0.96); box-shadow: inset -1px 0 0 hsl(var(--border) / 0.42), inset 1px 0 0 hsl(var(--foreground) / 0.05), 14px 0 34px -30px rgb(0 0 0 / 0.62); } @supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) { .host-sidebar-glass { background: hsl(var(--sidebar) / 0.92); } } html.native-host * { scrollbar-width: none; scrollbar-gutter: auto !important; } html.native-host *::-webkit-scrollbar { display: none; width: 0; height: 0; } .shadow-inner-right { box-shadow: inset -9px 0 6px -1px rgb(0 0 0 / 0.02); } /* Markdown body styles, ported from agent-chat-ui's markdown-styles.css. */ .markdown-content > :first-child { @apply mt-0; } .markdown-content > :last-child { @apply mb-0; } /* Override Tailwind Typography's built-in colors with our design tokens so assistant messages use the same --foreground as user messages. */ .markdown-content { --tw-prose-body: hsl(var(--foreground)); --tw-prose-headings: hsl(var(--foreground)); --tw-prose-bold: hsl(var(--foreground)); --tw-prose-lead: hsl(var(--foreground)); } .markdown-content .contains-task-list { @apply list-none pl-0; } .markdown-content .task-list-item { @apply list-none pl-0; } /* CJK-friendly line-height: prose paragraphs default to 1.625 which is tight for Chinese/Japanese/Korean characters. Bump to 1.8 for better readability when the browser detects a CJK primary font. */ :lang(zh), :lang(zh-CN), :lang(zh-TW), :lang(zh-HK), :lang(ja), :lang(ko) { --cjk-line-height: 1.8; } :root { --cjk-line-height: 1.625; } /* L→R sheen clipped to live activity labels. The highlight lives inside the glyphs, not in the row background, so dark mode stays quiet. */ @keyframes streaming-text-sheen-ltr { 0% { background-position: 140% 50%; } 100% { background-position: -40% 50%; } } .streaming-text-sheen { position: relative; color: hsl(var(--muted-foreground)); } .file-reference-sheen { color: inherit; } .streaming-text-sheen::after { content: attr(data-sheen-text); position: absolute; inset: 0; display: block; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; pointer-events: none; color: transparent; background: linear-gradient( 90deg, transparent 0%, transparent 38%, hsl(var(--foreground) / 0.98) 50%, transparent 62%, transparent 100% ); background-size: 260% 100%; background-position: 140% 50%; background-repeat: no-repeat; background-clip: text; -webkit-background-clip: text; -webkit-text-fill-color: transparent; animation: streaming-text-sheen-ltr 2.8s ease-in-out infinite; } .dark .streaming-text-sheen::after { background-image: linear-gradient( 90deg, transparent 0%, transparent 38%, hsl(var(--foreground) / 0.98) 50%, transparent 62%, transparent 100% ); } @media (prefers-reduced-motion: reduce) { .streaming-text-sheen::after { animation: none; content: ""; } } @keyframes composer-status-strip-enter { 0% { max-height: 0; opacity: 0; transform: translateY(10px) scale(0.985); } 72% { max-height: var(--composer-strip-max-height, 46px); opacity: 1; transform: translateY(-1px) scale(1.004); } 100% { max-height: var(--composer-strip-max-height, 46px); opacity: 1; transform: translateY(0) scale(1); } } @keyframes composer-status-strip-exit { 0% { max-height: var(--composer-strip-max-height, 46px); opacity: 1; transform: translateY(0) scale(1); } 100% { max-height: 0; opacity: 0; transform: translateY(8px) scale(0.99); } } .composer-status-strip { transform-origin: bottom center; will-change: max-height, opacity, transform; } .composer-status-strip[data-state="enter"] { animation: composer-status-strip-enter 280ms cubic-bezier(0.16, 1, 0.3, 1) both; } .composer-status-strip[data-state="exit"] { animation: composer-status-strip-exit 180ms ease-in both; } @keyframes run-pulse-dot { 0%, 100% { transform: scale(0.9); opacity: 0.76; } 50% { transform: scale(1.08); opacity: 1; } } @keyframes run-pulse-ring { 0% { transform: scale(0.42); opacity: 0.34; } 100% { transform: scale(1.28); opacity: 0; } } .run-pulse-icon { color: hsl(204 82% 46%); } .run-pulse-icon__ring, .run-pulse-icon__dot { display: block; border-radius: 999px; pointer-events: none; } .run-pulse-icon__ring { position: absolute; height: 12px; width: 12px; background: hsl(204 82% 46% / 0.22); animation: run-pulse-ring 1.55s ease-out infinite; } .run-pulse-icon__dot { height: 6px; width: 6px; background: currentColor; box-shadow: 0 0 0 1px hsl(204 82% 46% / 0.14); animation: run-pulse-dot 1.55s ease-in-out infinite; } @keyframes queued-prompt-row-enter { 0% { opacity: 0; transform: translateY(6px); } 100% { opacity: 1; transform: translateY(0); } } .queued-prompt-row { animation: queued-prompt-row-enter 220ms cubic-bezier(0.16, 1, 0.3, 1) both; } @media (prefers-reduced-motion: reduce) { .composer-status-strip { will-change: auto; } .composer-status-strip[data-state] { animation: none; } .run-pulse-icon, .run-pulse-icon * { animation: none; } .run-pulse-icon__ring { opacity: 0.18; transform: scale(1); } .run-pulse-icon__dot { opacity: 1; transform: scale(1); } .queued-prompt-row { animation: none; } } /** Goal halo: pale sky blue (not ``--primary``, which often reads as neutral gray). */ @keyframes goal-shell-glow-breathe { 0%, 100% { filter: drop-shadow(0 0 10px hsl(204 72% 52% / 0.22)) drop-shadow(0 0 24px hsl(199 80% 58% / 0.14)); } 50% { filter: drop-shadow(0 0 17px hsl(204 78% 48% / 0.32)) drop-shadow(0 0 38px hsl(199 85% 55% / 0.2)); } } .goal-shell-glow { animation: goal-shell-glow-breathe 4.8s ease-in-out infinite; } @keyframes goal-shell-glow-breathe-dark { 0%, 100% { filter: drop-shadow(0 0 12px hsl(198 90% 72% / 0.28)) drop-shadow(0 0 28px hsl(195 95% 65% / 0.16)); } 50% { filter: drop-shadow(0 0 20px hsl(198 95% 78% / 0.42)) drop-shadow(0 0 42px hsl(195 100% 70% / 0.24)); } } .dark .goal-shell-glow { animation-name: goal-shell-glow-breathe-dark; } @media (prefers-reduced-motion: reduce) { .goal-shell-glow { animation: none; filter: drop-shadow(0 0 14px hsl(204 70% 50% / 0.24)); } .dark .goal-shell-glow { filter: drop-shadow(0 0 14px hsl(198 88% 70% / 0.32)); } } @keyframes cli-app-linked-sheen { 0% { transform: translateX(-140%) skewX(-14deg); opacity: 0; } 18% { opacity: 0.7; } 72%, 100% { transform: translateX(140%) skewX(-14deg); opacity: 0; } } .cli-app-linked-chip::after { content: ""; position: absolute; inset: -1px; pointer-events: none; background: linear-gradient( 90deg, transparent 0%, hsl(var(--foreground) / 0.14) 46%, hsl(var(--background) / 0.7) 50%, hsl(var(--foreground) / 0.12) 54%, transparent 100% ); animation: cli-app-linked-sheen 1.25s ease-out 1; } .dark .cli-app-linked-chip::after { background: linear-gradient( 90deg, transparent 0%, hsl(var(--foreground) / 0.12) 46%, hsl(var(--background) / 0.5) 50%, hsl(var(--foreground) / 0.1) 54%, transparent 100% ); } @media (prefers-reduced-motion: reduce) { .cli-app-linked-chip::after { animation: none; content: none; } } /* Subtle scrollbar that doesn't fight the dark background. */ .scrollbar-thin { scrollbar-width: thin; scrollbar-color: hsl(var(--muted-foreground) / 0.4) transparent; } .scrollbar-thin::-webkit-scrollbar { width: 6px; height: 6px; } .scrollbar-thin::-webkit-scrollbar-thumb { background-color: hsl(var(--muted-foreground) / 0.4); border-radius: 9999px; } .scrollbar-track-transparent { scrollbar-gutter: stable; } .scrollbar-track-transparent::-webkit-scrollbar-track { background: transparent; } }