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.
This commit is contained in:
@@ -0,0 +1,48 @@
|
||||
# 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.
|
||||
@@ -0,0 +1,41 @@
|
||||
# Frontend Modernization Plan
|
||||
|
||||
## Design direction
|
||||
|
||||
Drop warm-paper/serif "manuscript" look — reads dated, low-contrast, single dull accent. New identity: **phase-driven color**. Novelly already models a novel's lifecycle as phases (`Brainstorming → Outlining → Drafting → Revising → Final`, see `novelPhases`, `StatusBadge` tones). Make that real data drive the whole app's mood instead of hiding in a badge — the active novel's phase sets an accent hue across nav, buttons, focus rings, charts. Writer sees at a glance "I'm in draft mode" vs "polishing." Distinctive, grounded in the product's own model, not decoration.
|
||||
|
||||
### Tokens
|
||||
|
||||
Color (base neutrals, dark-first):
|
||||
- `--ink: #14121a` / `--ink-muted: #8b859a`
|
||||
- `--surface: #1b1825` (panel/card) / `--surface-sunken: #100e17`
|
||||
- `--canvas: #0c0a12` (app background)
|
||||
- `--line: #2c2838`
|
||||
- Light mode mirrors with `--canvas:#f7f6fb`, `--surface:#ffffff`, `--ink:#14121a`
|
||||
|
||||
Phase accents (used for `--accent` + `--accent-soft`, swapped by `novel.phase`):
|
||||
- Brainstorming — `#7c5cff` violet
|
||||
- Outlining — `#2f8fe0` blue
|
||||
- Drafting — `#ff7a45` coral
|
||||
- Revising — `#14b88a` teal
|
||||
- Final — `#d9a404` gold
|
||||
|
||||
Type:
|
||||
- Display (headlines, dashboard hero, page titles): **Fraunces** — variable serif w/ real character, used large/sparingly
|
||||
- UI (nav, buttons, body chrome): **Inter**
|
||||
- Prose editing (chapter/beat text, agent transcript): keep a serif for long-form reading — **Source Serif 4** replaces Iowan/Palatino (renders consistently, not Mac-only)
|
||||
- Utility/data (counts, timestamps, mono bits): **JetBrains Mono**
|
||||
|
||||
Layout: left sidebar nav (persistent, icon+label, collapsible), agent as a right-docked slide-out panel triggered from anywhere (sidebar icon, always visible), main content full-bleed under a slim top bar (breadcrumb + phase pill + user menu — no more "← Novels" link floating left of the title).
|
||||
|
||||
Signature element: the phase-accent system itself — nav active states, primary buttons, focus rings, and the dashboard's activity graph all recolor together when phase changes. Nothing else in the app competes for boldness; everything else stays a disciplined dark neutral.
|
||||
|
||||
## Chunks (each independently buildable/committable)
|
||||
|
||||
1. **Design tokens + primitives** — rewrite `index.css` theme (colors, fonts incl. `@font-face`/Google Fonts imports, spacing), update `ui.tsx` primitives (`btn`, `card`, `input`, `StatusBadge`) to new tokens. No layout changes yet — existing pages just reskin. Fastest way to see the new palette/type everywhere at once.
|
||||
2. **App shell: sidebar nav** — replace `NovelLayout`'s header+tab-bar with left sidebar (novel switcher, section nav, phase pill), slim top bar. Fixes the back-link-left-of-title complaint structurally. Agent gets a nav icon but no panel yet (still routes to `/agent` page).
|
||||
3. **Dashboard rebuild** — make it the true home: recent activity + work history (already there) alongside prominent "start new work" actions (new chapter, new character, continue last chapter) above the fold. This is the biggest content/layout change, isolated to one page.
|
||||
4. **Global agent panel** — extract `AgentPage`'s chat UI into a slide-out panel mounted at the app shell level (outside `<Outlet>`), triggered from the sidebar on any route, passes current route/entity as context. Retire the standalone `/agent` route once panel covers it.
|
||||
5. **Polish pass** — motion (panel slide, nav active-state transitions, dashboard load-in), empty states, focus-visible/reduced-motion audit, remaining pages (Characters/Chapters/Tags/Locations/Settings) get spacing/type touch-ups to match new primitives from chunk 1.
|
||||
|
||||
Suggest reviewing after each chunk before starting the next — chunk 2 and 4 both touch navigation/shell so seeing 1–2 landed first will make it obvious if the sidebar direction is right before the agent panel builds on top of it.
|
||||
Reference in New Issue
Block a user