# Presentation Surface Theme Normalization 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:** Normalize `/present` chat and discussion/Q&A surfaces so light chat, direct discussion branches, and presenter notes share one editorial presentation vocabulary. **Architecture:** Add a small semantic surface contract with `data-presentation-surface="editorial|night"` on presentation side-surfaces. Style `OperatorChat` and `DiscussionPanel` through that contract, keeping existing storyboard, layout, chat messages, and discussion routing intact. Do not introduce a new theme engine or component library in this slice. **Tech Stack:** React, TypeScript, CSS, Vitest, Testing Library, Playwright CLI screenshot smoke. ## Global Constraints - Follow design spec: `docs/superpowers/specs/2026-07-08-presentation-surface-theme-normalization-design.md`. - Do not change `/console`. - Do not replace chat UI. - Do not alter storyboard content or scene composition. - Do not add dependencies. - Keep CSS scoped to presentation surfaces. - Prefer semantic surface attributes over ad hoc color selectors. - Generated `.visual-smoke/` screenshots must remain ignored. --- ## File Structure - Modify `web/apps/console/src/presentation/OperatorChat.tsx` - Add `data-presentation-surface`. - Modify `web/apps/console/src/presentation/OperatorChat.test.tsx` - Pin editorial/night surface mapping. - Modify `web/apps/console/src/presentation/DiscussionPanel.tsx` - Add `data-presentation-surface="editorial"`. - Modify `web/apps/console/src/presentation/DiscussionPanel.test.tsx` - Pin discussion panel surface contract for Q&A branches and legacy branches. - Modify `web/apps/console/src/presentation/presentation.css` - Normalize chat/discussion/presenter-note surfaces. - Modify `docs/current_roadmap.md` - Mark surface normalization complete after implementation. - Move this plan to `docs/historical/superpowers/plans/2026-07-08-presentation-surface-theme-normalization.md` after implementation. --- ### Task 1: Add Semantic Surface Attributes **Files:** - Modify: `web/apps/console/src/presentation/OperatorChat.tsx` - Modify: `web/apps/console/src/presentation/OperatorChat.test.tsx` - Modify: `web/apps/console/src/presentation/DiscussionPanel.tsx` - Modify: `web/apps/console/src/presentation/DiscussionPanel.test.tsx` **Interfaces:** - Consumes: - `compositionForState(state).chatTheme` - `DiscussionPanel` branch ID. - Produces: - `OperatorChat` root has `data-presentation-surface="editorial"` when `chatTheme === "light"`, otherwise `"night"`. - `DiscussionPanel` root has `data-presentation-surface="editorial"`. - [ ] **Step 1: Add failing OperatorChat surface test** In `web/apps/console/src/presentation/OperatorChat.test.tsx`, add this test: ```tsx it("maps light chat theme to the editorial presentation surface", () => { const state = { ...initialPresentationState, location: { kind: "main" as const, sceneId: "workflow-demo" as const, beatId: "graph", focusPath: [] }, }; render(); const chat = screen.getByLabelText("scripted operator chat"); expect(chat).toHaveAttribute("data-chat-theme", "light"); expect(chat).toHaveAttribute("data-presentation-surface", "editorial"); }); ``` Add a second test: ```tsx it("maps dark chat theme to the night presentation surface", () => { render(); const chat = screen.getByLabelText("scripted operator chat"); expect(chat).toHaveAttribute("data-presentation-surface", "night"); }); ``` - [ ] **Step 2: Add failing DiscussionPanel surface tests** In `web/apps/console/src/presentation/DiscussionPanel.test.tsx`, add: ```tsx it("renders Q&A branches on the editorial presentation surface", () => { render(); expect(screen.getByRole("dialog")).toHaveAttribute("data-presentation-surface", "editorial"); }); it("renders legacy discussion branches on the same editorial surface", () => { render(); expect(screen.getByRole("dialog")).toHaveAttribute("data-presentation-surface", "editorial"); }); ``` - [ ] **Step 3: Run failing tests** Run: ```bash pnpm --dir web --filter @lda/console test -- src/presentation/OperatorChat.test.tsx src/presentation/DiscussionPanel.test.tsx ``` Expected: FAIL because `data-presentation-surface` is not emitted yet. - [ ] **Step 4: Add `OperatorChat` surface attribute** In `web/apps/console/src/presentation/OperatorChat.tsx`, find: ```tsx const composition = compositionForState(state); return (