UI: unified design system, light/dark themes, redesigned pages and player UI
Tokens and components in styles.css, shared Ui (dialogs, toasts), icons, bottom tab bar on mobile, keyboard/gamepad navigation, library shelf with filters and conversion badges, hero game page, restyled player screens. Games list now returns per-game version counts. Adds docs/UI_DESIGN.md. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
51a7e77e56
commit
9ee3e1ff6e
27 files changed
+2399
-508
No files matched your search
@@ -0,0 +1,39 @@
|
||||
import { useCallback, useEffect, useState } from "react";
|
||||
|
||||
export type ThemeChoice = "system" | "dark" | "light";
|
||||
const KEY = "pg-theme";
|
||||
|
||||
function read(): ThemeChoice {
|
||||
try {
|
||||
const v = localStorage.getItem(KEY);
|
||||
return v === "dark" || v === "light" ? v : "system";
|
||||
} catch {
|
||||
return "system";
|
||||
}
|
||||
}
|
||||
|
||||
function apply(choice: ThemeChoice) {
|
||||
const root = document.documentElement;
|
||||
if (choice === "system") delete root.dataset.theme;
|
||||
else root.dataset.theme = choice;
|
||||
const dark = choice === "dark" || (choice === "system" && matchMedia("(prefers-color-scheme: dark)").matches);
|
||||
document.querySelector('meta[name="theme-color"]')?.setAttribute("content", dark ? "#0e1016" : "#f4f1ec");
|
||||
}
|
||||
|
||||
export function useTheme() {
|
||||
const [choice, setChoice] = useState<ThemeChoice>(read);
|
||||
useEffect(() => {
|
||||
apply(choice);
|
||||
try {
|
||||
if (choice === "system") localStorage.removeItem(KEY);
|
||||
else localStorage.setItem(KEY, choice);
|
||||
} catch {
|
||||
/* private mode */
|
||||
}
|
||||
}, [choice]);
|
||||
const cycle = useCallback(
|
||||
() => setChoice((c) => (c === "system" ? "dark" : c === "dark" ? "light" : "system")),
|
||||
[],
|
||||
);
|
||||
return { choice, setChoice, cycle };
|
||||
}
|
||||
Reference in new issue
Block a user