diff --git a/CLAUDE.md b/CLAUDE.md index 867ac765..223ce247 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -78,7 +78,7 @@ boot; a shared `/watch` link boots from its own entry, `watch.html` → `watchMa app-free by a contract test) → **`modules//`** (one folder per page: the page, its rail, its store, its tests, and its `module.ts` definition — label, icon, gate, the lazy page and rail, its store — collected in nav order by `features/navigation/moduleRegistry`, which also mounts every store at the root; a new page is its folder, its id in -`lib/urlState` and its entry there) → +`lib/urlState` and its entry there, plus its panel in `lib/panelLayout` if it has a rail) → **`features//`** (what several pages share: video cards, filters, downloads, the player, navigation) → the **platform layer `components/ui/`** (domain-free primitives: the popover engine and its menus, `Modal`/`Overlay`, `Button`/`form`, `DataTable`/`VirtualGrid`, `QueryState`, diff --git a/docs/development.md b/docs/development.md index 8af4586e..0bb8d445 100644 --- a/docs/development.md +++ b/docs/development.md @@ -51,6 +51,11 @@ A frontend page is one folder, `frontend/src/modules//` (the layering is in 4. The id in `lib/urlState`'s `PAGES`, and the definition in `features/navigation/moduleRegistry.ts`, in nav-rail order. The rail, the palette, the `g` chords, the tab title and the root's stores all read from there. 5. Its strings in both locales (`src/i18n/locales`). +6. A page with a side rail also names its panel below the module, in `lib/` (rails share one layout + and collapse machinery, which lib may not learn from a module): the `PanelId` and its default group + order, storage and pref keys in `lib/panelLayout.ts`, its collapse flag in `lib/useRail.ts` + (`COLLAPSE`), and those keys in `lib/storage.ts`. The rail calls `useRail("")` and hands what it + returns to `ui/FilterRail`; tsc names each table still missing the new id. What holds it: `moduleRegistry.contract.test.ts` (every id defined once, from its own folder, lazily), `moduleStores.contract.test.tsx` (no store reads another module), the `local/layers` lint rule (imports only go diff --git a/docs/gates.md b/docs/gates.md index da680464..b0e23f5f 100644 --- a/docs/gates.md +++ b/docs/gates.md @@ -61,7 +61,8 @@ them itself (`no-undef`, `no-redeclare`, `no-dupe-keys`, …), nor the formattin | src tests · ui tests · lib tests | `local/literal-a11y-text`, `local/input-primitive`, `local/surface-role`, `local/glyph-link` — off | A test renders throwaway markup (a raw input as a focus target, an untranslated label) that is not product UI. `local/button-primitive` stays on: in a test file (and in a control primitive) it only refuses a raw `