Theme & Styling
The frontend supports dark / light themes. The user's choice is stored in localStorage (key app_theme, dark by default) and toggled from the header.
How Theming Works
- Root data attribute:
App.tsxwrites the current mode to<html data-theme="dark|light">; global CSS switches the variable sets via[data-theme]. - antd theme:
ConfigProvider theme={mode === 'dark' ? darkTheme : lightTheme}themes the antd components;locale={zhCN}and a unified empty state viarenderEmpty. - Toggle animation:
toggle(point)uses the View Transitions API for a circular "liquid" reveal from the click point, falling back to an instant switch underprefers-reduced-motion: reduceor in unsupported browsers. - Hook:
useThemeMode()(src/theme/ThemeContext.ts) exposes the currentmodeandtoggle.
Styling Conventions (read before writing a page)
- Never hardcode colors. Page styles must use the CSS variables defined in
index.css/list-pages.css, so both themes apply automatically. - Give list pages a root
className="list-page"to inherit the unified layout fromlist-pages.css(filter area + table area + bottom spacing). - Use the brand/accent variables (e.g.
--brand,--text-secondary— see the variable list inindex.css) instead of hardcoding values like#3b82f6. - Style antd via
ConfigProvidertokens, not!importantoverrides.
Checklist
- [ ] Page is readable in both dark and light themes (screenshot compare)
- [ ] No hardcoded colors
- [ ]
message/modalcome from@/utils/feedback(theme-aware), not antd static methods