theming: migrate cospend to semantic CSS variables, extract SaveFab, refactor measure page
All checks were successful
CI / update (push) Successful in 4m21s
All checks were successful
CI / update (push) Successful in 4m21s
Replace hardcoded Nord colors with semantic CSS variables across all cospend pages and shared components (FormSection, ImageUpload, SplitMethodSelector, UsersList, PaymentModal, BarChart). Remove all dark mode override blocks. Make BarChart font colors theme-reactive via isDark() + MutationObserver. Extract reusable SaveFab component and use it on recipe edit and all cospend edit/add pages. Remove Cancel buttons and back links in favor of browser navigation. Replace raw checkboxes with Toggle component. Move fitness measurement add/edit forms to separate routes with SaveFab. Collapse profile section (sex/height) by default on the measure page. Document theming rules in CLAUDE.md for future reference.
This commit is contained in:
47
CLAUDE.md
47
CLAUDE.md
@@ -29,3 +29,50 @@ Svelte 5 removed event modifiers like `on:click|preventDefault`. Use inline hand
|
||||
|
||||
Generates a Svelte Playground link with the provided code.
|
||||
After completing the code, ask the user if they want a playground link. Only call this tool after user confirmation and NEVER if code was written to files in their project.
|
||||
|
||||
## Theming Rules
|
||||
|
||||
### Semantic CSS Variables (ALWAYS use these, NEVER hardcode Nord values for themed properties)
|
||||
|
||||
| Purpose | Variable | Light resolves to | Dark resolves to |
|
||||
|---|---|---|---|
|
||||
| Page background | `--color-bg-primary` | white/light | dark |
|
||||
| Card/section bg | `--color-surface` | nord6-ish | nord1-ish |
|
||||
| Secondary bg | `--color-bg-secondary` | slightly darker | slightly lighter |
|
||||
| Tertiary bg (inputs, insets) | `--color-bg-tertiary` | nord5-ish | nord2-ish |
|
||||
| Hover/elevated bg | `--color-bg-elevated` | nord4-ish | nord3-ish |
|
||||
| Primary text | `--color-text-primary` | dark text | light text |
|
||||
| Secondary text (labels, muted) | `--color-text-secondary` | nord3 | nord4 |
|
||||
| Tertiary text (descriptions) | `--color-text-tertiary` | nord2 | nord5 |
|
||||
| Borders | `--color-border` | nord4 | nord2/3 |
|
||||
|
||||
### What NOT to do
|
||||
- **NEVER** use `var(--nord0)` through `var(--nord6)` for backgrounds, text, or borders — these don't adapt to theme
|
||||
- **NEVER** write `@media (prefers-color-scheme: dark)` or `:global(:root[data-theme="dark"])` override blocks — semantic variables handle both themes automatically
|
||||
- **NEVER** use `var(--font-default-dark)` or `var(--accent-dark)` — these are legacy
|
||||
|
||||
### Accent colors (OK to use directly, they work in both themes)
|
||||
- `var(--blue)`, `var(--red)`, `var(--green)`, `var(--orange)` — named accent colors
|
||||
- `var(--nord10)`, `var(--nord11)`, `var(--nord12)`, `var(--nord14)` — OK for hover states of accent-colored buttons only
|
||||
|
||||
### Chart.js theme reactivity
|
||||
Charts don't use CSS variables. Use the `isDark()` pattern from `FitnessChart.svelte`:
|
||||
```js
|
||||
function isDark() {
|
||||
const theme = document.documentElement.getAttribute('data-theme');
|
||||
if (theme === 'dark') return true;
|
||||
if (theme === 'light') return false;
|
||||
return window.matchMedia('(prefers-color-scheme: dark)').matches;
|
||||
}
|
||||
const textColor = isDark() ? '#D8DEE9' : '#2E3440';
|
||||
```
|
||||
Re-create the chart on theme change via `MutationObserver` on `data-theme` + `matchMedia` listener.
|
||||
|
||||
### Form inputs
|
||||
- Background: `var(--color-bg-tertiary)`
|
||||
- Border: `var(--color-border)`
|
||||
- Text: `var(--color-text-primary)`
|
||||
- Label: `var(--color-text-secondary)`
|
||||
|
||||
### Toggle component
|
||||
Use `Toggle.svelte` (iOS-style) instead of raw `<input type="checkbox">` for user-facing boolean switches.
|
||||
|
||||
Reference in New Issue
Block a user