Commit Graph

170 Commits

Author SHA1 Message Date
Lukas
fba83bebd6 Add JSON import/export for full encounter state
Export and import encounter, undo/redo history, and player characters
as a downloadable .json file. Export/import actions are in the action
bar overflow menu. Import validates using existing rehydration functions
and shows a confirmation dialog when replacing a non-empty encounter.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 14:28:39 +01:00
Lukas
f6766b729d Rename spec 037-undo-redo to 006-undo-redo for sequential numbering
Delete merged feature branches (005–037) that inflated the auto-increment
counter in create-new-feature.sh, and renumber the undo-redo spec to
follow the existing 001–005 sequence.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 11:32:29 +01:00
Lukas
f10c67a5ba Dismiss side panel when encounter becomes empty
All checks were successful
CI / check (push) Successful in 1m7s
CI / build-image (push) Successful in 15s
Closes the stat block / source manager panel when the last combatant
is removed or the encounter is cleared, giving a fully clean state.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
0.9.13
2026-03-27 00:16:32 +01:00
Lukas
9437272fe0 Batch bestiary add produces a single undo entry
All checks were successful
CI / check (push) Successful in 1m10s
CI / build-image (push) Successful in 15s
Extract addOneFromBestiary (no undo) and build addMultipleFromBestiary
on top so confirming N creatures from the bestiary panel creates one
undo entry that restores the entire batch, not N individual entries.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
0.9.12
2026-03-27 00:07:25 +01:00
Lukas
541e04b732 Wrap initiative rolls with undo so they produce undo entries
Initiative rolls (single and bulk) called makeStore() directly from
useInitiativeRolls, bypassing the withUndo wrapper. Expose withUndo
from the encounter context and wrap both roll paths.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 00:06:50 +01:00
Lukas
e9fd896934 Clean up gitignore and CLAUDE.md
All checks were successful
CI / check (push) Successful in 1m8s
CI / build-image (push) Successful in 30s
Add .rodney/ to gitignore. Remove redundant Active Technologies and
Recent Changes sections from CLAUDE.md — info already covered by
Tech Stack and Data & Storage sections.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
0.9.11
2026-03-26 23:36:52 +01:00
Lukas
29cdd19cab Roll back renames on failed compound add operations
addFromBestiary and addFromPlayerCharacter rename existing combatants
before adding the new one. If the add fails, the renames were applied
without an undo entry. Restore the pre-operation snapshot on failure.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 23:31:11 +01:00
Lukas
17cc6ed72c Add undo/redo for all encounter actions
Memento-based undo/redo with full encounter snapshots. Undo stack
capped at 50 entries, persisted to localStorage. Triggered via
buttons in the top bar (inboard of turn navigation) and keyboard
shortcuts (Ctrl+Z / Ctrl+Shift+Z, Cmd on Mac, case-insensitive key
matching). Clear encounter resets both stacks.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 23:30:33 +01:00
Lukas
9d81c8ad27 Atomic addCombatant with optional CombatantInit bag
addCombatant now accepts an optional init parameter for pre-filled stats
(HP, AC, initiative, creatureId, color, icon, playerCharacterId), making
combatant creation a single atomic operation with domain validation.

This eliminates the multi-step store.save() bypass in addFromBestiary and
addFromPlayerCharacter, and removes the CombatantOpts/applyCombatantOpts
helpers. Also extracts shared initiative sort logic into initiative-sort.ts
used by both addCombatant and setInitiative.

Closes #15

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 22:13:20 +01:00
Lukas
7199b9d2d9 Add browser-interactive-testing skill and fix Biome/audit config
Integrate the rodney/showboat browser automation skill for headless
Chrome screenshots and testing. Exclude .rodney and .agent-tests
from Biome file scanning. Add picomatch override to resolve
high-severity ReDoS vulnerability in knip/jscpd transitive deps.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 20:10:57 +01:00
Lukas
158bcf1468 Add ADRs for branded types, bestiary loading, and pre-commit gates
ADR-003: Branded types for compile-time identity safety at zero
runtime cost.
ADR-004: On-demand bestiary via compact index + IndexedDB cache,
avoiding distribution of copyrighted content.
ADR-005: All quality gates at pre-commit for tight agent feedback
loops, with analysis of per-change hooks as a future option.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 15:02:48 +01:00
Lukas
fab9301b20 Decompose ActionBar into hook and focused sub-components
All checks were successful
CI / check (push) Successful in 1m7s
CI / build-image (push) Has been skipped
Extract useActionBarState hook with all search/queue/mode state and
handlers. Extract RollAllButton (context-consuming, zero props),
BrowseSuggestions, CustomStatFields, and refactor AddModeSuggestions
to use grouped SuggestionActions interface (11 props → 6).

