|
| 1 | +# Implementation Plan: CSS-Based Quiz Answer Hiding |
| 2 | + |
| 3 | +**Branch**: `010-css-answer-hiding` | **Date**: 2025-11-28 | **Spec**: [spec.md](./spec.md) |
| 4 | +**Input**: Feature specification from `/specs/010-css-answer-hiding/spec.md` |
| 5 | + |
| 6 | +## Summary |
| 7 | + |
| 8 | +Hide quiz answer/detail columns via CSS before JavaScript executes, preventing answer visibility when JS is disabled or during page load. CSS already partially implemented in `f13ldman.css`. Need to add override rules for student/instructor modes and author mode visual indicators. |
| 9 | + |
| 10 | +## Technical Context |
| 11 | + |
| 12 | +**Language/Version**: CSS3 + TypeScript 5.x (for JS integration) |
| 13 | +**Primary Dependencies**: Existing DITA template CSS (`f13ldman.css`), Lit 3.x components |
| 14 | +**Storage**: N/A (CSS-only feature) |
| 15 | +**Testing**: Vitest (unit), Playwright (E2E) |
| 16 | +**Target Platform**: Chrome/Edge 96+, Firefox 102+ (offline, file:// protocol) |
| 17 | +**Project Type**: Single project (browser extension pattern) |
| 18 | +**Performance Goals**: No layout shift on column reveal |
| 19 | +**Constraints**: Bundle size ≤40KB, works offline from file:// URLs |
| 20 | +**Scale/Scope**: Single page quiz tables |
| 21 | + |
| 22 | +## Constitution Check |
| 23 | + |
| 24 | +*GATE: Must pass before Phase 0 research. Re-check after Phase 1 design.* |
| 25 | + |
| 26 | +- [x] **Offline-First**: CSS loaded from local template file, no network required |
| 27 | +- [x] **Progressive Enhancement**: CSS hides by default, JS reveals when appropriate |
| 28 | +- [x] **Test-Driven Development**: Tests will verify CSS visibility behavior |
| 29 | +- [x] **Phase-Gated Delivery**: Single-phase implementation with test verification |
| 30 | +- [x] **Performance Constraints**: CSS-only, no bundle impact |
| 31 | +- [x] **Data Isolation**: N/A (no data storage) |
| 32 | +- [x] **Zero Configuration**: CSS in template file, no setup required |
| 33 | + |
| 34 | +## Project Structure |
| 35 | + |
| 36 | +### Documentation (this feature) |
| 37 | + |
| 38 | +```text |
| 39 | +specs/010-css-answer-hiding/ |
| 40 | +├── plan.md # This file |
| 41 | +├── research.md # Phase 0 output |
| 42 | +├── data-model.md # N/A - CSS-only feature |
| 43 | +├── quickstart.md # Phase 1 output |
| 44 | +├── contracts/ # N/A - no API contracts |
| 45 | +└── tasks.md # Phase 2 output (/speckit.tasks) |
| 46 | +``` |
| 47 | + |
| 48 | +### Source Code (repository root) |
| 49 | + |
| 50 | +```text |
| 51 | +dita/template/ |
| 52 | +├── f13ldman.css # Production CSS (hiding + overrides) |
| 53 | +└── f13ldman_author_mode.css # Author visual indicators |
| 54 | +
|
| 55 | +dita-demo/oxygen-webhelp/template/ |
| 56 | +└── f13ldman.css # Demo copy (synced from dita/template) |
| 57 | +
|
| 58 | +src/init/ |
| 59 | +└── bootstrap.ts # May need qd-quiz-instructor class |
| 60 | +
|
| 61 | +tests/ |
| 62 | +├── integration/ |
| 63 | +│ └── quiz-table.test.ts # Verify CSS visibility behavior |
| 64 | +└── e2e/ |
| 65 | + └── workflows/ |
| 66 | + ├── dita-student-flow.spec.ts |
| 67 | + └── instructor-dynamic-reveal.spec.ts |
| 68 | +``` |
| 69 | + |
| 70 | +**Structure Decision**: CSS-only changes in DITA template, minimal JS changes in bootstrap.ts if needed for instructor class. |
| 71 | + |
| 72 | +## Current State Analysis |
| 73 | + |
| 74 | +**Already Implemented** (in `dita/template/f13ldman.css` lines 584-586): |
| 75 | +```css |
| 76 | +/* hide the answer and details cells */ |
| 77 | +.qd-quiz td:nth-child(2), .qd-quiz td:nth-child(3) { |
| 78 | + visibility: hidden; /* avoids layout shift */ |
| 79 | +} |
| 80 | +``` |
| 81 | + |
| 82 | +**Missing**: |
| 83 | +1. Header cells not hidden (th elements) |
| 84 | +2. Override rules for student interactive mode |
| 85 | +3. Override rules for instructor mode |
| 86 | +4. Author mode visual indicators in `f13ldman_author_mode.css` |
| 87 | +5. Sync to `dita-demo/oxygen-webhelp/template/f13ldman.css` |
| 88 | + |
| 89 | +## Implementation Approach |
| 90 | + |
| 91 | +### CSS Rules to Add |
| 92 | + |
| 93 | +**1. Complete Base Hiding** (update existing in `f13ldman.css`): |
| 94 | +```css |
| 95 | +/* Hide answer and detail columns in quiz tables */ |
| 96 | +.qd-quiz td:nth-child(2), .qd-quiz td:nth-child(3), |
| 97 | +.qd-quiz th:nth-child(2), .qd-quiz th:nth-child(3) { |
| 98 | + visibility: hidden; |
| 99 | +} |
| 100 | +``` |
| 101 | + |
| 102 | +**2. Student Interactive Mode Override** (add to `f13ldman.css`): |
| 103 | +```css |
| 104 | +/* Student mode: reveal answer column for input controls */ |
| 105 | +.qd-quiz-interactive td:nth-child(2), |
| 106 | +.qd-quiz-interactive th:nth-child(2) { |
| 107 | + visibility: visible; |
| 108 | +} |
| 109 | +``` |
| 110 | + |
| 111 | +**3. Instructor Mode Override** (add to `f13ldman.css`): |
| 112 | +```css |
| 113 | +/* Instructor mode: reveal both answer and detail columns */ |
| 114 | +.qd-quiz-instructor td:nth-child(2), .qd-quiz-instructor td:nth-child(3), |
| 115 | +.qd-quiz-instructor th:nth-child(2), .qd-quiz-instructor th:nth-child(3) { |
| 116 | + visibility: visible; |
| 117 | +} |
| 118 | +``` |
| 119 | + |
| 120 | +**4. Author Mode Indicators** (add to `f13ldman_author_mode.css`): |
| 121 | +```css |
| 122 | +/* Visual indicators for hidden quiz cells (answer column) */ |
| 123 | +[outputclass~='qd-quiz'] entry:nth-child(2) { |
| 124 | + background-color: rgba(255, 200, 200, 0.5); /* Light red - hidden in prod */ |
| 125 | +} |
| 126 | + |
| 127 | +/* Visual indicators for hidden quiz cells (detail column) */ |
| 128 | +[outputclass~='qd-quiz'] entry:nth-child(3) { |
| 129 | + background-color: rgba(255, 200, 200, 0.5); /* Light red - hidden in prod */ |
| 130 | +} |
| 131 | + |
| 132 | +/* Visual indicators for interactive analysis cells */ |
| 133 | +[outputclass~='interactive'] { |
| 134 | + background-color: rgba(200, 255, 200, 0.5); /* Light green - interactive */ |
| 135 | +} |
| 136 | +``` |
| 137 | + |
| 138 | +### JavaScript Changes |
| 139 | + |
| 140 | +**bootstrap.ts** - Add `qd-quiz-instructor` class when instructor logs in: |
| 141 | + |
| 142 | +Check if `revealQuizAnswersForInstructor()` function already adds this class. If not, add: |
| 143 | +```typescript |
| 144 | +quizTables.forEach((table) => { |
| 145 | + table.classList.add('qd-quiz-instructor'); |
| 146 | + // ... existing code |
| 147 | +}); |
| 148 | +``` |
| 149 | + |
| 150 | +### Test Verification |
| 151 | + |
| 152 | +1. Run existing tests - should pass with CSS overrides |
| 153 | +2. Verify student inputs visible after login |
| 154 | +3. Verify instructor sees all columns |
| 155 | +4. Visual check in demo for no layout shift |
| 156 | + |
| 157 | +## Complexity Tracking |
| 158 | + |
| 159 | +No constitution violations. Simple CSS-only feature with minimal JS integration. |
| 160 | + |
| 161 | +## Files to Modify |
| 162 | + |
| 163 | +| File | Change | |
| 164 | +|------|--------| |
| 165 | +| `dita/template/f13ldman.css` | Add th hiding, student/instructor overrides | |
| 166 | +| `dita/template/f13ldman_author_mode.css` | Add author visual indicators | |
| 167 | +| `dita-demo/oxygen-webhelp/template/f13ldman.css` | Sync from dita/template | |
| 168 | +| `src/init/bootstrap.ts` | Add `qd-quiz-instructor` class (if needed) | |
| 169 | + |
| 170 | +## Risk Assessment |
| 171 | + |
| 172 | +- **Low**: CSS changes are additive, existing JS hiding continues to work |
| 173 | +- **Low**: `visibility: hidden` preserves layout, no shift concerns |
| 174 | +- **Low**: Tests check class presence, CSS is transparent to them |
0 commit comments