# Presentation Contrast Readability Implementation Plan
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
**Goal:** Fix the immediate `/present` readability regressions from the visual pass: dark-on-dark Scene 7 authoring loop text, dark-on-dark Scene 10 chat rail text, and generated screenshot hygiene.
**Architecture:** Treat this as a bugfix, not a redesign. Add explicit foreground colors and small DOM/test hooks where the contrast contract matters, keep the existing presentation layout, and verify with focused tests plus screenshots. Do not change scene composition, chat framework, or storyboard content.
**Tech Stack:** React, TypeScript, CSS, Vitest, Testing Library, Playwright CLI screenshot smoke.
## Global Constraints
- Do not change `/console`.
- Do not add dependencies.
- Do not rewrite chat UI in this slice.
- Do not alter storyboard scene order or branch content.
- Keep visual fixes scoped to `web/apps/console/src/presentation`.
- Explicitly set foreground colors where dark surfaces are used.
- Generated screenshot directories must not remain untracked after the slice.
---
## File Structure
- Modify `web/apps/console/src/presentation/SceneBody.tsx`
- Add stable readability data hooks to Scene 7 authoring nodes.
- Modify `web/apps/console/src/presentation/SceneBody.test.tsx`
- Pin Scene 7 authoring node readability hook.
- Modify `web/apps/console/src/presentation/OperatorChat.tsx`
- Restore or add chat theme/readability attributes.
- Modify `web/apps/console/src/presentation/OperatorChat.test.tsx`
- Pin chat surface readability attributes.
- Modify `web/apps/console/src/presentation/presentation.css`
- Set explicit authoring-loop and chat-rail foreground colors.
- Modify `.gitignore`
- Ignore generated visual smoke screenshot folder.
- Modify `docs/current_roadmap.md`
- Mark contrast/readability pass completed after implementation.
- Move this plan to `docs/historical/superpowers/plans/2026-07-08-presentation-contrast-readability.md` after implementation.
---
### Task 1: Scene 7 Authoring Loop Contrast
**Files:**
- Modify: `web/apps/console/src/presentation/SceneBody.tsx`
- Modify: `web/apps/console/src/presentation/SceneBody.test.tsx`
- Modify: `web/apps/console/src/presentation/presentation.css`
**Interfaces:**
- Consumes: existing Scene 7 authoring loop DOM:
- `aria-label="agent authoring loop"`
- `.scene-body__authoring-node`
- `data-authoring-active`
- `data-authoring-past`
- Produces:
- `data-readable-surface="dark"`
- explicit foreground colors for label/detail/number on authoring nodes.
- [ ] **Step 1: Add a failing readability-hook test**
In `web/apps/console/src/presentation/SceneBody.test.tsx`, inside the existing test `"renders Scene 7 as an agent authoring loop with beat-specific emphasis"`, add this assertion after `const loop = ...`:
```tsx
expect(loop).toHaveAttribute("data-readable-surface", "dark");
```
Also add this assertion after the active-stage assertion:
```tsx
expect(screen.getByText("Validate and diagnose").closest(".scene-body__authoring-node"))
.toHaveAttribute("data-readable-surface", "dark");
```
- [ ] **Step 2: Run failing test**
Run:
```bash
pnpm --dir web --filter @lda/console test -- src/presentation/SceneBody.test.tsx
```
Expected: FAIL because the authoring loop does not expose the readability hook yet.
- [ ] **Step 3: Add readability data hooks**
In `web/apps/console/src/presentation/SceneBody.tsx`, change:
```tsx
```
to:
```tsx
```
Change the authoring node element:
```tsx
```
to:
```tsx
```
- [ ] **Step 4: Fix authoring foreground CSS**
In `web/apps/console/src/presentation/presentation.css`, update `.scene-body__authoring-node` to set explicit text color:
```css
.scene-body__authoring-node {
position: relative;
z-index: 1;
display: grid;
align-content: start;
gap: 0.35rem;
min-height: 8.6rem;
border: 1px solid color-mix(in oklch, var(--stage-line) 72%, transparent);
border-radius: 0.75rem;
padding: 0.75rem;
background: color-mix(in oklch, var(--stage-surface) 88%, transparent);
color: var(--text-primary);
transition: opacity 180ms ease, transform 180ms ease, border-color 180ms ease, background 180ms ease;
}
```
Add:
```css
.scene-body__authoring-node strong {
color: var(--text-primary);
}
```
Replace:
```css
.scene-body__authoring-node small {
color: var(--text-muted);
font: 0.72rem/1.35 var(--font-interface);
}
```
with:
```css
.scene-body__authoring-node small {
color: color-mix(in oklch, var(--text-primary) 72%, var(--text-muted));
font: 0.72rem/1.35 var(--font-interface);
}
```
If `--text-primary` or `--text-muted` are not available in this scope during browser review, use the existing stage tokens already present in nearby CSS. Do not introduce new global tokens.
- [ ] **Step 5: Run focused test**
Run:
```bash
pnpm --dir web --filter @lda/console test -- src/presentation/SceneBody.test.tsx
```
Expected: PASS.
- [ ] **Step 6: Commit Task 1**
```bash
git add web/apps/console/src/presentation/SceneBody.tsx web/apps/console/src/presentation/SceneBody.test.tsx web/apps/console/src/presentation/presentation.css
git commit -m "fix: restore authoring loop contrast"
```
---
### Task 2: Scene 10 Chat Rail Contrast
**Files:**
- Modify: `web/apps/console/src/presentation/OperatorChat.tsx`
- Modify: `web/apps/console/src/presentation/OperatorChat.test.tsx`
- Modify: `web/apps/console/src/presentation/presentation.css`
**Interfaces:**
- Consumes:
- `compositionForState(state)` result with `chatMode` and `chatTheme`.
- Existing `.operator-chat` and `.chat-message` CSS classes.
- Produces:
- `data-chat-theme={composition.chatTheme}`
- `data-readable-surface="dark"` or `"light"` on the chat root.
- explicit chat message foreground colors.
- [ ] **Step 1: Add failing chat theme/readability test**
In `web/apps/console/src/presentation/OperatorChat.test.tsx`, add:
```tsx
it("exposes chat theme and readable surface attributes", () => {
render();
const chat = screen.getByLabelText("scripted operator chat");
expect(chat).toHaveAttribute("data-chat-theme");
expect(chat).toHaveAttribute("data-readable-surface");
});
```
- [ ] **Step 2: Run failing test**
Run:
```bash
pnpm --dir web --filter @lda/console test -- src/presentation/OperatorChat.test.tsx
```
Expected: FAIL because `OperatorChat` currently emits `data-mode` only.
- [ ] **Step 3: Restore chat attributes**
In `web/apps/console/src/presentation/OperatorChat.tsx`, replace:
```tsx