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>
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>
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>
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>
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>
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>