Files
mimic/tasks/todo.md
Knacky 5627d7dcfa docs(sprint 7): plan — terminal-SOC design refresh
9 binding decisions locked with user 2026-06-09 (4-question + 4-question
+ 3-question rounds). Visual direction Bloomberg / terminal SOC. Border
radius 0 except status pills and avatars. Palette kept (primary blue +
slab + canvas/paper/cloud/fog/ink), ADD success/warn semantic tokens.
Scope: 8 pages + 17 components + tokens + DESIGN.md rewrite, all in one
sprint. JetBrains Mono for data only (Inter stays for body/headers).
Light + dark both kept. Zero transitions (brutalist).

Plan validated by spec-reviewer pre-pass: APPROVED with 3 findings
addressed inline (D9 added, R2 reworded, semantic tokens promoted from
optional to locked).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-09 18:34:45 +02:00

154 lines
12 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Sprint 7 — Design Refresh: Terminal-SOC Aesthetic
> Branch : `sprint/7-design` · Worktree : `.claude/worktrees/sprint-7-design` · Base : `main` @ `e27babe`
## §0 — Binding decisions (locked with user, 2026-06-09)
1. **Visual direction**: Bloomberg / Terminal-SOC — dense, brutalist, semantic colors strong, no ornament.
2. **Border-radius**: **0 everywhere** except status pills (`rounded-pill`) and avatars (round). All buttons, cards, modals, inputs, dropdowns, tables, tags → angular.
3. **Palette**: KEEP current (`#024ad8` primary blue, `slab #111827`, `canvas/paper/cloud/fog/ink` light+dark vars). ADD semantic tokens `success-green` + `warn-amber` (confirmed scope add — needed for SOC-grade status legibility on dashboards and badges).
4. **Scope**: Refonte globale en 1 sprint (all 8 pages + 17 components + tokens + DESIGN.md).
5. **Monospace**: data-only — JetBrains Mono for IDs, dates ISO, commands, execution output, MITRE techniques, metrics. Inter stays for body/labels/headers.
6. **Mono font**: JetBrains Mono, bundled locally via `@fontsource-variable/jetbrains-mono` (consistent with existing Inter bundle).
7. **Modes**: KEEP light + dark both. Toggle stays.
8. **Animations**: **Brutalist — zero transition**. Remove all `transition-*` utilities, focus rings sharp, hover instantaneous.
9. **Display scale reduction**: locked. `display-xxl 72→40`, `display-xl 56→32`, `display-lg 44→28`, `display-md 32→24`, `display-sm 24→20`, `display-xs 20→16`. Headers stay modest in terminal aesthetic — no editorial flourish at hero scale.
## §1 — Pre-work checks (team-lead, before dispatch)
- [ ] Confirm `tasks/lessons.md` has nothing contradicting this brief
- [ ] Verify uncommitted `.claude/agents/frontend-builder.md` patch (Skill mandatory) is restored in worktree — sprint hygiene
- [ ] Send plan to **spec-reviewer** for 2-pass approval (vs SPEC.md, vs §0 binding decisions). MUST be APPROVED before any code touches `frontend/`.
- [ ] After approval: dispatch frontend-builder with this todo as brief.
## §2 — Sprint hygiene (commit #1)
- [ ] `chore(agents): frontend-builder must invoke Skill frontend-design before UI work` — lands BEFORE design work so the agent itself triggers the Skill on first call this sprint.
## §3 — Foundation: DESIGN.md + tokens (commits #2#4)
### §3.1 DESIGN.md rewrite (commit #2)
- [ ] Replace current HP-catalog doc (346 lines, off-brand) with terminal-SOC spec covering:
- **Overview**: brutalist BAS Purple Team console, angular surfaces, semantic color signals, data-monospace hybrid
- **Colors**: keep all existing tokens with **role redefinition** for terminal-SOC context. Primary = neutral action. Bloom-deep/coral = destructive/alert. ADD `success` (green) + `warn` (amber) — locked §0 D3 — with light + dark variants and WCAG AA contrast on slab and canvas surfaces
- **Typography**: Inter (body/headers/labels) + JetBrains Mono (data). Concrete tier table with size/weight/line-height
- **Layout**: tighter spacing (replace `section 80px``section 48px`; halve card padding on dense surfaces)
- **Shapes**: ALL radii = 0 except `rounded-pill` reserved for status badges and avatars
- **Components**: re-document `btn-*`, `text-input`, `card-*`, `badge-*`, `nav-*`, `modal-*` with brutalist specs (no shadow, hairline borders, zero transition)
- **Do's/Don'ts**: zero rounded on conteneurs; zero transitions; semantic colors only on status surfaces; mono ONLY for data, never headers
- **Iteration guide**
- [ ] Doc lives in English (in-repo).
### §3.2 Tailwind token refresh (commit #3)
- [ ] `frontend/tailwind.config.ts`:
- `borderRadius`: keep `none: 0`, keep `pill: 9999px`. Drop or stop using `xs/sm/md/lg/xl` for surfaces — keep only if a badge variant needs `2px`
- ADD `fontFamily.mono`: `['JetBrains Mono Variable', 'JetBrains Mono', 'ui-monospace', 'monospace']`
- ADD semantic colors (locked §0): `success: { DEFAULT, soft }` (green) + `warn: { DEFAULT, soft }` (amber). Pull dark-mode variants from CSS vars too. Suggested anchors — `success #16a34a` (dark `#22c55e`), `warn #d97706` (dark `#f59e0b`); design-reviewer audits WCAG AA at both modes.
- Reduce `display-*` scale (locked §0): `display-xxl 72px → 40px`, `display-xl 56→32`, `display-lg 44→28`, `display-md 32→24`, `display-sm 24→20`, `display-xs 20→16` — terminal headers are modest
- Drop `tracking[0.7px]` and uppercase from `button-md` (still ALLCAPS via class but no letter-spacing)
- Drop shadow tokens or keep but ensure no component class applies them
- [ ] `frontend/src/styles/index.css`:
- Drop `font-size: 16.5px` root bump (back to `16px` standard)
- Set body `line-height: 1.4`, tighten headings to 1.1
- Rewrite `.btn-primary/ink/outline/outline-ink`: `rounded-none`, NO `transition-colors`, keep `uppercase`, drop `tracking-[0.7px]`, keep `h-11` (touch target)
- Rewrite `.text-input`: `rounded-none`, focus border-primary sharp (no halo), no transition
- Rewrite `.card-product` and any `.card-*`: `rounded-none`, no shadow, 1px hairline border for separation
- Rewrite `.badge-pill-*`: keep `rounded-pill` ONLY here (status badges); strip uppercase if applied
- Rewrite `.modal-backdrop`: same dark backdrop, no rounded for the modal frame itself
- ADD `.mono` utility or rely on Tailwind's `font-mono` (preferred) for data cells
### §3.3 JetBrains Mono bundle (commit #4)
- [ ] `cd frontend && npm i @fontsource-variable/jetbrains-mono`
- [ ] `frontend/src/styles/fonts.css`: add `@import '@fontsource-variable/jetbrains-mono'`
- [ ] No CDN. Confirms via `npm ls @fontsource-variable/jetbrains-mono`.
## §4 — Component sweep (commit #5)
Rule: `rounded-*``rounded-none` unless explicitly an avatar or status pill; remove `transition-*`; data text → `font-mono`.
- [ ] `Layout.tsx`: nav-bar/utility-strip already angular — confirm. Remove `transition-colors` on theme button and hover-underline transitions. Mono font for any data label exposed (e.g. user.role pill).
- [ ] `StatusBadge.tsx`: KEEP rounded → switch to `rounded-pill` (it's a status pill, locked exception). Audit semantic mapping (planned/active/closed → semantic tokens once added).
- [ ] `SimulationStatusBadge.tsx`: same — `rounded-pill`, semantic colors aligned with new tokens.
- [ ] `FormField.tsx`: angular inputs (already via `.text-input` recipe — confirm).
- [ ] `EmptyState.tsx`: angular wrapper. No rounded illustration container.
- [ ] `ErrorState.tsx`: angular. Bloom-deep border-left if signalling.
- [ ] `LoadingState.tsx`: drop any rounded spinner background. Spinner shape ok.
- [ ] `ConfirmDialog.tsx`: angular modal. Buttons via new `.btn-*` recipes.
- [ ] `Toast.tsx`: angular. Semantic color border-left strip.
- [ ] `ExportEngagementButton.tsx` (sprint 6): angular dropdown menu. Audit `rounded-*` in the menu/item classes.
- [ ] `MitreMatrixModal.tsx`: angular modal. Cells already grid — confirm no rounded.
- [ ] `MitreTechniquePicker.tsx`: angular dropdown.
- [ ] `MitreTechniquesField.tsx`: angular chips.
- [ ] `MitreTechniqueTag.tsx`: angular tag (NOT pill — terminal tag, not a status). Decide once and apply consistently across MITRE surfaces.
- [ ] `TemplatePickerModal.tsx`: angular modal.
- [ ] `SimulationList.tsx`: angular table. Data cells (commands, executed_at, MITRE techniques) → `font-mono`.
- [ ] `ProtectedRoute.tsx`: no visual surface, skip.
## §5 — Page sweep (commit #6)
For each page: header/body/footer review, replace rounded card containers with angular hairline-bordered containers, ensure data cells use mono.
- [ ] `LoginPage.tsx`: angular form card. Drop ornament.
- [ ] `EngagementsListPage.tsx`: angular table container (currently `.card-product` with rounded-xl). Data cells (dates) → mono.
- [ ] `EngagementDetailPage.tsx`: angular header section. Engagement metadata (start/end dates, IDs, created_at) in mono. Simulations table covered via SimulationList.
- [ ] `EngagementFormPage.tsx`: angular form. Date inputs ok.
- [ ] `SimulationFormPage.tsx`: angular form. Commands textarea → mono.
- [ ] `TemplatesListPage.tsx`: angular list.
- [ ] `TemplateFormPage.tsx`: angular form. Commands field → mono.
- [ ] `UsersAdminPage.tsx`: angular table. Username column → mono (it's an ID).
## §6 — Test refresh (commit #7)
- [ ] `cd frontend && npm run test -- --run` — identify failing assertions on class names (`rounded-xl`, `card-product`, etc.). Update tests to use semantic queries (role, name, data-testid) where possible; if test asserts on visual class, update assertion to the new class.
- [ ] No new vitest tests added (visual sprint, behavior unchanged).
- [ ] Playwright e2e: should be `data-testid`-driven — run full suite to confirm no regression. If breakage, fix the testid not the test logic.
## §7 — Reviews
- [ ] **spec-reviewer** (pre-dispatch, §1): plan validated vs SPEC.md and §0 binding decisions
- [ ] **frontend-builder** (§2-§6): implements, runs typecheck/lint/test, delivers screenshots for design-reviewer (every page + key states, light+dark)
- [ ] **design-reviewer** (post-frontend): reviews screenshots + diff vs new DESIGN.md. Brutalist consistency, mono-discipline (only data), zero-rounded discipline.
- [ ] **code-reviewer** (post-design): reviews frontend diff for duplication, lost reuse, dead code.
- [ ] **test-verifier**: skipped this sprint (no new US, no behavior change).
- [ ] **backend-builder**: idle, no work this sprint.
## §8 — Git workflow
- [ ] Branch: `sprint/7-design` (already created from origin/main)
- [ ] Commits: conventional, one per logical group (§2 to §7)
- [ ] PR via `make open-pr` (Gitea pattern, per memory)
- [ ] PR body in `tasks/pr-body-sprint-7.md`
- [ ] CHANGELOG.md sprint 7 section
## §9 — Risks & mitigations
- **R1 — Tests break en masse**: many vitest specs may assert on class strings (e.g., `rounded-xl` on cards). Mitigation: update assertions to semantic queries; budget half a phase to test repair.
- **R2 — Dark mode contrast lost**: angular + new semantic colors may break WCAG AA contrast on dark slab. Mitigation: design-reviewer audits both modes; adjust the dark variant hex to meet WCAG AA. Rollback the success/warn family only if no accessible green/amber is achievable on the dark slab.
- **R3 — Mono overflow**: JetBrains Mono is wider than Inter at same px. Cell widths in tables may overflow. Mitigation: keep `table-layout: fixed` and `word-break: break-word` (pattern reused from PDF export CSS sprint 6).
- **R4 — DESIGN.md rewrite churn**: replacing 346 lines is a big diff. Mitigation: rewrite atomically in commit #2, keep token names consistent so downstream commits don't drift.
- **R5 — User taste mismatch**: "Bloomberg/SOC" may not match user's mental image. Mitigation: design-reviewer screenshots → user check-in BEFORE merge.
## §10 — Definition of Done
- [ ] All §0 decisions reflected in DESIGN.md + tokens + components + pages
- [ ] `npm run typecheck` clean
- [ ] `npm run lint` clean
- [ ] `npm run test -- --run` all green
- [ ] Backend untouched — `git diff origin/main -- backend/` empty
- [ ] Playwright e2e green (223 baseline preserved)
- [ ] Screenshots delivered (light + dark) for every page + key states
- [ ] DESIGN.md rewritten, no HP/Forma/wordmark/chevron references
- [ ] CHANGELOG.md sprint 7 section
- [ ] PR opened on Gitea
- [ ] User merges PR → sprint closed → team idle ready for sprint 8
## §11 — Lessons being applied from prior sprints
- **SPEC/DESIGN commit-first**: DESIGN.md rewrite is commit #2 (after sprint hygiene). No design churn mid-sprint.
- **spec-reviewer 2-pass**: APPROVED before dispatch, not after.
- **Team idle policy**: 6 agents already mounted, no shutdown until PR merged.
- **frontend-builder MUST invoke `Skill frontend-design`** before UI work (the patch commits as #1, takes effect immediately for the same sprint).