Files
novelly/docs/plans/web/frontend-modernization_output.md
James Wampler 1423977ed4 Modernize web client: dark phase-driven theme, sidebar shell, global agent panel
Replaces the warm-paper/serif look with a dark palette where the novel's
lifecycle phase drives the accent color app-wide. Sidebar nav replaces the
old header/tab-bar. Dashboard leads with quick actions (new chapter, new
character, continue writing) instead of just showing history. Agent chat
is now a context-aware slide-out panel reachable from any page in a novel,
replacing the buried /agent tab.
2026-08-20 14:21:44 -07:00

49 lines
4.9 KiB
Markdown

# Frontend Modernization — Output
Implemented per `docs/plans/web/frontend-modernization_plan.md`, all 5 chunks.
## Chunk 1 — Design tokens + primitives
- `src/index.css`: full token rewrite. Dark-first palette (`--canvas`, `--surface`, `--surface-sunken`, `--ink`, `--ink-muted`, `--line`), violet `--accent` default, light-mode override via `prefers-color-scheme` + `data-theme`.
- Five-stage color ramp `--stage-1..5` (violet → blue → coral → teal → gold), shared by `NovelPhase` and `DraftStatus` via `src/api/stage.ts` (`novelPhaseColor`, `draftStatusColor`) — both are 5-step progressions, one hue system backs both.
- Fonts self-hosted via `@fontsource-variable/*` (no CDN dep): Fraunces (display), Inter (UI), Source Serif 4 (prose/markdown), JetBrains Mono (utility). Imported in `src/main.tsx`.
- `src/components/ui.tsx` primitives (`.card`, `.btn`, `.input`, `StatusBadge`, etc.) rebuilt on the new tokens.
## Chunk 2 — Sidebar shell
- `src/pages/NovelLayout.tsx` rebuilt: left sidebar (wordmark, novel title, phase pill, icon nav) replaces the old header + horizontal tab bar. Kills the old back-link-next-to-title layout — top bar is now just a breadcrumb.
- New `src/components/icons.tsx` — small hand-written inline SVG icon set (no icon library dependency).
- **Signature element**: novel's `phase` sets `--accent`/`--accent-soft` for the whole layout, scoped via inline style on the layout root. Nav active state, buttons, focus rings, phase pill all recolor together when phase changes.
- Bug fixed during build: breadcrumb section-matching used a suffix `startsWith` check that broke on exact segment matches (`chapters` vs `chapters/`) — replaced with explicit segment split/compare.
## Chunk 3 — Dashboard rebuild
- `src/pages/DashboardPage.tsx`: quick-actions row now leads the page — **New chapter** (creates + jumps into the editor), **New character** (reuses the add-character modal, now exported from `CharactersPage.tsx`), and **Continue writing** (jumps to the most-recently-updated chapter, or **View chapters** if nothing's drafted).
- Brainstorming phase gets its own pair above the notes field: **Add a character** / **Move to outlining**.
- Renamed `OutliningDashboard``WorkDashboard` (it covers Outlining/Writing/Editing/Complete, not just Outlining — old name was misleading).
- History content (activity graph, recent chapters/characters, tag cloud) unchanged, just repositioned under the new hero row.
## Chunk 4 — Global agent panel
- `/agent` route and `pages/AgentPage.tsx` retired.
- New `src/components/AgentPanel.tsx`: fixed slide-out drawer mounted in `NovelLayout` (shell level), reachable from every page in a novel via the sidebar "Agent" toggle or `g a`. Non-modal — background stays interactive.
- **Context-aware**: panel shows "Talking about {X}" — resolves to the specific chapter/character title on detail pages, falls back to section name elsewhere. Each outgoing message gets a `Context: {label}` line prepended (server has no route awareness, so this is how the agent learns what page you're on); stripped back out and shown as a small "re: …" tag on render rather than raw text in the transcript.
- Compacted the old two-pane (sidebar list + chat) layout into a single column with a conversation-switcher dropdown — panel width doesn't fit a full list rail.
- No backend changes — works within the existing `SendAgentMessageRequest` shape.
## Chunk 5 — Polish
- Global `:focus-visible` ring via `box-shadow` (not `outline`, to avoid clobbering `TagColorPicker`'s outline-based selection indicator or `.input`'s own focus ring). Ring color follows the phase accent.
- Global `prefers-reduced-motion: reduce` override (`!important` on `animation-duration`/`transition-duration`/`scroll-behavior`) — neutralizes the agent panel's slide transition too, since author `!important` beats a normal-priority inline style in the cascade.
- Fixed two leftover hardcoded `#9a4a2f` (old terracotta accent) defaults in `TagColorPicker.tsx` and `TagsPage.tsx` → new violet `#7c5cff`.
- Audited remaining pages (Settings, Locations, Tags, Characters, Chapters) — all inherit cleanly from the chunk-1 primitives already, no stale styling found.
## Verification
Every chunk built clean (`npm run build`) and was clicked through live in Chrome against a local API + SQLite instance — login/signup, novel creation, phase switching (confirmed accent recolor live: violet → blue → coral), chapter/character creation flows, agent panel open/close/context-swap across navigation, keyboard focus ring.
## Deferred / not done
- Sidebar collapse toggle — mentioned in the original plan's layout description ("persistent, icon+label, collapsible") but never implemented; flagged as deferred in chunk 2 and again in chunk 5. Would need its own pass (collapsed-width icon rail, persisted preference).
- No backend/API changes anywhere in this arc — all five chunks were frontend-only.