ActionBar is now a ~120-line layout shell.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 11:41:35 +01:00
Lukas
d653cfe489 Add ADR template and first two architecture decision records
Document the errors-as-values pattern (ADR-001) and domain events
as plain data objects (ADR-002) to capture the reasoning behind
these foundational design choices.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 11:19:54 +01:00
Lukas
228a2603e8 Add Sapped and Slowed conditions for 5.5e weapon mastery
All checks were successful
CI / check (push) Successful in 1m8s
CI / build-image (push) Successful in 15s
These D&D 2024 weapon mastery conditions are edition-gated: they only
appear in the condition picker when 5.5e rules are selected. Applied
conditions still render correctly regardless of edition setting.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
0.9.10
2026-03-25 00:31:41 +01:00
Lukas
27ff8ba1ad Collapse hover-only buttons to zero width when hidden
All checks were successful
CI / check (push) Successful in 1m8s
CI / build-image (push) Successful in 16s
Edit and add-condition buttons now take no space when not hovered,
eliminating the gap between name and condition icons. They slide in
smoothly on hover with a 150ms transition.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
0.9.9
2026-03-25 00:19:47 +01:00
Lukas
4cfcefe6c3 Hide custom stat fields on mobile, fix action bar gap consistency
All checks were successful
CI / check (push) Successful in 1m7s
CI / build-image (push) Successful in 16s
Init/AC/MaxHP inputs are hidden on phones — users set these values
directly in the combatant row after adding. Fixes uneven spacing
between action bar elements by using consistent gap-3.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
0.9.8
2026-03-24 23:41:18 +01:00
Lukas
8baccf3cd3 Merge 006-mobile-touch-targets: mobile foundation and bug fixes
All checks were successful
CI / check (push) Successful in 1m8s
CI / build-image (push) Successful in 16s
- iOS zoom fix (16px input font)
- Safe area insets for notched phones
- viewport-fit=cover
- Action bar flex-wrap for narrow screens
- Slightly increased row padding on mobile
- Fix stat block panel showing wrong creature on first open
- Skip auto-opening stat block when adding on mobile
0.9.7
2026-03-24 23:26:33 +01:00
Lukas
a9ca31e9bc Skip auto-opening stat block panel when adding creatures on mobile
On desktop the panel has room alongside the combatant list, but on
mobile it covers the screen and disrupts the add-combatant flow.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 23:22:54 +01:00
Lukas
64a1f0b8db Add mobile foundation: iOS zoom fix, safe area insets, row padding
- Input base font 16px on mobile to prevent iOS Safari auto-zoom
- Safe area insets for notched phones (top/bottom bars)
- viewport-fit=cover to enable safe area env() values
- Action bar flex-wrap for custom stat field overflow
- Slightly increased row padding on mobile (py-3 sm:py-2)
- Removed redundant font-size classes from Input usages

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 23:19:10 +01:00
Lukas
5e5812bcaa Fix stat block panel showing wrong creature on first open
useAutoStatBlock was overriding the user's creature selection when
the panel transitioned from closed to open. Now only auto-updates
when the active turn index changes (advance/retreat), not when the
panel mode changes.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 23:18:49 +01:00
Lukas
9e09c8ae2a Sync theme-color meta tag with active light/dark theme
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 17:59:13 +01:00
Lukas
4d0ec0c7b2 Add Open Graph meta tags for link previews in messengers
All checks were successful
CI / check (push) Successful in 1m8s
CI / build-image (push) Successful in 15s
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
0.9.6
2026-03-24 17:54:05 +01:00
Lukas
fe62f2eb2f Add PWA manifest, app icons, and favicon
D20-themed icon in app color scheme for home screen installation,
favicon, and apple-touch-icon. Standalone display mode makes the
app feel native when launched from home screen.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 17:51:28 +01:00
Lukas
7092677273 Make layout full-width on mobile with docked top/bottom bars
Remove max-width constraint and horizontal padding on small screens
so content goes edge-to-edge. Turn navigation and action bar lose
rounded corners on mobile and dock flush to top/bottom edges.
Desktop layout (sm: and up) is unchanged.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 17:36:01 +01:00
Lukas
e1a06c9d59 Tighten combatant row grid on mobile for better name visibility
Reduce grid gap and initiative column width on small screens,
restoring full layout at the sm breakpoint.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 17:35:42 +01:00
Lukas
4043612ccf Add rules edition setting for condition tooltips (5e/5.5e)
All checks were successful
CI / check (push) Successful in 1m8s
CI / build-image (push) Successful in 16s
Introduce a settings modal (opened from the kebab menu) with a rules
edition selector for condition tooltip descriptions and a theme picker
replacing the inline cycle button. About half the conditions have
meaningful mechanical differences between editions.

