Commit Graph

109 Commits

Author SHA1 Message Date
Lukas
7a87d979bf Fix native dialog centering and text color
All checks were successful
CI / check (push) Successful in 1m24s
CI / build-image (push) Successful in 19s
Tailwind v4 preflight resets dialog margins and color inheritance.
Add m-auto to restore showModal() centering, and text-foreground
so ghost buttons inherit the correct color.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
0.7.6
2026-03-16 11:55:18 +01:00
Lukas
02096bcee6 Fix bottom bar clipping on hosted deployment
All checks were successful
CI / check (push) Successful in 1m29s
CI / build-image (push) Successful in 31s
Use h-dvh (100dvh) instead of h-screen (100vh) so the layout
accounts for browser chrome (address bar, bottom toolbar).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
0.7.5
2026-03-16 11:50:59 +01:00
Lukas
c092192b0e Add _copy field to RawMonster, remove noExplicitAny biome-ignore
The _copy field is a real property in the raw bestiary JSON — adding it
to the interface is more accurate than casting through any. Ratchet
source ignore threshold from 3 to 2.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-16 11:31:34 +01:00
Lukas
4d1a7c6420 Remove noAwaitInLoops biome-ignore by chaining batches with reduce
Replace the for-loop with await-in-loop with a .reduce() chain that
sequences Promise.allSettled batches without triggering the lint rule.
Ratchet source ignore threshold from 4 to 3.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-16 11:24:31 +01:00
Lukas
46b444caba Refactor combatant row: single-click rename, book icon for stat blocks
Replace 250ms click timer and double-click detection with immediate
single-click rename for all combatant types. Add a BookOpen icon before
the name on bestiary rows as the dedicated stat block trigger. Remove
auto-show stat block on turn advance. Update specs to match: consistent
collapse/expand terminology, book icon requirements, no row-click stat
block behavior.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-16 11:14:28 +01:00
Lukas
e68145319f Add biome-ignore backpressure script, convert modals to native <dialog>
Adds scripts/check-lint-ignores.mjs with four enforcement mechanisms:
ratcheting count cap (12 source / 3 test), banned rule prefixes,
required justification, and separate test thresholds. Wired into
pnpm check.

