- 2026-05-14: T3 Testing Infrastructure completed - vitest.config.ts updated: happy-dom env, globals, setupFiles, aliases @/* - Installed: @testing-library/dom, happy-dom, @playwright/test - Created: tests/setup.ts (crypto mock), tests/utils.ts (mock helpers), playwright.config.ts, tests/example.test.ts - Scripts added: test:unit, test:ui - All 56 tests pass (existing + new) - Key pattern: Use happy-dom instead of jsdom for lighter weight; mock crypto.getRandomValues for deterministic dice tests # DM Dashboard Design System — Wave 1 Learnings ## Design System Foundation (2026-05-14) ### Theme Architecture - Created `src/styles/dm-theme.css` with `:root` CSS custom properties for orange accent (`#E87722`) - Variables defined: `--accent`, `--accent-light`, `--accent-dark`, `--bg-primary`, `--bg-secondary`, `--bg-card`, `--text-primary`, `--text-secondary`, `--border-color` - DM layout wraps `BaseLayout` and imports theme CSS; components use Tailwind arbitrary values like `bg-[var(--bg-card)]` ### Component Patterns - **DmButton**: Supports `primary` / `secondary` / `ghost` variants and `sm` / `md` / `lg` sizes. Uses `focus-visible:ring-[var(--accent)]` for accessible focus states. Disabled state handled with `disabled:` modifiers. - **DmCard**: Simple container with configurable padding (`none` / `sm` / `md` / `lg`). Base style: `rounded-xl bg-[var(--bg-card)] border border-[var(--border-color)] shadow-lg shadow-black/20`. - **DmInput**: Wraps label + input. Dark theme input: `bg-[var(--bg-secondary)] border-[var(--border-color)]` with orange focus ring. Supports `required` indicator. - **DmHeader**: Flex header with logo icon (pen/edit SVG), title, and slot for actions. Uses `backdrop-blur-sm` for modern glass effect. - **DmLayout**: Wraps `BaseLayout`, imports `dm-theme.css`, sets `bg-[var(--bg-primary)]` on wrapper div. ### Tailwind v4 Conventions - Project uses `@import "tailwindcss"` and `@theme` block in `BaseLayout.astro` global styles - Existing accent color (`#534AB7`) defined via `--color-accent` in `@theme`; DM theme uses separate `:root` variables to avoid collision - `focus-visible:` pattern used consistently across interactive elements (copied from existing GeneratorCard/ResultBox patterns) ### Dark Theme Consistency - Base dark palette: `bg-zinc-950` / `text-zinc-100` from existing site - DM theme maps closely: `--bg-primary: #0f0f0f`, `--bg-secondary: #1a1a1a`, `--bg-card: #242424` - Orange accent (`#E87722`) provides high contrast against dark backgrounds ### Verification - Build passes successfully (`npm run build` exits 0) - Temporary test page confirmed all components render and compile correctly - No existing components modified ## Initiative Tracker Component (T9) — 2026-05-14 ### TDD Cycle - RED: Wrote `tests/initiative-tracker.test.ts` with 11 tests covering `sortByInitiative`, `getNextActiveIndex`, and `rollInitiative` — all failed initially due to missing module. - GREEN: Created `src/lib/client/initiative.ts` with pure helper functions; all 11 tests pass. - Refactor: No changes needed — functions are already minimal and pure. ### Files Created - `src/lib/client/initiative.ts` — pure helpers: `sortByInitiative`, `getNextActiveIndex`, `rollInitiative` - `tests/initiative-tracker.test.ts` — 11 tests (sorting, cycling, edge cases, dice roll bounds) - `src/components/dm/InitiativeTracker.astro` — full interactive component ### Component Design - Uses `DmButton` and `DmInput` for consistent DM theme styling - Form layout: Name (5 cols) + Modifier (3 cols) + Roll d20 (2 cols) + Add (2 cols) - Initiative can be entered manually or auto-rolled (d20 + modifier) - List sorted descending by initiative with numbered badges - Active combatant: orange border (`border-[var(--accent)]`) + orange background tint + orange numbered badge - Delete per combatant (trash icon), Clear All, Next Turn buttons - Data persisted in `sessionStorage` (resets on refresh — MVP scope) - Empty state shown when no combatants ### Key Patterns - Client script imports from `@/lib/client/initiative` — Astro bundles TypeScript imports in `