diff --git a/app/app.css b/app/app.css index 26b15b7..57259bc 100644 --- a/app/app.css +++ b/app/app.css @@ -1,4 +1,4 @@ -@import url("https://fonts.googleapis.com/css2?family=Inter:ital,opsz,wght@0,14..32,100..900;1,14..32,100..900&family=Instrument+Sans:ital,wght@0,400..700;1,400..700&family=Geist+Mono:wght@100..900&display=swap"); +@import url("https://fonts.googleapis.com/css2?family=Inter:ital,opsz,wght@0,14..32,100..900;1,14..32,100..900&family=Instrument+Sans:ital,wght@0,400..700;1,400..700&family=Geist+Mono:wght@100..900&family=JetBrains+Mono:ital,wght@0,400;0,500;0,600;0,700;1,400&family=Newsreader:ital,opsz,wght@0,6..72,400;0,6..72,500;0,6..72,600;1,6..72,400&display=swap"); /* Active theme — must be first so its @import url() font directives resolve * to the top of the output. Themes are self-contained: tokens + fonts. */ diff --git a/app/routes/ai.tsx b/app/routes/ai.tsx index 3d66c42..835ef47 100644 --- a/app/routes/ai.tsx +++ b/app/routes/ai.tsx @@ -316,18 +316,26 @@ export default function AIRoute() { const availableModels = status.kind === "live" ? status.models : ["mock"] return ( - + - + {/* Console aesthetic is scoped to this wrapper only, so the appbar + * and sidebar keep using the global skyrise tokens (light/dark + * toggle still works for them). */} +
+ +
) diff --git a/app/themes/console.css b/app/themes/console.css index 6c0edfe..dc47e68 100644 --- a/app/themes/console.css +++ b/app/themes/console.css @@ -11,7 +11,9 @@ * with skyrise / vibespace tokens. * ============================================================================ */ -@import url("https://fonts.googleapis.com/css2?family=JetBrains+Mono:ital,wght@0,400;0,500;0,600;0,700;1,400&family=Newsreader:ital,opsz,wght@0,6..72,400;0,6..72,500;0,6..72,600;1,6..72,400&display=swap"); +/* Fonts (JetBrains Mono + Newsreader) are loaded by app.css's top-level + * @import url() — keep this file free of @import statements so it can sit + * inside the bundle without violating "@import before any rule". */ [data-theme="console"] { /* ── Palette ─────────────────────────────────────────────────────────── */ @@ -90,10 +92,17 @@ var(--console-ink); } +/* Wrapper must be a positioning context so the grain overlay (and any + * other absolutely-positioned atmosphere) doesn't escape to the viewport. */ +[data-theme="console"] { + position: relative; + isolation: isolate; +} + /* Grain — single SVG turbulence, low opacity. Doesn't ship as an asset. */ [data-theme="console"]::before { content: ""; - position: fixed; + position: absolute; inset: 0; pointer-events: none; opacity: 0.035;