Implement the 018-combatant-concentration feature that adds a per-combatant concentration toggle with Brain icon, purple border accent, and damage pulse animation in the encounter tracker
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
73
specs/018-combatant-concentration/plan.md
Normal file
73
specs/018-combatant-concentration/plan.md
Normal file
@@ -0,0 +1,73 @@
|
||||
# Implementation Plan: Combatant Concentration
|
||||
|
||||
**Branch**: `018-combatant-concentration` | **Date**: 2026-03-06 | **Spec**: [spec.md](./spec.md)
|
||||
**Input**: Feature specification from `/specs/018-combatant-concentration/spec.md`
|
||||
|
||||
## Summary
|
||||
|
||||
Add concentration as a separate per-combatant boolean state (not a condition). A Brain icon toggle appears on hover (or stays visible when active), a colored left border accent marks concentrating combatants, and a pulse animation fires when a concentrating combatant takes damage. Implementation follows the existing toggle-condition pattern across all three layers (domain, application, web adapter).
|
||||
|
||||
## Technical Context
|
||||
|
||||
**Language/Version**: TypeScript 5.8 (strict mode, verbatimModuleSyntax)
|
||||
**Primary Dependencies**: React 19, Vite 6, Tailwind CSS v4, Lucide React (icons)
|
||||
**Storage**: Browser localStorage (existing adapter, transparent JSON serialization)
|
||||
**Testing**: Vitest
|
||||
**Target Platform**: Modern browsers (local-first, single-user)
|
||||
**Project Type**: Web application (monorepo: domain / application / web)
|
||||
**Performance Goals**: Instant UI response on toggle; pulse animation ~600-800ms
|
||||
**Constraints**: No migration needed for localStorage; new optional boolean field is backward-compatible
|
||||
**Scale/Scope**: Single-user encounter tracker; ~10-20 combatants per encounter
|
||||
|
||||
## Constitution Check
|
||||
|
||||
*GATE: Must pass before Phase 0 research. Re-check after Phase 1 design.*
|
||||
|
||||
| Principle | Status | Notes |
|
||||
|-----------|--------|-------|
|
||||
| I. Deterministic Domain Core | PASS | `toggleConcentration` is a pure function: same input encounter + combatant ID yields same output. No I/O, randomness, or clocks. |
|
||||
| II. Layered Architecture | PASS | Domain defines the toggle function; Application orchestrates via `EncounterStore` port; Web adapter implements UI + persistence. No layer violations. |
|
||||
| III. Agent Boundary | N/A | No agent/AI features in this feature. |
|
||||
| IV. Clarification-First | PASS | Spec is fully specified; no NEEDS CLARIFICATION markers. |
|
||||
| V. Escalation Gates | PASS | All work is within spec scope. |
|
||||
| VI. MVP Baseline Language | PASS | No permanent bans introduced. |
|
||||
| VII. No Gameplay Rules | PASS | Concentration is state tracking only; no automatic save mechanics or rule enforcement. |
|
||||
|
||||
All gates pass. No violations to track.
|
||||
|
||||
## Project Structure
|
||||
|
||||
### Documentation (this feature)
|
||||
|
||||
```text
|
||||
specs/018-combatant-concentration/
|
||||
├── plan.md
|
||||
├── research.md
|
||||
├── data-model.md
|
||||
├── quickstart.md
|
||||
└── tasks.md
|
||||
```
|
||||
|
||||
### Source Code (repository root)
|
||||
|
||||
```text
|
||||
packages/domain/src/
|
||||
├── types.ts # Add isConcentrating to Combatant
|
||||
├── events.ts # Add ConcentrationStarted/ConcentrationEnded
|
||||
├── toggle-concentration.ts # New pure domain function
|
||||
├── index.ts # Re-export new function + events
|
||||
└── __tests__/
|
||||
└── toggle-concentration.test.ts # New test file
|
||||
|
||||
packages/application/src/
|
||||
├── toggle-concentration-use-case.ts # New use case
|
||||
└── index.ts # Re-export
|
||||
|
||||
apps/web/src/
|
||||
├── hooks/use-encounter.ts # Add toggleConcentration callback
|
||||
├── components/combatant-row.tsx # Add Brain icon toggle + left border accent + pulse
|
||||
├── persistence/encounter-storage.ts # Add isConcentrating to rehydration
|
||||
└── App.tsx # Wire toggleConcentration prop
|
||||
```
|
||||
|
||||
**Structure Decision**: Follows existing monorepo layout with domain/application/web layers. Each new file mirrors the established pattern (e.g., `toggle-concentration.ts` mirrors `toggle-condition.ts`).
|
||||
Reference in New Issue
Block a user