- Add description5e field to ConditionDefinition with 5e (2014) text
- Add RulesEditionProvider context with localStorage persistence
- Create SettingsModal with Conditions and Theme sections
- Wire condition tooltips to edition-aware descriptions
- Fix 6 inaccurate 5.5e condition descriptions
- Update spec 003 with stories CC-3, CC-8 and FR-095–FR-102

Closes #12

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
0.9.5
2026-03-24 17:08:41 +01:00
Lukas
cfd4aef724 Expand pre-2024 {@atk} tags to full attack type labels in stat blocks
Old 5etools data uses {@atk mw} instead of {@atkr m}, which the generic
tag handler was reducing to bare "mw" text. Adds dedicated handling for
all {@atk} variants and bumps the bestiary cache version to clear stale
processed data.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 10:11:54 +01:00
Lukas
968cc7239b Downgrade Knip 6 to 5 for CI compatibility
All checks were successful
CI / check (push) Successful in 1m6s
CI / build-image (push) Successful in 22s
Knip 6 uses oxc-parser which attempts a 6GB ArrayBuffer allocation
that fails on the CI runner (3.7GB RAM, no swap). This is a known
oxc allocator issue (oxc-project/oxc#20513) with no fix yet.
Revert to Knip 5 which uses TypeScript's parser. Also revert the
NODE_OPTIONS workaround since it's no longer needed.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
0.9.4
2026-03-23 16:31:58 +01:00
Lukas
d9562f850c Inline NODE_OPTIONS for CI check step
Some checks failed
CI / check (push) Failing after 18s
CI / build-image (push) Has been skipped
Step-level env may not propagate to pnpm subprocesses in Gitea
Actions. Inline the variable directly in the command instead.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 14:48:33 +01:00
Lukas
ec9f2e7877 Increase Node heap limit for CI check step
Some checks failed
CI / check (push) Failing after 16s
CI / build-image (push) Has been skipped
oxc-parser (used by Knip) fails with ArrayBuffer allocation
error on the CI runner's default heap size. Set max-old-space-size
to 2048MB to accommodate the buffer allocation.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 14:40:33 +01:00
Lukas
c4079c384b Fix initiative input clipping inside container
Some checks failed
CI / check (push) Failing after 17s
CI / build-image (push) Has been skipped
Widen initiative grid column from 3rem to 3.5rem and use w-full
on the editing input so it fits within the rounded background
container without overflowing.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 14:26:39 +01:00
Lukas
a4285fc415 Polish stat containers and optical alignment
Refine AC shield to use filled shape with border color instead of
stroke outline. Add subtle muted background to initiative container.
Apply optical vertical centering to round badge text (-3px) and
AC shield number (-2px). Unify round badge corners to rounded-md.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 14:23:22 +01:00
Lukas
9c0e3398f1 Move AC shield next to initiative and refine shield style
Place AC between initiative and name to group static reference
stats on the left, leaving HP as the sole dynamic element on
the right. Dim the shield outline to 40% opacity so it recedes
visually, and nudge the number up 2px toward the visual center.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 13:54:20 +01:00
Lukas
9cdf004c15 Restyle HP display as compact rounded pill
Group current HP, temp HP, and max HP into a single bordered
pill container with a subtle slash separator. Removes the
scattered layout with separate elements and gaps. Temp HP +N
only renders when present (no invisible spacer).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 13:11:28 +01:00
Lukas
8bf69fd47d Add temporary hit points as a separate damage buffer
Temp HP absorbs damage before current HP, cannot be healed, and
does not stack (higher value wins). Displayed as cyan +N after
current HP with a Shield button in the HP adjustment popover.
Column space is reserved across all rows only when any combatant
has temp HP. Concentration pulse fires on any damage, including
damage fully absorbed by temp HP.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 11:39:47 +01:00
Lukas
7b83e3c3ea Upgrade pnpm 10.6.0 to 10.32.1
Fixes Node DEP0169 url.parse() deprecation warning

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 10:17:07 +01:00
Lukas
c3c2cad798 Upgrade lefthook 1 to 2
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 10:15:23 +01:00
Lukas
3f6140303d Upgrade knip 5 to 6
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 10:09:56 +01:00
Lukas
fd30278474 Upgrade jsdom 28 to 29
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 10:09:11 +01:00
Lukas
278c06221f Upgrade Vite 8, plugin-react 6, Vitest 4
Vite 6→8 (Rolldown/Oxc), @vitejs/plugin-react 4→6 (Babel-free), Vitest 3→4 (AST coverage)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 09:41:14 +01:00
Lukas
722e8cc627 Update patch/minor dev dependencies
Biome 2.4.7→2.4.8, Tailwind 4.2.1→4.2.2, oxlint 1.55→1.56, oxlint-tsgolint 0.16→0.17.1

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 09:17:26 +01:00
Lukas
64741956dd Preserve search input and focus when toggling browse mode
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-22 23:25:40 +01:00
Lukas
6336dec38a Add condition tooltips with 5.5e descriptions
All checks were successful
CI / check (push) Successful in 1m22s
CI / build-image (push) Successful in 19s
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
0.9.3
2026-03-22 22:48:23 +01:00
Lukas
9def2d7c24 Fix condition picker clipping out of viewport
All checks were successful
CI / check (push) Successful in 1m17s
CI / build-image (push) Successful in 27s
Render condition picker via React portal with fixed positioning so it
is no longer clipped by the overflow-y-auto combatant list container.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
0.9.2
2026-03-22 22:34:15 +01:00
Lukas
f729e37689 Replace book icon with name-click stat block toggle and pencil rename
Name click now opens/collapses the stat block panel; a hover-visible
pencil icon next to the name handles renaming. Removes the standalone
book icon for a cleaner, more intuitive combatant row.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-22 22:29:56 +01:00
Lukas
86768842ff Refactor App.tsx from god component to context-based architecture
All checks were successful
CI / check (push) Successful in 1m18s
CI / build-image (push) Has been skipped
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-19 15:33:33 +01:00
Lukas
6584d8d064 Add advantage/disadvantage rolling for initiative
All checks were successful
CI / check (push) Successful in 1m17s
CI / build-image (push) Successful in 19s
Right-click or long-press the d20 button (per-combatant or Roll All)
to open a context menu with Advantage and Disadvantage options.
Normal left-click behavior is unchanged.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
0.9.1
2026-03-18 09:16:04 +01:00
Lukas
7f38cbab73 Preserve stat block panel collapsed state on turn advance
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-17 23:23:52 +01:00
Lukas
2971898f0c Add dark and light theme with OS preference support
All checks were successful
CI / check (push) Successful in 1m22s
CI / build-image (push) Successful in 36s
Follow OS color scheme by default, with a three-way toggle
(System / Light / Dark) in the kebab menu. Light theme uses warm,
neutral tones with soft card-to-background contrast. Semantic colors
(damage, healing, conditions) keep their hue across themes.

Closes #10

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
0.9.0
2026-03-17 13:24:18 +01:00
Lukas
43780772f6 Improve bestiary icon UX and auto-update stat block on turn change
- Use Book/BookOpen icons to indicate stat block open state
- Bump combatant icons (bestiary + PC) from 14px to 16px
- Use text-foreground for bestiary icon visibility
- Auto-update stat block panel to active combatant's creature on turn advance
- Update bestiary spec edge case to reflect new behavior

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-17 12:48:38 +01:00