Files
initiative/specs/017-combat-conditions/spec.md

148 lines
9.7 KiB
Markdown

# Feature Specification: Combat Conditions
**Feature Branch**: `017-combat-conditions`
**Created**: 2026-03-06
**Status**: Draft
**Input**: User description: "Add combat conditions to combatants with icon tags, compact picker, and Lucide icon mapping"
## User Scenarios & Testing *(mandatory)*
### User Story 1 - Add a Condition to a Combatant (Priority: P1)
As a DM running an encounter, I want to quickly apply a condition to a combatant so I can track status effects during combat.
**Why this priority**: Core functionality -- without the ability to add conditions, the feature has no value.
**Independent Test**: Can be fully tested by clicking the "+" button on a combatant, selecting a condition, and verifying it appears as an icon tag under the combatant's name.
**Acceptance Scenarios**:
1. **Given** a combatant with no active conditions, **When** I look at the combatant row, **Then** I see a small "+" button in the condition area below the combatant name.
5. **Given** a combatant with one or more active conditions, **When** I look at the combatant row, **Then** I see the active condition icon tags followed by a "+" button.
2. **Given** a combatant row, **When** I click the "+" button, **Then** a compact picker opens showing all 15 available conditions, each displayed as an icon with a label.
3. **Given** the condition picker is open, **When** I click a condition entry, **Then** the condition is toggled on and appears as a colored icon tag under the combatant name in the combat row.
4. **Given** the condition picker is open with some conditions already active, **When** I view the picker, **Then** active conditions are visually distinguished from inactive ones.
---
### User Story 2 - Remove a Condition from a Combatant (Priority: P1)
As a DM, I want to quickly remove a condition from a combatant when the effect ends so the tracker stays accurate.
**Why this priority**: Equally critical as adding -- conditions must be removable to reflect combat state changes.
**Independent Test**: Can be tested by clicking an active condition icon tag and verifying it is removed.
**Acceptance Scenarios**:
1. **Given** a combatant with one or more active conditions, **When** I click an active condition icon tag in the combat row, **Then** the condition is removed and the icon tag disappears.
2. **Given** a combatant with one active condition, **When** I remove that condition, **Then** only the "+" button remains in the condition area.
3. **Given** the condition picker is open, **When** I click an active condition in the picker, **Then** the condition is toggled off and removed from the combatant row.
---
### User Story 3 - View Condition Details via Tooltip (Priority: P2)
As a DM, I want to hover over a condition icon to see its name so I can quickly identify conditions without memorizing icons.
**Why this priority**: Important for usability but the feature is functional without it.
**Independent Test**: Can be tested by hovering over an active condition icon tag and verifying the tooltip displays the condition name.
**Acceptance Scenarios**:
1. **Given** a combatant with an active condition, **When** I hover over the condition icon tag, **Then** a tooltip appears showing the condition's name (e.g., "Blinded", "Poisoned").
2. **Given** I am hovering over a condition icon, **When** I move the cursor away, **Then** the tooltip disappears.
---
### User Story 4 - Multiple Conditions on One Combatant (Priority: P2)
As a DM, I want to apply multiple conditions to a single combatant so I can track complex combat situations.
**Why this priority**: Common in D&D play but the feature works with single conditions first.
**Independent Test**: Can be tested by applying multiple conditions and verifying all appear as icon tags.
**Acceptance Scenarios**:
1. **Given** a combatant with one active condition, **When** I open the picker and add another condition, **Then** both conditions appear as icon tags under the combatant name.
2. **Given** a combatant with multiple active conditions, **When** I view the combat row, **Then** all condition icons are displayed compactly without increasing the row width.
3. **Given** a combatant with many conditions (e.g., 5+), **When** I view the combat row, **Then** the row may grow slightly taller to accommodate wrapping condition icons but does not grow wider.
4. **Given** a combatant has "poisoned" applied first and "blinded" applied second, **When** I view the combat row, **Then** "blinded" appears before "poisoned" (fixed definition order, not insertion order).
---
### Edge Cases
- What happens when all 15 conditions are applied to a single combatant? The icons wrap within the row, increasing row height but not width.
- What happens when a combatant is removed from the encounter? Its conditions are removed with it (no orphaned condition data).
- What happens when the picker is open and I click outside of it? The picker closes.
- What happens when a condition is toggled on then immediately toggled off in the picker? The condition does not appear in the combat row.
## Requirements *(mandatory)*
### Functional Requirements
- **FR-001**: The MVP MUST support the following 15 standard D&D 5e conditions: blinded, charmed, deafened, exhaustion, frightened, grappled, incapacitated, invisible, paralyzed, petrified, poisoned, prone, restrained, stunned, unconscious. MVP baseline does not include additional or homebrew conditions.
- **FR-002**: Each condition MUST have a fixed icon and color mapping as follows:
| Condition | Icon | Color |
| -------------- | --------- | ------- |
| Blinded | EyeOff | neutral |
| Charmed | Heart | pink |
| Deafened | EarOff | neutral |
| Exhaustion | BatteryLow | amber |
| Frightened | Siren | orange |
| Grappled | Hand | neutral |
| Incapacitated | Ban | gray |
| Invisible | Ghost | violet |
| Paralyzed | ZapOff | yellow |
| Petrified | Gem | slate |
| Poisoned | Droplet | green |
| Prone | ArrowDown | neutral |
| Restrained | Link | neutral |
| Stunned | Sparkles | yellow |
| Unconscious | Moon | indigo |
- **FR-003**: Active conditions MUST appear as small icon tags below the combatant name in the combat row, displayed in the fixed definition order from FR-001 (blinded first, unconscious last), regardless of the order in which they were applied.
- **FR-004**: The condition area MUST always display a small "+" button, regardless of whether the combatant has active conditions. When conditions are active, the "+" button appears after the last condition icon tag.
- **FR-005**: Clicking the "+" button MUST open a compact condition picker showing all conditions as icon + label pairs.
- **FR-006**: Clicking a condition in the picker MUST toggle it on or off for that combatant.
- **FR-007**: Clicking an active condition icon tag in the combat row MUST remove that condition.
- **FR-008**: Hovering over an active condition icon tag MUST display a tooltip with the condition name.
- **FR-009**: Condition icons MUST NOT increase the width of the combat tracker; row height may increase slightly to accommodate wrapping.
- **FR-010**: Conditions MUST be persisted as part of the combatant's state (surviving page reload via existing persistence).
- **FR-011**: The condition data model MUST be extensible to support future additions (e.g., tooltips with descriptions, mechanical effects).
- **FR-012**: No emoji icons may be used; all icons MUST come from the Lucide icon library.
### Key Entities
- **Condition**: A status effect that can be applied to a combatant. Defined by a unique identifier (string literal), a display name, an associated icon, and a color category.
- **CombatantConditions**: The set of active conditions on a given combatant. Stored as part of the combatant's state. A combatant may have zero or more active conditions; each condition can appear at most once per combatant.
## Success Criteria *(mandatory)*
### Measurable Outcomes
- **SC-001**: A condition can be added to a combatant in 2 clicks or fewer (click "+", click condition).
- **SC-002**: A condition can be removed from a combatant in 1 click (click the active icon tag).
- **SC-003**: All 15 D&D 5e conditions are available and visually distinguishable by icon and color.
- **SC-004**: The combat tracker maintains its current width when conditions are displayed; only row height may increase.
- **SC-005**: Condition state survives a full page reload without data loss.
- **SC-006**: Users can identify any condition by hovering over its icon to see the name tooltip.
## Clarifications
### Session 2026-03-06
- Q: In which order should active conditions be displayed in the combat row? -> A: Fixed definition order (blinded, charmed, ..., unconscious) as listed in FR-001. Order does not depend on when a condition was applied.
- Q: Should the "+" button remain visible when conditions are already active? -> A: Yes, the "+" button is always visible alongside active condition tags, appearing after the last icon.
## Assumptions
- The 15 conditions listed are the standard D&D 5e conditions and represent the complete set for MVP. Additional conditions (e.g., homebrew) are not included but the data model should not prevent future extension.
- Color categories (neutral, pink, amber, orange, gray, violet, yellow, slate, green, indigo) map to subtle color classes already available in the project's design system.
- The existing persistence mechanism will transparently handle the new condition data as part of combatant serialization.
- The condition picker closes when a user clicks outside of it or when the user navigates away.
- Conditions have no mechanical effects in MVP (e.g., "blinded" does not auto-impose disadvantage). The spec is purely for visual tracking.