Skip to content

feat(nav): left side-panel on every destination page#3472

Merged
BunsDev merged 1 commit into
mainfrom
feat-standalone-sidepanel
Jul 19, 2026
Merged

feat(nav): left side-panel on every destination page#3472
BunsDev merged 1 commit into
mainfrom
feat-standalone-sidepanel

Conversation

@BunsDev

@BunsDev BunsDev commented Jul 19, 2026

Copy link
Copy Markdown
Member

What

The left side-panel is now present on every page — especially the dashboard pages, which previously had none.

Why

Destination routes render outside the SPA workspace (which owns SidebarMinimal), so /dashboard, /dashboard/familiars/growth, /weaves, /proposals, /settings, and /daily-report/[date] had no side panel at all — landing there stranded you with only a breadcrumb. AnalyticsPageShell (the standalone icon rail with ?mode= deep links back into the SPA) already existed for exactly this purpose but was applied to only 3 of the 9 destination pages.

How

  • Wrap all remaining destination pages in AnalyticsPageShell, converting each page's root <main class="dr-page"> to a <div> (the shell's aps-main is the page's main landmark — no nested landmarks).
  • The rail's Dashboard foot link gets aria-current="page" + an accent-presence tint (12% fill / 35% border per the tint recipe) when on /dashboard.
  • New rule in route-inventory.test.ts: every destination-kind route must mount AnalyticsPageShell, so a future destination page can't ship without the side panel. Window-hosts (/quick-chat) and dev-only pages stay bare by design.

Verification

Booted the branch and screenshotted: rail present on /dashboard (with active tint on the foot link), /dashboard/familiars/growth, /weaves, and /settings; no console errors on the changed pages (compared against main's server). 790 test files pass; tsc --noEmit clean.

Closes cave-4i6u.

🤖 Generated with Claude Code

The standalone destination routes render outside the SPA workspace that owns
SidebarMinimal, so /dashboard, /dashboard/familiars/growth, /weaves,
/proposals, /settings, and /daily-report/[date] shipped with no side panel at
all — landing there stranded you with only a breadcrumb. AnalyticsPageShell
(the standalone icon rail with ?mode= deep links back into the SPA) already
existed for exactly this but was applied to only 3 of 9 destination pages.

Wrap all remaining destination pages in the shell, keeping each page's
dr-page content as a div (aps-main is the main landmark). The rail's
Dashboard foot link now carries aria-current="page" + an accent-presence
tint when you're on /dashboard. route-inventory.test.ts gains a rule:
every destination-kind route must mount AnalyticsPageShell, so future
destination pages can't ship without the side panel.

Verified in the running app: rail present on dashboard, growth, weaves,
and settings; no console errors; 790 test files pass; tsc clean.

Closes cave-4i6u.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings July 19, 2026 16:17

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR ensures all destination-kind standalone routes render with the same left icon rail as the SPA workspace by consistently wrapping them in AnalyticsPageShell, and adds a route inventory invariant to prevent future destination pages from shipping without the side panel.

Changes:

  • Wrap remaining destination pages (/dashboard, /weaves, /proposals, /settings, /daily-report/[date], etc.) in AnalyticsPageShell and remove per-page root <main> to avoid nested main landmarks.
  • Add “current page” styling + aria-current="page" behavior for the Dashboard rail foot link on /dashboard.
  • Add a route-inventory.test.ts rule asserting destination pages mount AnalyticsPageShell.

Reviewed changes

Copilot reviewed 10 out of 10 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
src/styles/analytics-page-shell.css Adds [aria-current="page"] styling for the active rail link.
src/components/analytics-page-shell.tsx Tracks pathname to set aria-current on the Dashboard link; updates shell docs to cover all destination routes.
src/app/weaves/page.tsx Wraps Weaves destination page in AnalyticsPageShell and changes root landmark from <main> to <div>.
src/app/settings/page.tsx Wraps Settings destination page in AnalyticsPageShell.
src/app/route-inventory.test.ts Adds an invariant requiring all destination routes to mount AnalyticsPageShell.
src/app/proposals/page.tsx Wraps Proposals destination page in AnalyticsPageShell and changes root landmark from <main> to <div>.
src/app/dashboard/page.tsx Wraps Dashboard destination page in AnalyticsPageShell and changes root landmark from <main> to <div>.
src/app/dashboard/familiars/growth/page.tsx Wraps Familiar Growth destination page in AnalyticsPageShell and changes root landmark from <main> to <div>.
src/app/dashboard-page.test.ts Extends dashboard page source assertions to require AnalyticsPageShell and forbid nested <main>.
src/app/daily-report/[date]/page.tsx Wraps both daily-report render branches in AnalyticsPageShell and changes root landmark from <main> to <div>.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/app/settings/page.tsx
Comment on lines +8 to +12
return (
<AnalyticsPageShell>
<SettingsShell />
</AnalyticsPageShell>
);
Comment on lines +116 to +119
assert.ok(
source.includes("AnalyticsPageShell"),
`${route} is a destination route — it must mount AnalyticsPageShell so the left side-panel is present on every page (cave-4i6u)`,
);
@BunsDev
BunsDev merged commit a981226 into main Jul 19, 2026
16 checks passed
@BunsDev
BunsDev deleted the feat-standalone-sidepanel branch July 19, 2026 16:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants