diff --git a/docs/superpowers/plans/2026-08-10-welcome-screen-polish.md b/docs/superpowers/plans/2026-08-10-welcome-screen-polish.md new file mode 100644 index 0000000..30f1286 --- /dev/null +++ b/docs/superpowers/plans/2026-08-10-welcome-screen-polish.md @@ -0,0 +1,192 @@ +# Welcome Screen Polish 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:** Add a gradient brand mark + larger title and pastel-tinted stat cards to the chat welcome screen, per the approved spec. + +**Architecture:** Two-file, class-string-only change: the welcome block in `ChatInterface.tsx` and the stats grid in `ResearchDashboard.tsx`. No logic changes. + +**Tech Stack:** Tailwind CSS 3 (`darkMode: "class"`), lucide-react icons, Vitest. + +**Spec:** `docs/superpowers/specs/2026-08-10-welcome-screen-polish-design.md` + +## Global Constraints + +- Purely visual: `npx tsc --noEmit`, `npx eslint` on the two files, `npm test` must stay green. +- `src/app/components/ChatInterface.tsx` contains unrelated uncommitted user changes — the implementer edits but does NOT stage or commit it; the controller stages only the task's hunk via filtered `git apply --cached`. `src/app/components/ResearchDashboard.tsx` is clean. +- NEVER use `git add -A` / `git add .`. Do not touch `src/app/components/ContextUsageIndicator.tsx` (untracked user WIP). +- Known pre-existing lint noise: `src/app/components/MarkdownContent.tsx` has an eslint error from user WIP — ignore it. +- All tinted classes are full static strings per stat — no dynamic Tailwind class construction (JIT must see them). +- Commit style: `style(webui): …`. + +--- + +### Task 1: Gradient brand mark + pastel stat cards + +**Files:** +- Modify: `src/app/components/ChatInterface.tsx` (~line 1744 welcome block; NOT committed by implementer) +- Modify: `src/app/components/ResearchDashboard.tsx` (stats grid; clean, committed normally) + +**Interfaces:** +- Consumes: existing tokens (`--ring` for focus rings). Produces nothing — leaf change. + +- [ ] **Step 1: Brand tile + larger title in the welcome block** + +In `src/app/components/ChatInterface.tsx`, add `Sparkles` to the existing `lucide-react` import (alphabetical position among the existing named imports; there is a multi-import from `lucide-react` near the top of the file). + +Find (lines 1744-1747): + +```tsx +
+

+ Where research evolves +

+``` + +Replace with: + +```tsx +
+
+
+

+ Where research evolves +

+``` + +- [ ] **Step 2: Per-stat tint fields in `ResearchDashboard.tsx`** + +In the `stats` array type (lines 172-179), add two fields to the inline type: + +```ts + const stats: Array<{ + value: string | number; + unit?: string; + label: string; + hint: string; + Icon: typeof Network; + cardClass: string; + tileClass: string; + target: NavTarget; + }> = [ +``` + +Add to each stat entry, respectively: + +Knowledge: +```ts + cardClass: + "border-cyan-100 bg-cyan-50 dark:border-cyan-900/50 dark:bg-cyan-950/40", + tileClass: + "bg-cyan-100 text-cyan-700 dark:bg-cyan-900/60 dark:text-cyan-300", +``` + +Timeline: +```ts + cardClass: + "border-violet-100 bg-violet-50 dark:border-violet-900/50 dark:bg-violet-950/40", + tileClass: + "bg-violet-100 text-violet-700 dark:bg-violet-900/60 dark:text-violet-300", +``` + +Workspace: +```ts + cardClass: + "border-amber-100 bg-amber-50 dark:border-amber-900/50 dark:bg-amber-950/40", + tileClass: + "bg-amber-100 text-amber-700 dark:bg-amber-900/60 dark:text-amber-300", +``` + +Scheduled: +```ts + cardClass: + "border-emerald-100 bg-emerald-50 dark:border-emerald-900/50 dark:bg-emerald-950/40", + tileClass: + "bg-emerald-100 text-emerald-700 dark:bg-emerald-900/60 dark:text-emerald-300", +``` + +- [ ] **Step 3: Card + icon-tile markup** + +In the stats map (line 215), change the destructure from: + +```ts + {stats.map(({ value, unit, label, hint, Icon, target }) => ( +``` + +to: + +```ts + {stats.map( + ({ value, unit, label, hint, Icon, cardClass, tileClass, target }) => ( +``` + +Replace the button's className (line 224): + +```ts + className="hover:border-[var(--brand)]/40 flex min-h-[82px] flex-col items-center justify-center gap-1 rounded-md border border-border bg-[var(--color-surface)] px-2 py-2.5 transition-colors hover:bg-accent/60 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring" +``` + +with (template literal, static parts first): + +```ts + className={`flex min-h-[82px] flex-col items-center justify-center gap-1 rounded-xl border px-2 py-2.5 transition-all hover:-translate-y-0.5 hover:shadow-md focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring ${cardClass}`} +``` + +Replace the icon (lines 226-229): + +```tsx +