Converts player-management and create-player-modal from div-based
modals to native <dialog> with showModal()/close(), removing 8
biome-ignore comments. Remaining ignores are legitimate (Biome
false positives or stopPropagation wrappers with no fitting role).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-15 16:21:46 +01:00
Lukas
d64e1f5e4a Add integration tests for App.tsx with accessible HP status labels
3 integration tests render the full <App /> and exercise multi-component
flows: add/remove combatant, turn tracking across two combatants, and
HP adjustment with unconscious state. Add aria-label to the clickable HP
button so tests query accessible names instead of CSS classes.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-15 01:46:32 +01:00
Lukas
ef0b755eec Add coverage thresholds for all tested directories, exclude dist from coverage
All checks were successful
CI / check (push) Successful in 1m4s
CI / build-image (push) Successful in 27s
Adds threshold entries for application, hooks, components, and components/ui
directories. Ratchets existing thresholds to match actual coverage. Excludes
**/dist/** from coverage to remove build output noise.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
0.7.4
2026-03-14 16:19:56 +01:00
Lukas
4be816d10f Add test coverage for 5 components: HpAdjustPopover, ConditionPicker, CombatantRow, ActionBar, SourceManager
Adds aria-label attributes to HP placeholder and source delete buttons
for both accessibility and testability.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-14 15:53:01 +01:00
Lukas
e531d82d1b Add test coverage for 3 hooks: useEncounter, usePlayerCharacters, useSidePanelState
29 tests covering state transitions, persistence sync, domain error
propagation, bestiary/PC add flows, and panel state machine logic.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-14 15:38:51 +01:00
Lukas
5a262c66cd Add test coverage for all 17 application layer use cases
Tests verify the get→call→save wiring and error propagation for each
use case. The 15 formulaic use cases share a test file; rollInitiative
and rollAllInitiative have dedicated suites covering their multi-step
logic (creature lookup, modifier calculation, iteration, early return).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-14 15:31:35 +01:00
Lukas
32b69f8df1 Use Readonly props and optional chaining/nullish coalescing
Mark component props as Readonly<> across 15 component files and
simplify edit-player-character field access with optional chaining
and nullish coalescing.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-14 15:13:39 +01:00
Lukas
8efba288f7 Use String.raw and RegExp.exec, add prefer-regexp-exec oxlint rule
Replace escaped backslash in template literal with String.raw in
auto-number.ts. Use RegExp#exec() instead of String#match() in
bestiary-adapter.ts. Enable typescript/prefer-regexp-exec in oxlint
for automated enforcement.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-14 14:55:54 +01:00
Lukas
c94c30e459 Add oxlint for type-aware linting that Biome cannot cover
Install oxlint with tsgolint for TypeScript type information. Enable
rules for unnecessary type assertions, deprecated API usage, preferring
replaceAll over replace with global regex, and String.raw for escaped
backslashes. Fix all violations: remove redundant as-casts, replace
deprecated FormEvent with SubmitEvent, convert replace(/g) to
replaceAll, and use String.raw in escapeRegExp. Add oxlint to the
pnpm check gate alongside Biome.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-14 14:41:30 +01:00
Lukas
36768d3aa1 Upgrade Biome to 2.4.7 and enable 54 additional lint rules
Add rules covering bug prevention (noLeakedRender, noFloatingPromises,
noImportCycles, noReactForwardRef), security (noScriptUrl, noAlert),
performance (noAwaitInLoops, useTopLevelRegex), and code style
(noNestedTernary, useGlobalThis, useNullishCoalescing, useSortedClasses,
plus ~40 more). Fix all violations: extract top-level regex constants,
guard React && renders with boolean coercion, refactor nested ternaries,
replace window with globalThis, sort Tailwind classes, and introduce
expectDomainError test helper to eliminate conditional expects.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-14 14:25:09 +01:00
Lukas
473f1eaefe Exclude agent plan files from version control
All checks were successful
CI / check (push) Successful in 46s
CI / build-image (push) Successful in 26s
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
0.7.3
2026-03-14 13:10:18 +01:00
Lukas
971e0ded49 Replace ref+tick workaround with proper state in useBestiary
Store creature map in useState instead of useRef with a dummy
tick counter. React now re-renders naturally when the map changes.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-14 13:02:24 +01:00
Lukas
36dcfc5076 Use useOptimistic for instant source manager cache clearing
Source rows disappear immediately when cleared instead of waiting
for the IndexedDB operation to complete. Real state syncs after.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-14 13:02:24 +01:00
Lukas
127ed01064 Add self-review checklist to CLAUDE.md
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-14 13:02:24 +01:00
Lukas
179c3658ad Use useDeferredValue for search dropdown rendering
Defer rendering of bestiary suggestions and player character matches
in ActionBar so the input stays responsive as the bestiary grows.
Keyboard navigation and selection logic still use the latest values.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-14 13:02:23 +01:00
Lukas
01f2bb3ff1 Move derived encounter flags into useEncounter() hook
Relocate isEmpty, hasCreatureCombatants, and canRollAllInitiative
from App.tsx into useEncounter(), reducing inline derivations in
the component (Phase 5 of App decomposition plan).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-14 13:02:23 +01:00
Lukas
930301de71 Rename fold/unfold to collapse/expand across panel code
Aligns terminology with standard UI conventions. Renames props,
state, handlers, aria-labels, test descriptions, and the test file.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-14 13:02:23 +01:00
Lukas
aa806d4fb9 Show bulk import toast when panel is folded
Previously the toast only showed when the panel was not in bulk-import
mode. Now it also shows when the panel is folded, since the user can't
see the in-panel progress indicator.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-14 13:02:23 +01:00
Lukas
61bc274715 Extract BulkImportToasts component from App.tsx
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-14 13:02:23 +01:00
Lukas
1932e837fb Extract PlayerCharacterSection component from App.tsx
Move player character modal state (createPlayerOpen, managementOpen,
editingPlayer) into a self-contained component with an imperative ref
handle. Closing the create/edit modal now returns to management.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-14 13:02:14 +01:00
Lukas
cce87318fb Extract useSidePanelState hook from App.tsx
Move panel view state, fold/pin state, isWideDesktop media query,
and all related handlers into a dedicated hook, reducing App.tsx
by ~80 lines of state management boilerplate.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-14 13:02:03 +01:00
Lukas
3ef2370a34 Replace panel mode booleans with discriminated union
Three mutually exclusive state variables (selectedCreatureId,
bulkImportMode, sourceManagerMode) replaced with a single PanelView
union type, eliminating impossible states and boolean-clearing
boilerplate in handlers.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-14 13:02:03 +01:00
Lukas
c75d148d1e Fix high-severity undici vulnerability via pnpm override
Override undici to >=7.24.0 to resolve GHSA-v9p9-hfj2-hcw8
(WebSocket 64-bit length overflow). The vulnerable version was
pulled in transitively via jsdom@28.1.0.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-14 13:02:03 +01:00
Lukas
63e233bd8d Switch side panel to stat block when advancing turns
All checks were successful
CI / check (push) Successful in 45s
CI / build-image (push) Successful in 18s
Previously the import/sources view would stay open when navigating to
the next combatant. Now advancing turns clears those modes so the active
creature's stat block is shown.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
0.7.2
2026-03-13 19:03:11 +01:00
Lukas
8c62ec28f2 Rename "Bulk Import" to "Import All Sources" and remove file size mention
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 19:01:03 +01:00
Lukas
72195e90f6 Show toast when roll-all-initiative skips combatants without loaded sources
Previously the button silently did nothing for creatures whose bestiary
source wasn't loaded. Now it reports how many were skipped and why. Also
keeps the roll-all button visible (but disabled) when there's nothing
left to roll, and moves toasts to the bottom-left corner.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 18:58:25 +01:00
Lukas
6ac8e67970 Move source manager from combatant area to side panel
Source management now opens in the right side panel (like bulk import
and stat blocks) instead of rendering inline above the combatant list.
All three panel modes properly clear each other on activation.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 18:40:28 +01:00
Lukas
a4797d5b15 Unfold side panel when triggering bulk import from overflow menu
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 18:33:05 +01:00
Lukas
d48e39ced4 Fix input not clearing after adding player character from suggestions
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 18:30:24 +01:00
Lukas
b7406c4b54 Make player character color and icon optional
Clicking an already-selected color or icon in the create/edit form now
deselects it. PCs without a color use the default combatant styling;
PCs without an icon show no icon. Domain, application, persistence,
and display layers all updated to handle the optional fields.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 18:01:20 +01:00
Lukas
07cdd4867a Fix custom combatant form disappearing when dismissing suggestions
All checks were successful
CI / check (push) Successful in 46s
CI / build-image (push) Successful in 18s
The "Add as custom" button and Escape key were clearing the name input
along with the suggestions, preventing the custom fields (Init, AC,
MaxHP) from ever appearing. Now only the suggestions are dismissed,
keeping the typed name intact so the custom combatant form renders.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
0.7.1
2026-03-13 17:30:17 +01:00
Lukas
85acb5c185 Migrate icon buttons to Button component and simplify size variants
All checks were successful
CI / check (push) Successful in 48s
CI / build-image (push) Successful in 18s
Replace raw <button> elements with Button variant="ghost" in stat-block
panel, toast, player modals. Add icon-sm size variant (h-6 w-6) for
compact contexts. Consolidate text button sizes into a single default
(h-8 px-3), removing the redundant sm variant. Add size prop to
ConfirmButton for consistent sizing.

Button now has three sizes: default (text), icon, icon-sm.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
0.7.0
2026-03-13 17:22:00 +01:00
Lukas
f9ef64bb00 Unify hover effects via semantic theme tokens
Replace one-off hover colors with hover-neutral/hover-destructive tokens
so all interactive elements respond consistently to theme changes. Fix
hover-neutral-bg token value (was identical to card surface, making hover
invisible on card backgrounds) to a semi-transparent primary tint. Switch
turn nav buttons to outline variant for visible hover feedback. Convert HP
popover damage/heal to plain buttons to avoid ghost variant hover conflict
with tailwind-merge.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 16:58:01 +01:00
Lukas
bd39808000 Declutter action bars: overflow menu, browse toggle, conditional D20
All checks were successful
CI / check (push) Successful in 48s
CI / build-image (push) Successful in 18s
Top bar stripped to turn navigation only (Prev, round badge, Clear, Next).
Roll All Initiative, Manage Sources, and Bulk Import moved to a new
overflow menu in the bottom bar. Player Characters also moved there.

Browse stat blocks is now an Eye/EyeOff toggle inside the search input
that switches between add mode and browse mode. Add button only appears
when entering a custom creature name. Roll All Initiative button shows
conditionally — only when bestiary creatures lack initiative values.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
0.6.0
2026-03-13 16:31:25 +01:00
Lukas
75778884bd Hide top bar in empty state and animate it in with first combatant
All checks were successful
CI / check (push) Successful in 45s
CI / build-image (push) Successful in 18s
The turn navigation bar is now hidden when no combatants exist, keeping
the empty state clean. It slides down from above when the first
combatant is added, synchronized with the action bar settling animation.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
0.5.2
2026-03-13 14:43:41 +01:00
Lukas
72d4f30e60 Center action bar in empty state for better onboarding UX
Replace the abstract + icon with the actual input field centered at the
optical center when no combatants exist. Animate the transition in both
directions: settling down when the first combatant is added, rising up
when all combatants are removed.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 14:29:51 +01:00
Lukas
96b37d4bdd Color player character names instead of left border
All checks were successful
CI / check (push) Successful in 45s
CI / build-image (push) Successful in 18s
Player characters now show their chosen color on their name text
rather than as a left border glow. Left border is reserved for
active row (accent) and concentration (purple).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
0.5.1
2026-03-13 11:52:09 +01:00
Lukas
76ca78c169 Improve player modals: Escape to close, trash icon for delete
Both player management and create/edit modals now close on Escape.
Delete player character button uses Trash2 icon instead of X to
distinguish permanent deletion from dismissal.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 11:51:58 +01:00
Lukas
b0c27b8ab9 Add red hover effect to destructive buttons
ConfirmButton now shows hover:text-hover-destructive in its default
state. Source manager delete buttons and Clear All get matching
destructive hover styling.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 11:51:34 +01:00
Lukas
458c277e9f Polish UI: consistent icon buttons, tooltips, modal backdrop close, and top bar layout
All checks were successful
CI / check (push) Successful in 45s
CI / build-image (push) Successful in 17s
- Standardize icon button sizing (size="icon") and color (text-muted-foreground) across top and bottom bars
- Group bottom bar icon buttons with gap-0 to match top bar style
- Add missing tooltips/aria-labels for stat block viewer, bulk import buttons
- Replace Settings icon with Library for source manager
- Make step forward/back buttons use primary (solid) variant
- Move round badge next to combatant name in center of top bar
- Close player create/edit and management modals on backdrop click

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
0.5.0
2026-03-12 18:47:47 +01:00
Lukas
91703ddebc Add player character management feature
All checks were successful
CI / check (push) Successful in 45s
CI / build-image (push) Successful in 18s
Persistent player character templates (name, AC, HP, color, icon) with
full CRUD, bestiary-style search to add PCs to encounters with pre-filled
stats, and color/icon visual distinction in combatant rows. Also stops
the stat block panel from auto-opening when adding a creature.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
0.4.0
2026-03-12 18:11:08 +01:00
Lukas
768e7a390f Improve empty encounter UX with interactive add button
All checks were successful
CI / check (push) Successful in 44s
CI / build-image (push) Successful in 22s
Replace the static "No combatants yet" text with a centered, breathing
"+" icon that focuses the action bar input on click, guiding users to
add their first combatant.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
0.3.0
2026-03-12 10:56:56 +01:00
Lukas
7feaf90eab Add "custom creature" option to bestiary suggestions dropdown
When typing a name that partially matches bestiary entries, users
couldn't access the custom creature fields (Init/AC/MaxHP). Now a
prominent option at the top of the dropdown lets users dismiss
suggestions and add a custom creature instead, with an Esc hint.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 10:45:39 +01:00
Lukas
b39e4923e1 Remove demo combatants and allow empty encounters
All checks were successful
CI / check (push) Successful in 45s
CI / build-image (push) Successful in 28s
Empty encounters are now valid (INV-1 updated). New sessions start
with zero combatants instead of pre-populated Aria/Brak/Cael.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
0.2.0
2026-03-12 10:24:26 +01:00
Lukas
369feb3cc8 Add deploy step to CI workflow to auto-restart container on tag push
All checks were successful
CI / check (push) Successful in 43s
CI / build-image (push) Successful in 17s
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
0.1.0
2026-03-12 10:19:34 +01:00