@import "tailwindcss"; @custom-variant dark (&:is(.dark *)); /* * THE SKIN — wave 5. Design tokens, the single place to restyle the app. * * Mathematical soundness, per the owner's brief: * - Tailwind's built-in 0.25rem (4px) spacing scale IS the rhythm — every * padding/margin/gap in the app uses whole units of a 4px base. * - The type scale below is a declared modular ladder (each --text-* token * carries its own line-height); components never invent pixel sizes. * - Radii ladder is 4 / 8 / 12 / 16px multiples of the 4px base. * - Emphasis colors live in tokens (--lh-ink-strong / --lh-ink-italic) so a * future settings UI reassigns them (configurable per the owner). */ /* Palette (owner's hexes): main #141414, raised #1C1C1C, edges #434343. Mono chrome = JetBrains Mono; prose = Source Sans 3; titles = CMU Serif. */ :root { --radius: 8px; --background: #141414; --foreground: #e6e6e6; --card: #1c1c1c; --card-foreground: #e6e6e6; --popover: #1c1c1c; --popover-foreground: #e6e6e6; --primary: #e6e6e6; --primary-foreground: #141414; --secondary: #1c1c1c; --secondary-foreground: #e6e6e6; --muted: #1c1c1c; --muted-foreground: #8d8d8d; --accent: #2a2a2a; --accent-foreground: #e6e6e6; --destructive: oklch(0.704 0.191 22.216); --border: #434343; --input: #434343; --ring: #8d8d8d; /* Emphasis coloring in teaching prose — ready for the settings UI. */ --lh-ink-strong: #c96b4a; --lh-ink-italic: #6fa9d6; --lh-prose-size: 16.5px; --lh-prose-leading: 1.5; } /* The app is always dark (); mirror the same values so the block stays coherent under Tailwind's variant. */ .dark { --background: #141414; --foreground: #e6e6e6; --card: #1c1c1c; --card-foreground: #e6e6e6; --popover: #1c1c1c; --popover-foreground: #e6e6e6; --primary: #e6e6e6; --primary-foreground: #141414; --secondary: #1c1c1c; --secondary-foreground: #e6e6e6; --muted: #1c1c1c; --muted-foreground: #8d8d8d; --accent: #2a2a2a; --accent-foreground: #e6e6e6; --destructive: oklch(0.704 0.191 22.216); --border: #434343; --input: #434343; --ring: #8d8d8d; --lh-ink-strong: #c96b4a; --lh-ink-italic: #6fa9d6; --lh-prose-size: 16.5px; --lh-prose-leading: 1.5; } /* CMU Serif bold (titles) — bundled local file, no CDN dependency. */ @font-face { font-family: "lh-cmu"; src: url("/fonts/cmunbx.ttf") format("truetype"); font-weight: 700; font-style: normal; font-display: swap; } @theme inline { /* Fonts: chrome = JetBrains Mono, prose = Source Sans 3, titles = CMU Serif bold. The JetBrains/SourceSans variables attach in app/layout.tsx. */ --font-ui: var(--font-jetbrains), ui-monospace, SFMono-Regular, monospace; --font-prose: var(--font-sans3), ui-sans-serif, system-ui, sans-serif; --font-title: "lh-cmu", serif; /* The modular type ladder — each size carries its own line-height. Component sizes must pull from this ladder. */ --text-xxs: 10px; --text-xxs--line-height: 1.4; --text-xs: 11px; --text-xs--line-height: 1.4; --text-sm: 12.5px; --text-sm--line-height: 1.4; --text-base: 14px; --text-base--line-height: 1.45; --text-lg: 16px; --text-lg--line-height: 1.45; --text-xl: 20px; --text-xl--line-height: 1.4; --text-2xl: 25px; --text-2xl--line-height: 1.3; --text-3xl: 32px; --text-3xl--line-height: 1.25; /* Radii ladder — 4/8/12/16 multiples of the 4px base. */ --radius-sm: 4px; --radius-md: 8px; --radius-lg: 12px; --radius-xl: 16px; --radius: 8px; --color-background: var(--background); --color-foreground: var(--foreground); --color-card: var(--card); --color-card-foreground: var(--card-foreground); --color-popover: var(--popover); --color-popover-foreground: var(--popover-foreground); --color-primary: var(--primary); --color-primary-foreground: var(--primary-foreground); --color-secondary: var(--secondary); --color-secondary-foreground: var(--secondary-foreground); --color-muted: var(--muted); --color-muted-foreground: var(--muted-foreground); --color-accent: var(--accent); --color-accent-foreground: var(--accent-foreground); --color-destructive: var(--destructive); --color-border: var(--border); --color-input: var(--input); --color-ring: var(--ring); } * { border-color: var(--color-border); } body { background: var(--color-background); color: var(--color-foreground); font-family: var(--font-ui); } /* Teaching prose (the markdown renderer's container gets .lh-prose): Source Sans 3 with the size/leading tokens; emphasis color bound to the settings-ready tokens. */ .lh-prose { font-family: var(--font-prose); font-size: var(--lh-prose-size); line-height: var(--lh-prose-leading); } .lh-prose :where(strong, b) { color: var(--lh-ink-strong); font-weight: 700; } .lh-prose :where(em, i) { color: var(--lh-ink-italic); } /* Thin dark native scrollbar (app-wide): dark thumb, transparent track. */ * { scrollbar-width: thin; scrollbar-color: var(--color-border) transparent; } ::-webkit-scrollbar { width: 8px; height: 8px; } ::-webkit-scrollbar-track { background: transparent; } ::-webkit-scrollbar-thumb { background: var(--color-border); border-radius: 8px; } ::-webkit-scrollbar-thumb:hover { background: var(--color-muted-foreground); } /* Dock variant swap — quick fade/rise on content change; the shell's HEIGHT morph is separate (WAAPI in DockOverlay). Re-applied via class toggling, no remount, so collapsed-question state survives. */ @keyframes dock-variant-in { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: translateY(0); } } .dock-variant { animation: dock-variant-in 160ms cubic-bezier(0.2, 0.8, 0.2, 1); } /* ============================================================ * W3 — presentation fixes (appended 2026-08-22) * ============================================================ */ /* Streamdown's internal UI chrome (code blocks, tables, mermaid containers, copy/download buttons) is styled with Tailwind utilities living in its dist * bundle. Tailwind v4 never scans node_modules, so without this line those * classes are dead — code blocks and mermaid containers rendered unstyled. * (Streamdown README, "Tailwind CSS setup".) */ @source "../node_modules/streamdown/dist/*.js"; /* Token the streamdown utilities reference (code-block/mermaid chrome uses * bg-sidebar / border-sidebar): map it onto the app's card surface. */ @theme inline { --color-sidebar: var(--card); } /* Mermaid diagrams: keep wide charts inside the content column. Mermaid * inlines a px max-width on the svg, so !important is required to win. */ [data-streamdown="mermaid"] svg { max-width: 100% !important; height: auto !important; } /* Display math: long equations scroll instead of overflowing the column. */ .katex-display { overflow-x: auto; overflow-y: hidden; } /* ============================================================ * Session status — phase colors + status dots * (picker strips, header chip, transcript dividers: one language) * ============================================================ */ /* Phase colors: blue = probing, violet = planning, green = teaching. Tuned per theme (light needs darker, dark lighter). These color the session dots, header chip and transcript dividers — one language. */ :root { --phase-probe: oklch(0.55 0.17 253); --phase-plan: oklch(0.54 0.19 300); --phase-teach: oklch(0.55 0.14 160); } .dark { --phase-probe: oklch(0.72 0.13 250); --phase-plan: oklch(0.72 0.14 300); --phase-teach: oklch(0.74 0.12 160); } @theme inline { --color-phase-probe: var(--phase-probe); --color-phase-plan: var(--phase-plan); --color-phase-teach: var(--phase-teach); } /* Session dot motion (picker): the ONLY animated state is "teacher is working" — a quiet phase-colored breathing. Pending questions are the dominant resting state and stay perfectly still (solid dot). */ @keyframes lh-dot-breathe { 0%, 100% { opacity: 0.35; transform: scale(0.75); } 50% { opacity: 1; transform: scale(1); } } .lh-dot-breathe { animation: lh-dot-breathe 1.4s ease-in-out infinite; } @media (prefers-reduced-motion: reduce) { .lh-dot-breathe { animation: none; } }