feat(ui): design tokens + light/dark theming, migrate in-game chrome (F1a)
Tests · UI / test (push) Successful in 2m4s

Introduce the shared design-token system under
ui/frontend/src/lib/theme/: tokens.css (dark default + light palette,
plus spacing/radii/typography scales), base.css global baseline
(document background, text, token focus ring, selection), and
theme.svelte.ts (system/light/dark choice, persisted to localStorage,
applied via data-theme on <html>). A pre-paint guard in app.html
resolves the theme before the app boots to avoid a flash, and the theme
picker is wired into the previously-disabled account-menu stub.

Migrate the always-visible in-game chrome to the tokens (header, account
menu, sidebar, tab-bar, bottom-tabs, shell background): dark renders as
before, light comes for free. The default stays dark during the
incremental migration; the remaining view bodies migrate in F1b.

Docs: ui/docs/design-system.md (+ index entry). Test: tests/theme.test.ts.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Ilia Denisov
2026-05-22 07:02:13 +02:00
parent 44ed0a90eb
commit 973480d812
16 changed files with 560 additions and 53 deletions
+14 -14
View File
@@ -205,10 +205,10 @@ destinations beats the duplication.
display: flex;
justify-content: space-around;
align-items: stretch;
background: #0a0e1a;
color: #e8eaf6;
border-top: 1px solid #20253a;
font-family: system-ui, sans-serif;
background: var(--color-bg);
color: var(--color-text);
border-top: 1px solid var(--color-border-subtle);
font-family: var(--font-sans);
}
.tabs button {
flex: 1;
@@ -220,13 +220,13 @@ destinations beats the duplication.
font: inherit;
font-size: 0.75rem;
background: transparent;
color: #aab;
color: var(--color-text-muted);
border: 0;
cursor: pointer;
}
.tabs button.active {
color: #e8eaf6;
background: #1c2238;
color: var(--color-text);
background: var(--color-surface-hover);
}
.tabs .icon {
font-size: 1.25rem;
@@ -240,12 +240,12 @@ destinations beats the duplication.
overflow-y: auto;
display: flex;
flex-direction: column;
background: #14182a;
color: #e8eaf6;
border-top: 1px solid #2a3150;
background: var(--color-surface-overlay);
color: var(--color-text);
border-top: 1px solid var(--color-border);
box-shadow: 0 -8px 24px rgba(0, 0, 0, 0.4);
z-index: 50;
font-family: system-ui, sans-serif;
font-family: var(--font-sans);
}
.drawer > button,
.drawer > details > summary {
@@ -259,7 +259,7 @@ destinations beats the duplication.
}
.drawer > button:hover,
.drawer > details > summary:hover {
background: #1c2238;
background: var(--color-surface-hover);
}
.drawer > details > summary {
list-style: none;
@@ -279,7 +279,7 @@ destinations beats the duplication.
display: flex;
flex-direction: column;
padding-left: 0.5rem;
border-left: 1px solid #2a3150;
border-left: 1px solid var(--color-border);
margin: 0 0.5rem 0.25rem;
}
.sub > button {
@@ -292,6 +292,6 @@ destinations beats the duplication.
cursor: pointer;
}
.sub > button:hover {
background: #1c2238;
background: var(--color-surface-hover);
}
</style>
+4 -4
View File
@@ -108,9 +108,9 @@ through the binding without extra plumbing.
flex-direction: column;
width: 18rem;
min-width: 18rem;
background: #0e1322;
color: #e8eaf6;
border-left: 1px solid #20253a;
background: var(--color-surface);
color: var(--color-text);
border-left: 1px solid var(--color-border-subtle);
}
.head {
display: flex;
@@ -130,7 +130,7 @@ through the binding without extra plumbing.
cursor: pointer;
}
.close:hover {
color: #6d8cff;
color: var(--color-accent);
}
.content {
flex: 1;
+6 -6
View File
@@ -51,24 +51,24 @@ flips it on.
display: flex;
gap: 0.25rem;
padding: 0.5rem 0.5rem 0;
border-bottom: 1px solid #20253a;
font-family: system-ui, sans-serif;
border-bottom: 1px solid var(--color-border-subtle);
font-family: var(--font-sans);
}
.tab-bar button {
font: inherit;
font-size: 0.9rem;
padding: 0.4rem 0.75rem;
background: transparent;
color: #aab;
color: var(--color-text-muted);
border: 0;
border-bottom: 2px solid transparent;
cursor: pointer;
}
.tab-bar button.active {
color: #e8eaf6;
border-bottom-color: #6d8cff;
color: var(--color-text);
border-bottom-color: var(--color-accent);
}
.tab-bar button:hover:not(.active) {
color: #e8eaf6;
color: var(--color-text);
}
</style>