When a user clicks the d20 to roll initiative for a single combatant whose
bestiary source isn't cached, show an informative toast and open the stat
block panel so they can load the source directly.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
When the side panel is in its initial closed state (not user-collapsed),
adding a combatant from the bestiary now opens the panel to show its
stat block. This makes the panel discoverable without overriding a
deliberate collapse.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Tailwind v4's static extractor missed classes adjacent to ${} in template
literals (e.g. `pb-8${...}`), causing missing styles in production builds.
Migrated all dynamic classNames to cn() and added a check script to prevent
regressions.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
Unify the action bar into a single search input with inline bestiary
dropdown. Clicking a dropdown entry queues it with +/- count controls
and a confirm button; Enter or confirm adds N copies to combat.
When no bestiary match exists, optional Init/AC/MaxHP fields appear
for custom creatures. The eye icon opens a separate search dropdown
to preview stat blocks without leaving the add flow.
Fix batch-add bug where only the last creature got a creatureId by
using store.save() instead of setEncounter() in addFromBestiary.
Prevent dropdown buttons from stealing input focus so Enter confirms
the queued batch.
Remove the now-redundant BestiarySearch component.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace the close button and heading with fold/unfold controls that
collapse the panel to a slim right-edge tab showing the creature name
vertically, and add a pin button (xl+ viewports with creature loaded)
that opens the creature in a second left-side panel for simultaneous
reference. Fold state is respected on turn change. 19 acceptance tests.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add padding to the inner combatant list container so the box-shadow glow
from the concentration-damage animation renders fully on all sides,
preventing clipping by the scrollable parent's implicit overflow-x.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>