Lukas 460c65bf49 Implement stat block panel fold/unfold and pin-to-second-panel
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>
2026-03-11 14:18:15 +01:00

Encounter Console

A local-first initiative tracker and encounter manager for tabletop RPGs (D&D 5e / 2024). Runs entirely in the browser — no server, no account, no data leaves your machine.

What it does

  • Initiative tracking — add combatants, roll initiative (manual or d20), cycle turns and rounds
  • Encounter state — HP, AC, conditions, concentration tracking with visual status indicators
  • Bestiary integration — import bestiary JSON sources, search creatures, and view full stat blocks
  • Persistent — encounters survive page reloads via localStorage; bestiary data cached in IndexedDB

Prerequisites

  • Node.js 22+
  • pnpm 10.6+

Getting Started

pnpm install
pnpm --filter web dev

Open http://localhost:5173.

Scripts

Command Description
pnpm --filter web dev Start the dev server
pnpm --filter web build Production build
pnpm test Run all tests (Vitest)
pnpm check Full merge gate (knip, biome, typecheck, test, jscpd)

Project Structure

apps/web/          React 19 + Vite — UI components, hooks, adapters
packages/domain/   Pure functions — state transitions, types, validation
packages/app/      Use cases — orchestrates domain via port interfaces
data/bestiary/     Bestiary index for creature search
scripts/           Build tooling (layer boundary checks, index generation)
specs/             Feature specifications (spec → plan → tasks)

Architecture

Strict layered architecture with enforced dependency direction:

apps/web (adapters)  →  packages/application (use cases)  →  packages/domain (pure logic)

Domain is pure — no I/O, no randomness, no framework imports. Layer boundaries are enforced by automated import checks that run as part of the test suite. See CLAUDE.md for full conventions.

Description
Initiative Tracker
Readme 2.6 MiB
Languages
TypeScript 85.5%
Shell 9.8%
JavaScript 3%
CSS 1.1%
Python 0.4%
Other 0.1%