feat(ui): group RulesDrawer presets by category + layout suggested-rules chips
Phase F.3 + F.2-UI of the rule-variants epic.
Preset metadata:
- Added optional `category: 'king' | 'objective' | 'movement' |
'multi-move' | 'pieces' | 'misc'` on PresetDef (registry.ts).
Defaults to 'misc' when omitted.
- Categorized all 28 registered presets:
* King Variants: knightmate-rules, coregal, dual-king,
weak-dual-king.
* Objectives: capture-to-win, last-piece-standing,
first-promotion-wins, suicide-chess, capture-all,
extinction-chess.
* Movement: pawns-move-backward, double-pawn-sprint,
pawn-diagonal-no-capture, knights-leap-twice,
bishops-ignore-color, rook-warp, wrap-board,
berolina-pawns(+2), bouncing-pieces(+2), queen-splits.
* Multi-move: double-move, monster-rules.
* Pieces: piece-hp, king-heals, explosive-rook,
knight-immunity, poisoned-squares.
UI:
- RulesDrawer.tsx renders presets in category sections with
sentence-case headers ('King Variants', 'Objectives',
'Movement', 'Multi-move', 'Pieces', 'Misc'). Empty sections
hidden. Each section has data-testid='rules-category-<id>' for
e2e addressability. Existing search / scope / duration controls
preserved.
- LayoutPicker.tsx renders a 'Suggested rules' chip group under
each layout with suggestedPresets.length > 0. Chips toggle
presets on/off. Active = filled (neutral-800), inactive =
ghost (neutral-100). data-testid='layout-suggested-preset-<id>'
on each chip.
- Lobby.tsx wires activations + setPresets props to LayoutPicker
so chip toggles flow into the host-game payload
(rulesetIds array).
Tests: 1651 passing (unchanged — pure UI metadata).