Redesign DM Dashboard (/dm/, /ru/dm/) with purple-gold theme (#534AB7 + #c8a84b): Design System: - Update dm-theme.css with 49 purple-gold tokens (transitions, shadows, hover states) - Create DmTabs.astro with ARIA, keyboard nav, URL hash sync, localStorage persistence - Create DmSidebar.astro for desktop navigation - Redesign DmHeader with gold accent - Update DmButton, DmCard, DmInput primitives - Expand i18n to 47 strings Layout: - Redesign DmLayout with 3-column dashboard grid (sidebar|main|context) - Update /dm/index.astro and /ru/dm/index.astro with named slots Feature Components: - DiceRoller: empty state, ARIA live, color-coded history, storage key fallback - InitiativeTracker: HP editing, active highlighting, storage key fallback - Open5eReference: skeletons, debounce, error retry, gold tabs - NotesPanel: cross-tab sync, copy-to-clipboard, auto-save - AuthPanel: VK/Yandex brand colors, pill buttons Tests: - Add 50 Playwright E2E tests (smoke, dice, initiative, reference, notes, data-migration) Fixes: - Document Open5e client.ts URL bugfix - Add backward-compatible storage key fallback for dice/initiative - Preserve legacy sessionStorage data on load
7.4 KiB
7.4 KiB
DM Dashboard Redesign — Work Notes
Theme Tokens (Target)
- Primary:
#534AB7 - Secondary:
#c8a84b - Background base:
#16120e - Surface:
#1e1912 - Card:
#221e18 - Green (crit):
#6ab04c - Red (fail):
#e06060 - Accent hover:
#6b5fc7 - Gold hover:
#d4b76a
Current State (2026-05-15)
- dm-theme.css: 11 properties, orange theme
- DmHeader: simple header with quill icon
- DmButton: 3 variants (primary/secondary/ghost)
- DmCard: padding variants, shadow
- DmInput: label + input with focus ring
- dm-translations.ts: 14 strings only
- Playwright: installed (@playwright/test v1.60.0), script is
test:ui
Decisions
- Keep CSS property names, only change values
- Russian-only, no EN translations needed
- Preserve all sessionStorage/localStorage keys
Learnings (2026-05-15)
- DmTabs.astro created: pill-style tab navigation with 4 tabs (Кубики, Инициатива, Справочник, Заметки)
- Uses CSS custom properties exclusively (no hardcoded colors)
- Server-side renders initial
aria-selectedbased onAstro.url.hash - Client script enhances with: click → pushState hash,
dm-tab-changecustom event, keyboard nav (ArrowLeft/Right, Home, End), localStorage persistence (dm-last-tab) - Uses
<a href="#tab">for graceful degradation (JS prevents default) - Touch-friendly sizing:
min-h-[44px] min-w-[80px] - Build passes cleanly
- DmSidebar.astro created: desktop-only sidebar navigation component with user info placeholder, tools section, reference section, and campaigns placeholder
- Sidebar uses emoji icons for tools, gold dot for reference items
- All translations validated against dm-translations.ts keys
- No mobile visibility toggle needed — DmLayout handles
hidden lg:blockfor sidebar column - Component takes optional
userprop withnameandavatarfields
InitiativeTracker Redesign (2026-05-15)
- Wrapped form, list, and empty state in DmCard for consistent card styling
- Changed sessionStorage key from
it-combatantstodm-initiativeper spec - Added inline HP editing: click HP span → input, blur/Enter to save, Escape to cancel
- Added
aria-live="polite"announcer for turn change announcements - Used
dmTranslations(T) for all static template strings; hardcoded Russian in client script - Active row:
bg-[var(--accent)]/10+ purple dot + "Ход" pill badge - Initiative score rendered in
text-[var(--gold)]for emphasis - Delete button: plain
<button>with ghost-like styling and ✕ SVG (DmButton doesn't forward aria-label) - Build passes cleanly
Open5eReference Redesign (2026-05-15)
What changed
- Tabs redesigned from pill buttons to gold-underline style (
border-b-2 border-[var(--gold)]) - Search input wrapped with magnifying-glass SVG icon (absolute positioned,
pointer-events-none) - Filter select styled to match DmInput focus ring (gold instead of accent)
- Results layout changed from vertical list to responsive grid (
grid-cols-1 sm:grid-cols-2) - Result cards use DmCard-like classes (
bg-[var(--bg-card)],border-[var(--border-gold-strong)], shadow) with hover lift (hover:-translate-y-0.5) - Card titles switched to
text-[var(--gold)]withgroup-hover:text-[var(--gold-hover)] - Loading skeletons added: 4 shimmer placeholders in Astro template, toggled via
o5-skeletonscontainer - Custom
@keyframes shimmer+.o5-shimmerclass for gold-tinted skeleton animation - Empty state enhanced with search icon (SVG) and two-line message
- Error state now includes retry button (
DmButtonsecondary variant) wired tomanager.search() - Detail modal card gets
border-2 border-[var(--accent)]for purple-tinted border
Preservation
- All Open5e API calls untouched (
Open5eUIManagerimported from@/lib/client/open5e-ui) - Debounce already implemented in manager (
setQueryDebouncedusessetTimeout300ms); component continues calling it - Pagination, modal ESC/overlay-click close, ARIA attributes all preserved
- All event listeners and state management logic kept verbatim
Verification
- Build passes cleanly (
npm run buildcompletes with no errors)
InitiativeTracker E2E Tests (2026-05-15)
What was done
- Created
tests/dm/initiative.spec.tswith 5 test cases covering:- Adding a combatant with auto-roll
- Sorting by initiative descending (deterministic via manual initiative input)
- Next turn cycling active combatant
- Deleting a combatant
- Mobile viewport rendering
- Added
data-testidattributes toInitiativeTracker.astrofor all test selectors - Added
dataTestidprop forwarding toDmInput.astroandDmButton.astro - Added
activeclass to active combatant row in client script for.activeselector
Bug found and fixed
DmButton.astrodid NOT forward theidprop. InitiativeTracker's client script relies ondocument.getElementById('it-add-btn'),it-roll-btn,it-next-btn,it-clear-btn. Becauseidwas swallowed by DmButton, all button event listeners werenulland the tracker was completely non-functional.- Fix: added
id?: stringto DmButton Props and forwardedid={id}to both<a>and<button>rendered elements.
Test determinism
- The "sort by initiative descending" test in the spec used auto-roll for both combatants, making it non-deterministic (could flake). Fixed by filling the manual initiative input with deterministic values (25 and 10) before adding each combatant.
- Similarly, "next turn" and "delete" tests now use deterministic initiative values to avoid any RNG-related flakiness.
Verification
npm run buildpasses cleanlynpx playwright test tests/dm/initiative.spec.tspasses all 10 tests (5 tests × 2 projects: chromium + mobile-chromium)
Verification (T18)
- Build passes cleanly (
npm run buildexit 0). - Tests pass: 148/148 Vitest, 6/6 Playwright data-migration.
npx tsc --noEmit --project tsconfig.jsonproduces no errors (clean).- Data migration findings:
- Dice history: INCOMPATIBLE — old
resultfield (nototal/rolls) causesrenderHistoryto throw. - Initiative: PARTIAL — old data renders but delete is broken due to missing
id. - Notes: FULLY COMPATIBLE — plain string loads correctly.
- Dice history: INCOMPATIBLE — old
Playwright E2E Testing (2026-05-15)
Discoveries
- DmLayout renders
slot name="context"twice (mobile in<main>+ desktop in<aside>), causing duplicate component instances in DOM. - Astro deduplicates
<script>tags per page, so component scripts run once even when component appears twice. This breaksdocument.getElementById-based scripts. - Fix: refactor scripts to use
querySelectorAllwithin[data-testid]containers and initialize each instance independently. - Playwright
:visiblepseudo-class is essential for selecting the correct instance when DOM has duplicates. new URL("/path", "https://api.example.com/v2")drops the/v2base path because leading/replaces entire path. Must use relative paths or trailing slash on base.- Open5e API
challenge_rating_decimalfield does not exist in v2; returnedtypeis an object{name, key}, not a string.
Test Implementation
- Created
tests/dm/reference.spec.tscovering tab switching, search filtering, detail modal, mobile viewport. - Created
tests/dm/notes.spec.tscovering textarea typing, auto-save indicator, clear button, character counter, mobile viewport. - Added
data-testidattributes toOpen5eReference.astro,NotesPanel.astro, andDmCard.astro. - Fixed
src/lib/open5e/client.tsAPI URL construction bug (missing/v2due to leading slash in endpoint paths).