Brings in the handoff design system from `Breakpilot Platform.zip`
(`breakpilot/design_handoff_customer_portal/`) as the base for restyling
every customer-area surface.
What's in:
* **Design tokens & layout primitives** — `src/app/globals.css` is the
handoff `styles.css` in full (OKLCH paper + ink + brand-violet,
--rule-* hairlines, --sev-* severity ramp, corner-tick bracket
treatment, ledger table, 32–36px row density, dark mode via
`[data-theme="dark"]`). Tailwind v4 layered on top via PostCSS for
utility helpers; the design system itself stays in plain CSS.
* **Geist + Geist Mono** wired through `next/font/google` so the
monospaced metadata/figures everywhere render at the intended weight.
* **Shell chrome** under `src/components/portal/`:
`Brand` (Breakpilot. wordmark with the violet trailing dot),
`Lifeline` (top full-width tenant rail — active / trial / frozen /
demo variants; archived swaps in `ArchivedLockout`),
`NavRail` (232px left rail with tenant switcher + workspace/admin/
settings groups + user chip; locked routes show a lock icon and a
"Requires X" tooltip rather than vanishing),
`Topbar` (breadcrumb + ⌘K button placeholder + theme toggle),
`ThemeToggle` (Sun/Moon, persists to `localStorage["bp.theme"]`,
no-flash via a head script in the root layout).
* **Dashboard** at `/[slug]/dashboard` rebuilt per handoff §1:
page-head with Export + Run scan (the latter wrapped in the frozen
write-guard hovercard surfacing `HTTP 402 · payment required`),
5-cell bracketed KPI rail (open findings + 14-day sparkbars + 7-day
delta, critical with severity stack, controls passing with violet
ring gauge + n/240, evidence area sparkline, last-scan cadence),
12-col grid: 30-day findings flow + severity stack legend +
top-5 open findings table on the left, product posture rows +
scan-activity heatmap (5x7) + recent-activity feed on the right.
Plain USER role drops the KPI rail and the org-wide panels per spec.
* **Charts** — minimal SVG primitives in `components/portal/charts/`:
Sparkbars, Sparkline (area + line), Ring, StackBar, Heatmap +
HeatLegend. All token-driven (`var(--sev-*)`, `var(--accent)`).
* **Fixtures** — `src/lib/fixtures.ts` is a TS port of the handoff's
`data.js`. Deterministic mulberry32 generators give the same
realistic DACH/EU compliance data every reload (~5 tenants × 30+ days
activity / 4–13 findings per product / 9 months invoices / hash-
chained audit). Source of truth for the design until tenant-registry
is enriched to carry these fields end-to-end. RBAC table (`canAccess`,
`landingFor`) ported alongside.
* **Dev session bypass** — `src/lib/get-session.ts` returns a synthetic
`SessionWithExtras` from one of the 6 fixtures when
`BP_DEV_FIXTURE=<id>` is set. Lets the portal render the design
without Keycloak + tenant-registry up. Real Auth.js wiring untouched.
What's NOT in yet (next commits):
* Products / Product launch / Org / Team / Billing / Audit / SSO pages
* Workflows editor (palette + canvas + inspector + drag-wiring)
* Command palette + toast system
* MSW handlers for the tenant data shapes (today the page reads the
fixture module directly server-side; MSW is for client-side calls)
Run locally:
pnpm install
BP_DEV_FIXTURE=admin-acme pnpm dev
open http://acme.localhost:3000/acme/dashboard
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
playwright.config.ts + tests/e2e/{apex,tenant,health}.spec.ts. make e2e for local. CI e2e job opt-in via RUN_E2E repo variable. OIDC click-through deferred to when stage is up.
Refs: M5.3
Next.js 16 + Auth.js v5 skeleton: host→slug middleware, tenant-context layout, OIDC sign-in flow against breakpilot-dev realm. 100% coverage on src/lib. Bumps next to 16.2.6 to clear trivy CVEs in 15.0.3.