diff --git a/CLAUDE.md b/CLAUDE.md index 7b533b4..eaf667e 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -54,12 +54,29 @@ Prefer separate, human-readable `.html` files over inlined HTML strings in Go. E - Do not inline JS in templates or merge unrelated features into one file - `ALT+SHIFT` is the modifier for all keyboard shortcuts — do not introduce others - Editor toolbar buttons use `data-action` + `data-key`; adding `data-key` auto-registers the shortcut -- Prefer generic, descriptive CSS classes (`btn`, `btn-small`, `muted`, `danger`) over element-specific names (`save-button`, `cancel-button`, `form-name-input`). Use a modifier + base class pattern (`btn btn-small`) rather than one-off classes that duplicate shared styles. -- Where possible, re-use existing CSS classes - For mutating modals (anything that POSTs and then navigates), call `closeModal()` and then `postReplace(action, body, target)` from `page/actions.js`. Do NOT use `
.submit()`. Two reasons: 1. The modal must be removed from the DOM before navigation, or the browser's bfcache snapshots it open and back-nav restores the modal. 2. `postReplace` uses `window.location.replace` so the action + result occupy a single history entry. A naive POST → 303 → GET creates two entries, and back-nav lands on a stale pre-mutation snapshot of the same page. +## CSS + +Follow **SMACSS** conventions (Scalable and Modular Architecture for CSS). The stylesheet is organized into five categories: + +- **Base** — element resets and global defaults only. Never style `header`, `textarea`, `input`, `aside`, `footer`, etc. directly for visual treatment — always via a class. +- **Layout** — `.row`, `.col`, `.page-wrap`. Use these for flex layout; do not inline `display: flex` on feature classes. +- **Modules** — reusable components: `.panel`, `.panel-header`, `.menu-row`, `.btn`, `.input`, `.muted`, `.truncate`, etc. New visual patterns should reuse these. Before adding a new module, check whether an existing one + a modifier already covers the case. +- **State** — `.is-*` prefix only (`.is-open`, `.is-selected`, `.is-active`, `.is-disabled`, `.is-empty`). State is the only place a class describes a moment in time rather than a structural role. +- **Theme** — colors, borders, spacing, and font sizes come from CSS variables defined in `:root` (`--bg`, `--secondary`, `--border`, `--border-dashed`, `--space-*`, `--font-*`). No hardcoded `1px solid #...`, no hardcoded rem spacing in component rules. + +Naming: flat-dash (`.panel-header`, `.btn-small`), not BEM (`.panel__header--small`). Modifiers attach as additional classes (`
`), not as new standalone classes. + +Anti-patterns to reject: +- One-off classes that duplicate an existing module (`.save-button` when `.btn` exists, `.form-name-input` when `.input` exists). +- Element selectors (`textarea { ... }`, `header { ... }`) for visual treatment — add a class instead. +- Inlining `display: flex; gap: X` on a feature class instead of composing with `.row` / `.col`. +- Adding a new module for a single use site — prefer a modifier on an existing module first. +- Hardcoded colors, border widths, or spacing values inside component rules — pull a variable, or add one to `:root` if it's missing. + ## Development Priorities When building features, apply this order: