Repository Public
1@import 'tailwindcss';23/*4 * Design tokens. `@theme` holds the LIGHT theme (the default, also what renders before any5 * script runs); `[data-theme='dark']` overrides the same variables. `data-theme` is set on6 * <html> by /theme-init.js (blocking, same-origin) and by the theme store.7 * Text-capable tokens (text, text-2, muted, accent, success, warning, error, coral-ink) meet8 * WCAG AA on bg/surface/surface-2 in both themes — verified by dev/check-contrast.mjs.9 * `*-vivid` tokens are for fills (dots, bars, rings), never for text.10 */11/*12 * Symbols for the terminal. The bundled @fontsource subsets omit box drawing, block elements,13 * arrows, braille (spinners) and dingbats, which Claude Code's UI uses; without these faces14 * they would come from a fallback font with different metrics (gaps in frames on the DOM15 * renderer). The full font files are only downloaded when such a character is displayed.16 */17@font-face {18 font-family: 'JetBrains Mono';19 font-style: normal;20 font-weight: 400;21 font-display: swap;22 src: url('../../node_modules/jetbrains-mono/fonts/webfonts/JetBrainsMonoNL-Regular.woff2') format('woff2');23 unicode-range: U+2190-21FF, U+2200-22FF, U+2300-23FF, U+2500-259F, U+25A0-25FF, U+2600-26FF, U+2700-27BF, U+2800-28FF, U+2B00-2BFF, U+E0A0-E0B3;24}25@font-face {26 font-family: 'JetBrains Mono';27 font-style: normal;28 font-weight: 700;29 font-display: swap;30 src: url('../../node_modules/jetbrains-mono/fonts/webfonts/JetBrainsMonoNL-Bold.woff2') format('woff2');31 unicode-range: U+2190-21FF, U+2200-22FF, U+2300-23FF, U+2500-259F, U+25A0-25FF, U+2600-26FF, U+2700-27BF, U+2800-28FF, U+2B00-2BFF, U+E0A0-E0B3;32}3334@theme {35 --color-bg: #f7f6f3;36 --color-surface: #ffffff;37 --color-surface-2: #f2f1ed;38 --color-elevated: #ffffff;39 --color-text: #17181c;40 --color-text-2: #555b69;41 --color-muted: #626876;42 --color-faint: #8e94a3;43 --color-accent: #5151e8;44 --color-accent-2: #8b5cf6;45 --color-accent-fg: #ffffff;46 /* Brand gradient stops (mark, primary CTA, phone home header) + ink for text on a white pill over it. */47 --color-brand-1: #5b5bf0;48 --color-brand-2: #8b5cf6;49 --color-brand-3: #ff7a59;50 --color-brand-ink: #3f3fd6;51 --color-coral: #ff7a59;52 --color-coral-ink: #b03e1c;53 --color-success: #0c7049;54 --color-warning: #805800;55 --color-error: #bf2c34;56 --color-success-vivid: #1fa971;57 --color-warning-vivid: #e0a100;58 --color-error-vivid: #e5484d;59 --color-line: #0000000f;60 --color-line-2: #00000017;61 --color-line-3: #0000002e;62 --color-card-line: #0000000a;63 --color-hover: #0000000a;64 --color-scrim: #17182059;65 --color-term-bg: #fcfcfa;66 --radius-sm: 10px;67 --radius-md: 16px;68 --radius-lg: 22px;69 --shadow-card: 0 1px 2px #1718200a, 0 4px 14px -6px #1718201a;70 --shadow-float: 0 2px 6px #1718200f, 0 12px 32px -10px #17182033;71 --shadow-pop: 0 4px 12px #17182014, 0 24px 56px -16px #17182047;72 --font-sans: var(--font-geist-sans), ui-sans-serif, system-ui, -apple-system, 'Helvetica Neue', sans-serif;73 --font-mono: 'JetBrains Mono', ui-monospace, 'SF Mono', Menlo, monospace;74 --ease-out: cubic-bezier(0.2, 0.7, 0.2, 1);75 --ease-spring: cubic-bezier(0.34, 1.4, 0.64, 1);76}7778[data-theme='dark'] {79 --color-bg: #080b10;80 --color-surface: #10151d;81 --color-surface-2: #161d27;82 --color-elevated: #1d2632;83 --color-text: #f4f7fb;84 --color-text-2: #a1adbd;85 --color-muted: #8492a6;86 --color-faint: #5d6a7d;87 --color-accent: #8f8fff;88 --color-accent-2: #b08cff;89 --color-accent-fg: #0a0a1f;90 --color-coral: #ff8f73;91 --color-coral-ink: #ff9d85;92 --color-success: #42c995;93 --color-warning: #e7b86b;94 --color-error: #f08080;95 --color-success-vivid: #42c995;96 --color-warning-vivid: #e7b86b;97 --color-error-vivid: #ed7777;98 --color-line: #ffffff0f;99 --color-line-2: #ffffff17;100 --color-line-3: #ffffff2b;101 --color-card-line: #ffffff14;102 --color-hover: #ffffff12;103 --color-scrim: #00000099;104 --color-term-bg: #080b10;105 --shadow-card: 0 1px 2px #00000040;106 --shadow-float: 0 8px 24px -8px #000000a6;107 --shadow-pop: 0 16px 48px -12px #000000cc;108 color-scheme: dark;109}110111/*112 * Codex instance (<html data-agent="codex">, set before paint by /theme-init.js from the cached113 * branding and confirmed by the branding store once /auth/status answered). Same neutrals and114 * status colours; only the accent family changes: emerald → teal → cyan instead of indigo → violet115 * → coral. Both blocks are checked by dev/check-contrast.mjs like the default tokens.116 */117html[data-agent='codex'] {118 --color-accent: #0b7268;119 --color-accent-2: #0891b2;120 --color-accent-fg: #ffffff;121 --color-brand-1: #047857;122 --color-brand-2: #0d9488;123 --color-brand-3: #0891b2;124 --color-brand-ink: #0a6b60;125}126html[data-agent='codex'][data-theme='dark'] {127 --color-accent: #2dd4bf;128 --color-accent-2: #22d3ee;129 --color-accent-fg: #04201c;130}131132@layer base {133 html {134 color-scheme: light;135 }136 html,137 body {138 height: 100%;139 background: var(--color-bg);140 color: var(--color-text);141 -webkit-text-size-adjust: 100%;142 overscroll-behavior: none;143 }144 body {145 font-family: var(--font-sans);146 font-size: 13px;147 line-height: 1.5;148 -webkit-font-smoothing: antialiased;149 -webkit-tap-highlight-color: transparent;150 font-feature-settings: 'ss01', 'cv11';151 }152 *,153 ::before,154 ::after {155 border-color: var(--color-line-2);156 }157 :focus-visible {158 outline: 2px solid var(--color-accent);159 outline-offset: 1px;160 }161 ::selection {162 background: color-mix(in srgb, var(--color-accent) 30%, transparent);163 }164 button {165 cursor: pointer;166 }167 button:disabled {168 cursor: not-allowed;169 }170 /* Real inputs never go below 16px on touch devices: iOS zooms the page otherwise. */171 @media (pointer: coarse) {172 input,173 textarea,174 select {175 font-size: 16px !important;176 }177 }178 * {179 scrollbar-width: thin;180 scrollbar-color: var(--color-line-3) transparent;181 }182}183184@layer components {185 /* Elevated surface: soft layered shadow in light, hairline in dark. */186 .card {187 background: var(--color-surface);188 border: 1px solid var(--color-card-line);189 border-radius: var(--radius-md);190 box-shadow: var(--shadow-card);191 }192 /* Brand gradient: mark, primary call to action, phone home header, activity accents only. */193 .bg-brand {194 background-image: linear-gradient(135deg, var(--color-brand-1) 0%, var(--color-brand-2) 58%, var(--color-brand-3) 135%);195 color: #fff;196 }197 .text-brand {198 background-image: linear-gradient(120deg, var(--color-accent) 0%, var(--color-accent-2) 60%, var(--color-coral) 120%);199 -webkit-background-clip: text;200 background-clip: text;201 color: transparent;202 }203 html[data-agent='codex'] .text-brand {204 background-image: linear-gradient(120deg, var(--color-accent) 0%, var(--color-accent-2) 100%);205 }206 /* Product names in the static HTML are the default product: hidden until the branding store took over. */207 html[data-agent='codex']:not([data-brand-ready]) [data-brand-text] {208 visibility: hidden;209 }210 .pressable {211 transition: transform 140ms var(--ease-out), box-shadow 140ms var(--ease-out);212 }213 .pressable:active {214 transform: scale(0.97);215 }216 /* Skeleton / indeterminate shimmer (never a fake percentage). */217 .shimmer {218 background-image: linear-gradient(100deg, transparent 20%, color-mix(in srgb, var(--color-text) 9%, transparent) 50%, transparent 80%);219 background-size: 200% 100%;220 animation: cr-shimmer 1.4s linear infinite;221 }222 .shimmer-accent {223 background-image: linear-gradient(100deg, transparent 0%, var(--color-accent) 45%, var(--color-accent-2) 55%, transparent 100%);224 background-size: 220% 100%;225 animation: cr-shimmer 1.6s linear infinite;226 }227 .glass {228 background: color-mix(in srgb, var(--color-surface) 78%, transparent);229 -webkit-backdrop-filter: saturate(1.6) blur(18px);230 backdrop-filter: saturate(1.6) blur(18px);231 }232 .tnum {233 font-variant-numeric: tabular-nums;234 }235 .app-viewport {236 /* Height is driven by window.visualViewport (see useVisualViewport); 100dvh is the fallback. */237 height: var(--vvh, 100dvh);238 }239 .pt-safe {240 padding-top: env(safe-area-inset-top);241 }242 .pb-safe {243 padding-bottom: env(safe-area-inset-bottom);244 }245 .px-safe {246 padding-left: env(safe-area-inset-left);247 padding-right: env(safe-area-inset-right);248 }249 .no-scrollbar {250 scrollbar-width: none;251 }252 .no-scrollbar::-webkit-scrollbar {253 display: none;254 }255}256257/* xterm: the helper textarea must never trigger iOS focus-zoom nor show a caret. */258.xterm .xterm-helper-textarea {259 font-size: 16px !important;260 opacity: 0 !important;261 caret-color: transparent;262}263.xterm {264 height: 100%;265 touch-action: none;266 font-variant-ligatures: none; /* a terminal shows => as two cells, not a ligature */267}268.xterm .xterm-scrollable-element > .scrollbar.vertical,269.xterm .xterm-scrollable-element > .scrollbar.vertical > .slider {270 width: 6px !important;271 border-radius: 3px;272}273.xterm .xterm-scrollable-element > .scrollbar.vertical {274 right: 2px !important;275}276.xterm .xterm-viewport {277 background-color: transparent !important;278}279280@keyframes cr-fade-in {281 from {282 opacity: 0;283 }284}285@keyframes cr-pop-in {286 from {287 opacity: 0;288 transform: translateY(4px) scale(0.985);289 }290}291@keyframes cr-slide-right {292 from {293 transform: translateX(100%);294 }295}296@keyframes cr-slide-left {297 from {298 transform: translateX(-100%);299 }300}301@keyframes cr-slide-up {302 from {303 transform: translateY(100%);304 }305}306@keyframes cr-shimmer {307 from {308 background-position: 120% 0;309 }310 to {311 background-position: -120% 0;312 }313}314@keyframes cr-ping {315 0% {316 transform: scale(1);317 opacity: 0.55;318 }319 100% {320 transform: scale(2.6);321 opacity: 0;322 }323}324@keyframes cr-draw {325 to {326 stroke-dashoffset: 0;327 }328}329@keyframes cr-pulse {330 50% {331 opacity: 0.45;332 }333}334.anim-fade {335 animation: cr-fade-in 140ms var(--ease-out);336}337.anim-pop {338 animation: cr-pop-in 160ms var(--ease-out);339}340.anim-slide-right {341 animation: cr-slide-right 200ms var(--ease-out);342}343.anim-slide-left {344 animation: cr-slide-left 200ms var(--ease-out);345}346.anim-slide-up {347 animation: cr-slide-up 200ms var(--ease-out);348}349.anim-ping {350 animation: cr-ping 1.8s var(--ease-out) infinite;351}352.anim-draw {353 stroke-dasharray: 1;354 stroke-dashoffset: 1;355 animation: cr-draw 420ms 80ms var(--ease-out) forwards;356}357/* Cross-fade while the theme changes (class added for ~300 ms by the theme store). */358html.theme-fade,359html.theme-fade * {360 transition: background-color 260ms ease, border-color 260ms ease, color 200ms ease, fill 200ms ease, box-shadow 260ms ease !important;361}362.anim-pulse {363 animation: cr-pulse 1.6s ease-in-out infinite;364}365@media (prefers-reduced-motion: reduce) {366 *,367 ::before,368 ::after {369 animation-duration: 1ms !important;370 animation-iteration-count: 1 !important;371 transition-duration: 1ms !important;372 scroll-behavior: auto !important;373 }374}375