ai: scope console theme to content wrapper, fix font loading
Two bugs in the previous /ai redesign: 1. theme="console" on AppShell put the entire shell (sidebar, appbar, appbar dropdowns, the lot) inside [data-theme="console"], so the console palette + JetBrains Mono override leaked into the sidebar and made light mode look broken on /ai. Scoped now: the AppShell stays in skyrise (so light/dark toggle keeps working everywhere), and only the route content area gets data-theme="console" via an inner wrapper. 2. The Google Fonts @import inside console.css was being silently dropped because @import rules must precede all other rules in the final bundle, and skyrise's content lands first. Moved JetBrains Mono + Newsreader into app.css's top-level @import url() alongside the existing Inter/Instrument Sans/Geist Mono families. Atmosphere ::before was also position: fixed, which painted the grain overlay across the whole viewport (including the sidebar) regardless of where data-theme lived. Now position: absolute on the wrapper, with isolation: isolate to keep z-index local. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -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
|
/* Active theme — must be first so its @import url() font directives resolve
|
||||||
* to the top of the output. Themes are self-contained: tokens + fonts. */
|
* to the top of the output. Themes are self-contained: tokens + fonts. */
|
||||||
|
|||||||
@@ -316,18 +316,26 @@ export default function AIRoute() {
|
|||||||
const availableModels = status.kind === "live" ? status.models : ["mock"]
|
const availableModels = status.kind === "live" ? status.models : ["mock"]
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<AppShell title="AI" theme="console">
|
<AppShell title="AI">
|
||||||
<LLMProvider adapter={adapter} model={activeModel}>
|
<LLMProvider adapter={adapter} model={activeModel}>
|
||||||
<ChatSurface
|
{/* Console aesthetic is scoped to this wrapper only, so the appbar
|
||||||
models={availableModels}
|
* and sidebar keep using the global skyrise tokens (light/dark
|
||||||
model={activeModel}
|
* toggle still works for them). */}
|
||||||
onModelChange={setModel}
|
<div
|
||||||
agents={agents}
|
data-theme="console"
|
||||||
activeAgent={activeAgent}
|
className="-m-6 flex h-full min-h-0 flex-col bg-[var(--console-ink)] text-[var(--console-text)]"
|
||||||
onAgentChange={setActiveAgentId}
|
>
|
||||||
isMock={status.kind === "mock"}
|
<ChatSurface
|
||||||
onRetryProbe={probe}
|
models={availableModels}
|
||||||
/>
|
model={activeModel}
|
||||||
|
onModelChange={setModel}
|
||||||
|
agents={agents}
|
||||||
|
activeAgent={activeAgent}
|
||||||
|
onAgentChange={setActiveAgentId}
|
||||||
|
isMock={status.kind === "mock"}
|
||||||
|
onRetryProbe={probe}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
</LLMProvider>
|
</LLMProvider>
|
||||||
</AppShell>
|
</AppShell>
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -11,7 +11,9 @@
|
|||||||
* with skyrise / vibespace tokens.
|
* 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"] {
|
[data-theme="console"] {
|
||||||
/* ── Palette ─────────────────────────────────────────────────────────── */
|
/* ── Palette ─────────────────────────────────────────────────────────── */
|
||||||
@@ -90,10 +92,17 @@
|
|||||||
var(--console-ink);
|
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. */
|
/* Grain — single SVG turbulence, low opacity. Doesn't ship as an asset. */
|
||||||
[data-theme="console"]::before {
|
[data-theme="console"]::before {
|
||||||
content: "";
|
content: "";
|
||||||
position: fixed;
|
position: absolute;
|
||||||
inset: 0;
|
inset: 0;
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
opacity: 0.035;
|
opacity: 0.035;
|
||||||
|
|||||||
Reference in New Issue
Block a user