Implement the 020-fix-zero-hp-opacity feature that replaces container-level opacity dimming with element-level opacity on individual leaf elements so that HP popover and condition picker render at full opacity for unconscious combatants
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
101
specs/020-fix-zero-hp-opacity/tasks.md
Normal file
101
specs/020-fix-zero-hp-opacity/tasks.md
Normal file
@@ -0,0 +1,101 @@
|
||||
# Tasks: Fix Zero-HP Opacity
|
||||
|
||||
**Input**: Design documents from `/specs/020-fix-zero-hp-opacity/`
|
||||
**Prerequisites**: plan.md (required), spec.md (required for user stories), research.md, data-model.md, quickstart.md
|
||||
|
||||
**Tests**: No test tasks included (not explicitly requested in spec). Existing tests must continue to pass via `pnpm check`.
|
||||
|
||||
**Organization**: Tasks are grouped by user story. US1 and US2 share the same root cause fix, so they are addressed together in Phase 2 (Foundational). US3 is verified as part of the same change.
|
||||
|
||||
## Format: `[ID] [P?] [Story] Description`
|
||||
|
||||
- **[P]**: Can run in parallel (different files, no dependencies)
|
||||
- **[Story]**: Which user story this task belongs to (e.g., US1, US2, US3)
|
||||
- Include exact file paths in descriptions
|
||||
|
||||
## Phase 1: Setup
|
||||
|
||||
**Purpose**: No setup required. This is a single-file bug fix in an existing codebase with all tooling already configured.
|
||||
|
||||
(No tasks — skip to Phase 2)
|
||||
|
||||
---
|
||||
|
||||
## Phase 2: Foundational (Core Fix)
|
||||
|
||||
**Purpose**: Remove the container-level `opacity-50` that cascades to popover/dropdown children and replace it with element-level dimming that preserves the unconscious visual indicator without affecting overlays.
|
||||
|
||||
- [x] T001 Remove `opacity-50` from the outer row container `<div>` (the `status === "unconscious" && "opacity-50"` expression on line 312) in `apps/web/src/components/combatant-row.tsx`
|
||||
- [x] T002 Apply `opacity-50` to the inner grid `<div>` (line 316) when `status === "unconscious"` and restructure the JSX so that `HpAdjustPopover` (currently rendered inside `ClickableHp` within the grid) is moved to render as a sibling outside the grid container, not a child of it, in `apps/web/src/components/combatant-row.tsx`
|
||||
- [x] T003 Apply `opacity-50` to the conditions container `<div>` (line 388) when `status === "unconscious"` and restructure the JSX so that `ConditionPicker` is rendered as a sibling outside the dimmed conditions wrapper, not a child of it, in `apps/web/src/components/combatant-row.tsx`
|
||||
- [x] T004 Verify that the `HpAdjustPopover` component renders at full opacity (no inherited dimming) when opened on a 0-HP combatant, by running `pnpm --filter web dev` and manually testing
|
||||
- [x] T005 Verify that the `ConditionPicker` component renders at full opacity (no inherited dimming) when opened on a 0-HP combatant, by running `pnpm --filter web dev` and manually testing
|
||||
- [x] T005a Verify edge case transitions: (a) heal a 0-HP combatant while the HP popout is open — row should transition to normal styling, popout stays functional; (b) reduce a combatant to 0 HP while the HP popout is open — row should transition to dimmed styling, popout stays at full opacity. Manual test via `pnpm --filter web dev`.
|
||||
|
||||
**Checkpoint**: At this point, both US1 (HP popover) and US2 (condition picker) should render at full opacity for 0-HP combatants.
|
||||
|
||||
---
|
||||
|
||||
## Phase 3: User Story 3 - Row Visual Distinction (Priority: P2)
|
||||
|
||||
**Goal**: Unconscious combatants remain visually distinguishable from conscious combatants.
|
||||
|
||||
**Independent Test**: View encounter list with a mix of conscious and unconscious combatants; unconscious rows should look dimmed while their popouts are full opacity.
|
||||
|
||||
### Implementation for User Story 3
|
||||
|
||||
- [x] T006 [US3] Verify that unconscious combatant rows still appear visually dimmed (via the element-level `opacity-50` applied in T002/T003) compared to healthy combatants in `apps/web/src/components/combatant-row.tsx`
|
||||
|
||||
**Checkpoint**: All user stories verified — unconscious rows are dimmed, but popouts/dropdowns render at full opacity.
|
||||
|
||||
---
|
||||
|
||||
## Phase 4: Polish & Cross-Cutting Concerns
|
||||
|
||||
- [x] T007 Run `pnpm check` to verify all quality gates pass (knip, format, lint, typecheck, test)
|
||||
- [x] T008 Run quickstart.md validation steps to confirm end-to-end fix
|
||||
|
||||
---
|
||||
|
||||
## Dependencies & Execution Order
|
||||
|
||||
### Phase Dependencies
|
||||
|
||||
- **Phase 2 (Foundational)**: No dependencies — start immediately. T001 must complete before T002/T003. T002 and T003 can run in parallel. T004/T005 are manual verification after T002/T003.
|
||||
- **Phase 3 (US3)**: Depends on Phase 2 completion (visual distinction is a side effect of the fix approach).
|
||||
- **Phase 4 (Polish)**: Depends on Phase 2 and Phase 3 completion.
|
||||
|
||||
### User Story Dependencies
|
||||
|
||||
- **US1 (HP popover)**: Addressed by T001 + T002. No dependency on other stories.
|
||||
- **US2 (Condition picker)**: Addressed by T001 + T003. No dependency on other stories.
|
||||
- **US3 (Visual distinction)**: Verified by T006. Depends on T002/T003 being correctly implemented.
|
||||
|
||||
### Parallel Opportunities
|
||||
|
||||
- T002 and T003 can be done in parallel (different sections of the same file, but non-overlapping regions)
|
||||
- T004 and T005 can be verified in parallel
|
||||
|
||||
---
|
||||
|
||||
## Implementation Strategy
|
||||
|
||||
### MVP First (All Stories in One Pass)
|
||||
|
||||
1. Complete T001 (remove container opacity) — this is the root cause fix
|
||||
2. Complete T002 + T003 (apply element-level dimming) — preserves visual distinction
|
||||
3. Verify T004 + T005 + T006 (manual testing)
|
||||
4. Run T007 (quality gate) + T008 (quickstart validation)
|
||||
5. **Done** — single commit, single file change
|
||||
|
||||
This is a small, surgical bug fix. All three user stories are addressed by the same structural change in `combatant-row.tsx`. The entire fix can be completed in a single pass.
|
||||
|
||||
---
|
||||
|
||||
## Notes
|
||||
|
||||
- Single file change: `apps/web/src/components/combatant-row.tsx`
|
||||
- No domain or application layer changes
|
||||
- No new dependencies
|
||||
- No new files
|
||||
- The key insight: CSS `opacity` on a parent creates a stacking context that dims all children. The fix must ensure popovers are never DOM descendants of a dimmed element.
|
||||
Reference in New Issue
Block a user