Files
initiative/specs/032-inline-confirm-buttons/plan.md

3.6 KiB

Implementation Plan: Inline Confirmation Buttons

Branch: 032-inline-confirm-buttons | Date: 2026-03-11 | Spec: spec.md Input: Feature specification from /specs/032-inline-confirm-buttons/spec.md

Summary

Replace single-click destructive actions and window.confirm() dialogs with a reusable ConfirmButton component that provides inline two-step confirmation. First click arms the button (checkmark icon, red background, scale pulse animation); second click executes the action. Auto-reverts after 5 seconds. Applied to the remove combatant (X) and clear encounter (trash) buttons. Fully keyboard-accessible.

Technical Context

Language/Version: TypeScript 5.8 (strict mode, verbatimModuleSyntax) Primary Dependencies: React 19, Tailwind CSS v4, Lucide React, class-variance-authority (cva) Storage: N/A (no persistence changes — confirm state is ephemeral) Testing: Vitest (unit tests for state logic; manual testing for animation/visual) Target Platform: Web (modern browsers) Project Type: Web application (monorepo: apps/web + packages/domain + packages/application) Performance Goals: Instant visual feedback (<16ms frame budget for animation) Constraints: No new runtime dependencies; CSS-only animation Scale/Scope: 1 new component, 3 modified files, 1 CSS animation added

Constitution Check

GATE: Must pass before Phase 0 research. Re-check after Phase 1 design.

Principle Status Notes
I. Deterministic Domain Core PASS No domain changes. Confirm state is purely UI-local.
II. Layered Architecture PASS ConfirmButton lives in adapter layer (apps/web/src/components/ui/). Confirmation logic moves from application hook to UI component where it belongs. No reverse dependencies.
III. Clarification-First PASS Spec is fully specified with zero NEEDS CLARIFICATION markers.
IV. Escalation Gates PASS All work is within spec scope.
V. MVP Baseline Language PASS Spec uses "MVP baseline does not include" for undo and configurability.
VI. No Gameplay Rules PASS No gameplay mechanics involved.

Post-Phase 1 re-check: All gates still pass. Moving window.confirm() out of use-encounter.ts into a UI component improves layer separation — confirmation is a UI concern, not an application concern.

Project Structure

Documentation (this feature)

specs/032-inline-confirm-buttons/
├── plan.md              # This file
├── research.md          # Phase 0 output
├── data-model.md        # Phase 1 output
├── quickstart.md        # Phase 1 output
└── tasks.md             # Phase 2 output (/speckit.tasks — NOT created by /speckit.plan)

Source Code (repository root)

apps/web/src/
├── components/
│   ├── ui/
│   │   ├── button.tsx              # Existing — wrapped by ConfirmButton
│   │   └── confirm-button.tsx      # NEW — reusable two-step confirm component
│   ├── combatant-row.tsx           # MODIFIED — use ConfirmButton for remove
│   └── turn-navigation.tsx         # MODIFIED — use ConfirmButton for trash
├── hooks/
│   └── use-encounter.ts            # MODIFIED — remove window.confirm()
└── index.css                       # MODIFIED — add scale pulse keyframe

Structure Decision: This feature adds one new component file to the existing ui/ directory and modifies three existing files. No new directories or structural changes needed. No contracts directory needed — this is an internal UI component with no external interfaces.