A daily log of what's changed across the Quorum project. Entries are reverse-chronological (newest first). Each day's entry covers: planning artifacts updated, structural / system changes, sessions completed, decisions made.
This is distinct from version-control.md, which is the strategy doc for how Quorum (the product) versions user artifacts at runtime. This file is the audit trail of how the project itself evolves.
Inline waitlist CTA, overnight-PR verification sweep, planning-page refresh (app + planning)
TextField slides in (ease-in-out, 300ms); on submit a success toast slides down from the top of the screen and the CTA slot becomes a small green check reading "You've been added." The toast is portaled to <body> with styles in globals.css, so it works on the public landing (which has no ToastProvider) as well as the app top nav and demo modal. Verified end-to-end with Playwright; typecheck, lint, and 169 unit tests pass.auto/*, story/*, and chore/* draft PRs (typecheck + lint + unit tests per branch) to sort them into ready / needs-fix / hold ahead of a merge pass.sprint-status.yaml, and the case study rewritten around the autonomous build story.Sixteen-PR overnight batch merged + second 24-routine batch opened (app)
The first overnight pipeline landed: sixteen remote routines each opened a draft PR, all verified locally and merged to main (each merge auto-deploys to production).
auto/* draft PRs (#31–#55) for polish, a11y, motion, toasts, error boundaries, CI, security headers, SEO, favicons/PWA, and more.Ship-spree: waitlist capture, public pricing, launchpad tour, demo hardening + Epic 1 retrospective (app + planning)
/pricing page (full plan grid + monthly/annual toggle) and footer.App build day two: tenant isolation, member flows, Customize tone, top-nav + Epic 2 specs (app + planning)
/community page + a richer launchpad community tile (roomier Builder spotlight).App shell + Home + Epic 12 surfaces (app)
Planning mobile nav + design-system rail polish (planning)
ds-sidenav top offset to 32px; a marker chip + hover state + collapsed-icon centering.Onboarding flow + composer v2 across every step + planning nav refactor + case study hero + pricing bump (planning + app)
Three-and-a-half-hour late-night push immediately following the 2026-05-18 build. Layered on top of the morning's quorum-app merge.
Onboarding (new):
- 4-step flow at /onboarding/{1-workspace, 2-idea, 3-team, 4-kickoff} in the dark .q-frame style with shared OnboardingShell component (DigitalWorldBackground, brand bar, progress dots, glass card).
- Step 2 (idea) adds file-upload zone (PNG/MD/PDF) + platform-target picker (Web / iOS / Android / macOS / Windows / TV).
- Kickoff page is a server-side router — auto-redirects to /w/<id> so the user never sees an interstitial.
- /demo?go={signup|signin|onboarding} route handler: signs out for sign-in/sign-up demos (shows unauthenticated landing), auto-signs-in as DEMO_USER_EMAIL for onboarding so the prototype walkthrough never dead-ends at sign-in.
Composer v2 (every step page):
- Stacked layout: target chip on top-left, Override link + outline-pill Lock CTA on top-right, input row with + attach / @ mention / send icon below. Single darker input.
- Dynamic step loader rewrites bundle-HTML composer markup on the fly; regex tolerates both <a class href> orderings + q-composer modifier classes + Override buttons with inline SVG. Covers 23/24 step files (legacy team-room excluded).
Three-pillar Desirability redesigned:
- Replaces the conversation-view with a curation-view per James's spec.
- 6 mock findings, each a card with agent attribution + kind chip (Insight/Risk/Assumption/Direction) + state pill (Included/Flagged/Open) + title + Source row + Impact row + Include ✓ / Flag ◆ / Remove × buttons.
- Stage card now shows counts: total / included / flagged / open. Feasibility + Viability ready to mirror the same pattern.
Case study hero (planning):
- Injected above case-study.md body by new build_case_study_hero().
- Stat strip (21 agents · N stories · N designed-or-shipped · N in production · 9 weeks mock).
- Status donut chart (real bucket counts from sprint-status, including new "mocked" bucket).
- 19-step pipeline ribbon with color per status.
- Image grid using real Step 1 LIVE screenshots (dark + light) from design-briefs/snapshots/; Step 3 + planning-index slots placeholder.
Planning nav refactored:
- Top nav now a pill-shaped liquid-glass container (backdrop-filter: blur(18px) saturate(1.35), border-radius 999px). No per-link borders, no header divider, no hero divider.
- TOP_NAV_LIMIT bumped 4 → 5 so all 5 default-visible items (Planning / Team / Case study / Design system / Prototype) fit in the pill.
- Planning's Prototype link goes to a hub page (exports/prototype/index.html) with 3 cards: marketing landing (/sign-up), sign-in (/sign-in), demo (/onboarding/1-workspace). Original Quroum bundle overview preserved at prototype/_quroum-overview.html.
Sign-up page (marketing landing):
- Price bump (final): Solo Pro $19 → $30/mo ($28/mo annual = $336/yr), Team Starter $39 → $50/mo ($46/mo annual = $552/yr per user), Team Business $79 → $100/mo ($92/mo annual = $1,104/yr per user). Solo Free stays $0. Round-number monthly across the board; annual savings dialed to ~1 month (was ~2) per James's call.
- Monthly/annual toggle (PlansSection client component) restyled to match Quorum's design-system language — liquid-glass pill container (same as planning nav), Source Code Pro UPPERCASE labels, cyan-soft active state with inset border + outer glow, ~1 mo free badge in green-soft. Annual shows total/yr, monthly shows "Save with annual · from $X/mo" hint.
- Team pricing flagged for review tomorrow — Solo Pro $30 vs Team Starter $50/user crossover math doesn't make sense for 2-3 person teams; feature density per tier needs re-evaluation.
- App Store + Google Play badges in hero (12px gap, 4-color Google Play Symbol).
- FAQ entry added: "Do you help with the setup work too — domains, hosting, databases?" plus existing export FAQ updated to mention the planning-site export.
- Hero top padding reduced ~40px (40→0 narrow, 72→16 wide) to shift content above the fold.
Cross-link nav:
- Every Quorum logo in the app (sign-in / sign-up / onboarding / /w/[id] / step pages) links to http://localhost:4567/ (planning home). Sign-in logo swapped from inline 3-dot SVG to the real branded /brand/quorum-plus-dark.svg.
Change-log presentation: - Month-level accordions (May open by default, April collapsed) wrapping day-level accordions (each day shows date + first-bold recap as summary; expand to read full entry).
Other:
- Step-2c context tiles: q-ctx-foot { margin-top: auto } so "Open" links align vertically across all three cards.
- Step-2b: redundant iterate-on-concept panel removed.
- Step-5a journey: "Add stop" → "Add moment".
- Initial concept visuals mockups switched to dark mode (oklch 10–14% backgrounds, light text, dark inner rows).
- Sprint-status: 22 backlog stories promoted to "mocked" status (designed in prototype, not implemented). Epic-status card adds a Mocked bucket with purple-blue swatch.
- /w/<id> workspace page allows anonymous viewing (demo robustness — auth gate stays on mutations, not the presentational shell).
Design briefs library + token preamble + live snapshot pipeline + sign-up hero rebuild (planning + quorum-app)
Codified the Claude Design workflow as a versioned artifact set. Driven by the realization that every Claude Design session was starting from a blank brain — visual decisions made in one session weren't carrying to the next, the original handoff bundle's team-room had drifted from what we shipped, and revisions lived only in chat scrollback.
New folder _bmad-output/planning-artifacts/design-briefs/ with seven files:
README.md — the workflow (Kinsley writes brief → James pastes preamble + reference + brief into Claude Design → bundle returns → dev session implements)._token-preamble.md — the locked visual system in 14 sections (palette, type, spacing, floating-panels grammar, methodology rail, agent roster, streaming patterns, composer, a11y floor, forbidden moves). Paste at the top of every Claude Design session._queue.md — every remaining V1 screen prioritized A→D for interview-week impact. Step routes (8 unbuilt pipeline steps), settings + admin (6 surfaces), error states, component-documentation framework, all enumerated with status.step-1-describe-shipped-reference.md — the shipped Step 1 documented as a reference brief (~350 lines). Captures every iteration since the original bundle (full-bleed frame, theme switcher, Quorum+ wordmark, sign-out footer, AI assist, transparency tweaks, layout adjustments). Intended to be pasted alongside the preamble at the start of any new Claude Design session so generated screens match what's live, not what the bundle had.step-2a-concept-alignment.md (150 lines), step-2b-generated-concepts.md (161), step-2c-organize-the-vision.md (184 — references the canonical "what is garbage" screen spec), step-3-three-pillar-analysis-desirability.md (245 — the portfolio-piece centerpiece). Each carries layout, exact copy strings, active roster, accept/reject criteria, ADA callouts.Live snapshot pipeline (quorum-app/scripts/snapshot-team-room.mjs): captures /w/<id> as a self-contained 105KB HTML file with all stylesheets inlined + dark + light PNG references at 2× DPR. Output lands in design-briefs/snapshots/. Re-run after meaningful changes to the team room before each Claude Design session. Sign-in via the seeded e2e test user. ~30s per run.
Sign-up hero rebuild (quorum-app): replaced the schematic laptop + phone mockups on /sign-up with two tablets framing real screenshots of the live team-room — Step 1 (Describe your idea) in the back tablet, Step 3 (Three-pillar analysis from the bundle's team-room.html) in the front. Tablets are larger (76-78% width), rotated -4°/+4.5°, with three floating feature tooltips between them (Methodology rail / Named AI team / Live artifacts) connected by glowing line projections. Layout switched from float: right + shape-outside to a flex split — fixes the regression where the back tablet covered "studio" in the title at narrow widths; at <1080px the panel becomes column-stacked with tablets below bullets and above "Choose your plan."
Screenshot capture pipeline (quorum-app/scripts/capture-tablets.mjs): Playwright signs in, navigates to /w/<id> and /_demo/step-3.html (the bundle's team-room HTML served statically for capture), grabs both at 1600×1000 @ 2× DPR. Output to public/hero/.
Decisions logged this session:
- Repo merge: quorum-app/ → quorum/app/. Reversed earlier "don't merge this week" decision after confirming Vercel was never set up for quorum-app (the assumed deploy-config blocker didn't exist). Subtree-merged quorum-app into quorum/app/ preserving full history via git subtree add --prefix=app. Updated cross-repo paths in scripts (SIBLING_APP_ROOT now points to quorum/app/, design-system snapshot looks at quorum/app/scripts/). Copied gitignored content (.env files, SESSION-RESUME-.md, reference docs/, .claude/settings.local.json) from backup since subtree only brings tracked files. npm install + prisma generate rerun in new location; dev server boots clean from quorum/app/. Backup at ~/Desktop/_backups/quorum-app-pre-merge-2026-05-18/ (2.6 GB). Rollback tag pre-merge-quorum-app-2026-05-18. GitHub repo jcfrank8910/quorum-app will be archived (not deleted) after a few days of stable operation. CLAUDE.md rewritten to reflect single-repo layout.
- Design system documentation lives in _bmad-output/planning-artifacts/, not app/.* Component specs (guidelines, code snippets, ADA notes) belong in the planning side; the live /design-system route in app/ reads them at build time when we wire that up. Implementation deferred behind the screen-design queue.
Commits (quorum-app):
- 7ab5c41 Sign-up hero: real team-room screenshots in two tablets + feature tooltips
Quorum-app pushed to origin/main (Tier 3 "ship it" at end-of-session). Quorum (planning repo) files written but uncommitted — needs a quorum-side session to fold into a commit per the cross-repo session-hygiene rule.
Team room shell + light/dark theme system shipped (quorum-app)
Driven by James's senior product designer interview this week. Pivoted from Story 1.5 (RBAC enforcement, backend-correct but invisible to a designer interviewer) to a design-led demo build of the team-room shell at /w/<id>.
Two Claude Design handoffs:
- First bundle (xAnHFv_LgRZDsnM53ci0Lw) — initial team-room at Step 3 / Desirability. Heavy transcript-driven layout. James reviewed and called it "not futuristic enough" and "too text heavy." First implementation went in (4 commits) but immediately replaced.
- Second bundle (sQiIDOtXbWLPnb2dTXiCFw) — full 9-step pipeline (step 1 through step 5 + team-room as step 3). Cleaner floating-panels system. Stage card + agent message + 4-card probe grid + composer pattern. Implemented step-1-describe as the new /w/<id>, replacing the "Team room lands in Story 2.1" placeholder.
Floating-panels grammar shipped: top bar (48px, 16px from edges), step-info bar (full-width, right-aligned roster), left nav (252px, flex-column with sign-out footer), center stage (composer at bottom), right rail (380px, stacked fcards). Backdrop reuses DigitalWorldBackground from /sign-in for visual continuity — the wireframe sphere + plexus appears on both auth and team-room surfaces.
Theme system end-to-end:
- Dark = default. Starship-at-night aesthetic. Saturated glass over digital planet. Cyan glow accents.
- Light = morning-studio. Crisp white glass over soft sophisticated aurora. Digital-planet canvas hidden (it was the dark-mode signature, reads as muddy noise on light). Comprehensive :root[data-theme="light"] override section in CSS touching ~30 classes (the dark-mode rules use literal color values not tokens, so a token swap alone doesn't work — Kinsley diagnosed this and rebuilt as a real design pass instead of a CSS variable inversion).
- ThemeSwitcher client component, persists to localStorage under key q-theme, toggles [data-theme="light"] on documentElement.
- Wordmark variant: quorum-plus-light.svg created with dark text + teal "+" preserved (the original SVG had filter: invert + hue-rotate which broke the teal color — replaced with a proper light SVG file).
Components landed: ThemeSwitcher.tsx, IdeaStageCard.tsx (client component owning textarea state so the AI-assist button is disabled-until-typing). Sign-out icon at the bottom of the left nav via the existing signOutAction server action.
Commits (quorum-app):
- e473a4c Tooling + small fixes: design-system snapshot, sign-in Suspense, supabase ping (cleanup of dangling 04-29/05-03 edits)
- aa2b051 Story 1.5 scaffold (spec only, no code — RBAC enforcement deferred behind the interview)
- 7205c09 Team room shell (Story 2.1 partial) — interview-week demo build
- 86e96f0 Team room polish: nav sign-out, AI assist wired, IdeaStageCard live
Pushed to origin/main (Tier 3 wrap fired by James saying "ship it" after Kinsley's light-mode rebuild landed).
Side-effects: Supabase project went into paused state mid-session (free-tier hibernation after 19 days inactive); James restored it from the dashboard while we debugged a getaddrinfo ENOTFOUND error on sign-up.
Kinsley sanctum (sibling repo): session log written at _bmad/memory/bmad-agent-ux-designer/sessions/2026-05-17.md capturing the light-mode architectural diagnosis (dark rules use literals not tokens, so overrides have to target classes not variables). MEMORY.md updated with the team-room shell + theme architecture. PERSONA.md evolution log records the first time crossing the "no production code" boundary (James asked explicitly with interview-week stakes).
Live design-system snapshot pipeline — built, then reverted (planning + quorum-app)
Prototyped a daily-refresh pipeline that would render quorum-app's /design-system route via Playwright and embed it inside Quorum's standard export wrapper. Two iterations, then removed.
quorum-app/scripts/snapshot-design-system.mjs booted a next dev server on port 3091, navigated Playwright to /design-system, inlined every external stylesheet plus all url() font/image references as base64 data URIs, stripped scripts, and wrote a self-contained ~415KB exports/design-system/index.html. Captured four interactive-state screenshots (full-page, modal-open, select-open, toast-success) into exports/design-system/screenshots/. Hooked into _gen_all_exports.py via a thin Python wrapper (_gen_design_system_snapshot.py) so daily export refreshes regenerated it automatically. Worked end-to-end (~30-45s added to the export run)..ds-container outerHTML, walk the CSSOM and scope-prefix every rule with .ds-embed (mapping :root/html/body to .ds-embed, dropping bare *, prefixing the rest), inline assets as data URIs, and write a JSON payload ({ contentHtml, cssText, capturedAt, source }) to _tmp/design-system-snapshot.json. Added a _render_design_system_from_snapshot helper in _gen_bmad_exports.py that consumed the JSON and built the page as Quorum hero + Source-of-truth callout + scoped <style> block + <div class="ds-embed app-scene ds-scene">{contentHtml}</div>, all wrapped via wrap_page so the page got Quorum's chrome. Reordered _gen_all_exports.py so the snapshot ran before _gen_bmad_exports.py. Worked: ~520KB self-contained page with Quorum nav around the embedded design-system content.<script> tag by design — necessary because a static HTML export can't host the React runtime — which means modal triggers, slide-swap, the custom Select listbox, the Toast firing buttons, and the Pill counter all appear non-functional in the snapshot. Playwright captures the open-state screenshots before the strip, so the visuals look right, but interactive triggers in the embedded HTML are dead. That's a structural ceiling, not a fixable bug. (2) Sticks with the deferred-deep-docs posture from project_design_system_deferred.md — Quorum's design-system page stays as a minimal live-read scaffold (parsing globals.css :root, listing src/components/ui/*.tsx, extracting fonts from layout.tsx) until quorum-app's design system stabilizes post-Story 2.x._gen_design_system_snapshot.py, _tmp/design-system-snapshot.json, exports/design-system/screenshots/. _gen_bmad_exports.py and _gen_all_exports.py reverted to their pre-experiment state via git checkout HEAD --. exports/design-system/index.html regenerated from the live-read fallback.scripts/snapshot-design-system.mjs, the empty scripts/ directory. package.json snapshot:design-system script entry removed.Pill default label fix (quorum-app)
src/app/design-system/page.tsx:527-529 — pill counter button was rendering Click me (0) on first paint, which read like preset state rather than an affordance. Changed the label expression from Click me ({count}) to Click me{count > 0 ? (${count}): ""} so the default reads Click me, with the counter appearing only after the first click. No state or behavior change. File-write only on the quorum-app side this session; will commit from a quorum-app session.Design-system showcase v3 — fully interactive iframe (planning + quorum-app)
After the two-iteration revert above, returned to the problem with a different approach: instead of stripping the React runtime, ship it.
quorum-app/scripts/snapshot-design-system.mjs (~270 lines) runs next build && next start (production bundles, not dev) on port 3091, navigates Playwright to /design-system, captures every same-origin response into quorum/_bmad-output/planning-artifacts/exports/design-system-app/<path> mirroring the URL structure, exercises the interactive states (modal, select, toast, slide-swap) so any code-split chunks load and get captured, then writes the rendered HTML to index.html in the same folder..html, .js, and .css file and replaces /_next/ absolute paths with relative _next/ references. CSS files in _next/static/css/ get their url(/_next/static/media/...) calls rewritten to url(../media/...) to resolve correctly relative to the CSS file's location. Result: the static bundle works under any URL prefix — local dev under localhost:8000/exports/design-system-app/, deployed at quorum.jayfrank.info/design-system-app/, or even file://._render_design_system_iframe in _gen_bmad_exports.py builds the design-system page as Quorum's standard hero + Source-of-truth callout + an iframe pointing at ../design-system-app/index.html. Iframe gets a fixed viewport height (min(900px, calc(100vh - 220px)), min 600px) so its position: fixed modals and toasts position correctly to the iframe's viewport instead of the auto-grown content height. Same-origin so postMessage works freely.localhost:3000/design-system now works at localhost:8000/exports/design-system/index.html — and will work at quorum.jayfrank.info/exports/design-system/index.html after deploy. Bundle: 13 files, ~680KB on disk; ~300-500KB over the wire after Cloudflare brotli.python3 _gen_all_exports.py rebuilds the bundle automatically on Tier 1+ wraps. Adds ~60-90s to the export run for the production next build.Suspense fix on /sign-in — surfaced by the production build (quorum-app)
The production next build from the snapshot pipeline above caught a real prerender bug that dev mode tolerates: useSearchParams() in SignInForm requires a Suspense boundary in app router for static prerender. Wrapped <SignInForm /> in <Suspense fallback={null}> at src/app/sign-in/page.tsx. Bonus catch — would have broken the production deploy whenever quorum-app gets to that step. Easier to find now than later.
PRD § The Three-Pillar Framework — new section, ~210 lines (planning)
The existing ## Three-Pillar Checkpoint Gates section covered gate mechanics (pass / fail / needs revisit). What was missing: the framework itself defined as Quorum's core practice — what each pillar means as a discipline, the agents who own each, the methods that run under each, the artifacts that come out the other side.
Added a new ## The Three-Pillar Framework section before the existing gates section. Structure:
The existing gate-mechanics section stays unchanged; the philosophy → mechanics flow now reads top-down through the document.
Team page — new export at /team/, 22 agents organized by pillar (planning)
New Team entry added to primary nav (default on, between Planning and Case study). New render_team_index() produces exports/team/index.html with two-level disclosure:
Visual choices that landed:
Total roster on the page: 22 agents. Each appears once in their primary pillar. Secondary contributions surfaced via chips, not duplicated cards.
Luca's First Breath + motion spec implementation (planning + quorum-app)
Brought Luca (motion designer) online for the first time on this project. First Breath protocol detected an immediate need (motion spec for the team-page disclosures), deferred discovery questions, served the spec.
_bmad/memory/bmad-agent-motion-designer/ with PERSONA, BOND, CREED, MEMORY, INDEX, and sessions/2026-04-29.md.~/.claude/agent-preferences.yaml set with agents.luca.name: Luca. Future projects pick this up automatically._style.py :root: --motion-duration-quick (160ms), --motion-duration-medium (220ms), --motion-duration-deliberate (320ms), --motion-ease-decel (cubic-bezier(0.2, 0.8, 0.2, 1)), --motion-ease-standard (cubic-bezier(0.4, 0, 0.2, 1)), --motion-ease-accel (cubic-bezier(0.4, 0, 1, 1)). Durations match existing quorum-app/globals.css conventions; the decel curve matches the existing Select listbox enter and modal slide.height + opacity (0.6 → 1 on L1, 0.7 → 1 on L2), no stagger between siblings. Chevron rotation synced to parent duration and curve.class="motion" and data-motion-scale="L1"|"L2" to each <details>. Wrapped non-summary children in <div class="motion__content">. Inline ~30-line JS helper using Web Animations API on <details> toggle events (since native <details> doesn't animate). prefers-reduced-motion: reduce collapses durations to 1ms (snap), drops opacity fades and translates, keeps chevron rotation as a directional indicator.Story 1.3.2 → review: WCAG AA gate goes wide, 5 e2e regressions cleared (quorum-app, afternoon session)
Path A from yesterday's recommendation: close Epic 1. Story 1.3.2 moved draft → review. The day's substance was widening the automated WCAG 2.1 AA coverage from the design-system reference page out to the post-auth core surfaces and the full /sign-up funnel — which immediately earned its keep by surfacing three more real production contrast bugs on shared chrome. All fixed, all retested, full gate green twice back-to-back. Tier 2 wrap, 4 commits on local main, unpushed.
Wider WCAG 2.1 AA coverage — 12 page-states under the gate (quorum-app)
/design-system at rest + with modal open, /sign-up, /sign-in, /workspaces picker (clean + with Edit modal open), /w/<id>, /w/<id>/members (team variant + solo_free variant), /new-workspace landing + plan-change panel, /sign-up?plan=solo_pro credentials step, /sign-up/pay?plan=solo_pro. Twelve distinct page-states. 39 axe scans across the run. Critical + serious filter — no severity exclusions on /sign-up anymore..sp-plan__period ("/mo" and "per user / mo" on every plan card across the funnel) — 3.22:1 (oklch(48%) ≈ #516164 on deep bg). Token swapped from --sp-fg-subtle to --sp-fg-subtle-aa (the AA-passing variant already existed in the codebase, just unused on this element). Now ~5.5:1..sp-footer-link a ("Already have an account? Sign in" on credentials step) — 1.72:1 link-vs-surrounding (cyan accent on muted gray, no underline). Added text-decoration: underline + 3px offset matching the existing .sp-legal treatment. WCAG 1.4.1 satisfied via non-color distinguisher..sp-footer a (same link wording on the landing-page footer) — same cause, same fix.--*-fg-subtle family of tokens (oklch 48%) is below AA on the deep backdrop in this codebase. The codebase ships -aa variants of the same tokens for exactly this case. Rule, written down: use the -aa variant for primary text on the deep bg; reserve plain -subtle for very-dim secondary content where AA isn't expected.Five e2e regressions surfaced + fixed (quorum-app)
The first full e2e run after the a11y work surfaced 5 regressions. None were caused by today's changes — all were existing drift from earlier voice / visual work that the spec selectors hadn't caught up with. All fixed in 8d68d74:
signup-funnel.spec.mts (lines 76, 101, 118, 129) traced to the Quentin voice pass at commit 81b4a4b. "Continue" is a banned generic verb in the voice guide; the comparison-panel CTA had been renamed Continue → Switch to <plan-name> (e.g. "Switch to Team Starter") and the back button Go back → "Keep current plan". Test selectors weren't updated. Regex moved to /^Switch to /i and /^keep current plan$/i.sign-in.spec.mts:53 ("multi-workspace picker lists memberships and navigates on click"): getByRole("link", { name: /Globex/i }).click() was finding the absolute-positioned .app-ws-card__link but the click was landing on a foreground sibling (the card content sits at higher z-index than the link's z-index: 1 because of stacking-context order). force: true didn't help — Playwright still routes through document.elementFromPoint which respects z-index. Switched to keyboard simulation (focus() + Enter). Cleaner than force-click; mirrors real keyboard-nav.Story 1.3.2 status flipped to review (quorum-app)
_bmad-output/implementation-artifacts/1-3-2-self-signup-with-plan-type.md — Tasks 13 + 14 checkboxes flipped with close-out notes; status header now reads review._bmad-output/implementation-artifacts/sprint-status.yaml — 1-3-2-self-signup-with-plan-type: review. last_updated: 2026-04-28. most-recent-action updated.project_stripe_mocked_v1 (placeholder IDs + Mock pay button). Deferred (not blockers to review): Task 5 (OAuth Google + Apple) blocked on developer-projects setup; OAuth happy-path e2e + Stripe paid-plan happy-path e2e blocked on those tasks shipping.Moments That Matter v0.5 — moment #58 added (planning repo)
accessibility-statement.md, FR47 (portfolio doc — automated gates are part of the case study).Platform decision locked to memory (quorum-app side)
project_platform_web_first_tauri_later.md indexed in the quorum-app project memory MEMORY.md. Locked answer to the recurring question "are we web or native": web-first Next.js, future macOS via Tauri shell, never native iOS / Android / SwiftUI / RN. Surface this when the question comes up rather than re-debating.Verification at wrap (quorum-app)
npm run typecheck clean.npm run lint — 0 errors, 1 pre-existing react-hook-form watch warning in SignUpForm.npm run test -- --run — 51/51 vitest unit tests pass (6 files).npm run test:e2e — 93/93 playwright tests, run twice back-to-back (~8 min each). Specs: a11y-coverage (10), create-workspace, design-system (29), edit-delete-workspace (12), invite-and-accept, sign-in, signup-and-plans, signup-funnel, workspace-upgrade (5).Commits (quorum-app, Tier 2 wrap, 4 unpushed on local main)
f25683f — Wider WCAG 2.1 AA coverage — post-auth core + extended marketing.b4937fe — A11y: extend coverage to /sign-up funnel + fix 3 WCAG AA bugs.07f5494 — Story 1.3.2: Task 13 close-out + Task 14 docs.8d68d74 — Story 1.3.2 → review: 5 e2e regression fixes + status flip.Push deferred to next quorum-app session per Tier 2.
Cross-repo state at wrap
quorum — local main 1 commit ahead of origin/main (5a6f1ec Wave 5 from 2026-04-27 evening, still unpushed). Two uncommitted file writes from quorum-app sessions: moments-that-matter.md (moment #58 + frontmatter v0.5) and this change-log.md entry. Tier 2 wrap on the quorum side will fold both into a single commit; Tier 3 will push Wave 5 + the new commit together.quorum-app — local main 4 commits ahead of origin/main. Push deferred.Wave 4 polish on planning exports (planning repo, evening session)
<select> to a custom dropdown component ported from master-doc's .dd pattern. First attempt used a fixed-position portaled listbox at z-index 1000; that anchored to a transformed/blurred ancestor and rendered "far below the trigger and behind tiles" — same root cause as today's quorum-app modal-clipping fix. Second attempt copied master-doc's approach verbatim: position: absolute inside .dd { position: relative }, no portal, panel at z-index: 30 inside an .epics-nav whose z-index: 20 actually sticks (see next bullet).body > * z-index normalizer corrected. The rule body > *:not(.page-globe):not(.am-modal-overlay) { position: relative; z-index: 1 } was clamping .epics-nav to z-index 1, trapping its descendant dropdown panel inside a low stacking context. Added :not(.epics-nav) to match master-doc — comment explains the specificity reason (0,2,1 vs. 0,1,0) so future passes don't strip the exclusion..epics-nav no longer sticks to the top of the viewport. Dropped position: sticky; top: 0 in favor of position: relative (z-index retained for the dropdown panel layering). The container scrolls naturally with the rest of the page now..dd__panel rather than mutating --surface-strong to keep the change scoped..doc-status-meta was -0.25rem 0 1.75rem — negative top pulled the pill tight against the subtitle. Now 1.25rem 0 1.5rem for breathing room above and below._gen_bmad_exports.py and _style.py saved as *.bak-2026-04-27 (untracked) before the dropdown rewrite — keeping them out of the commit so the working tree stays clean.Workspace edit + delete API shipped (quorum-app, all-day session)
/api/workspaces/[id] route with owner-only authz via membership lookup. Zod validator (updateWorkspaceSchema) supports partial updates of name + planKey with an at-least-one refinement. P2002 dup-name returns 409 with the existing-workspace context. DELETE wraps workspaceInvite + membership cleanup + workspace.delete in a Prisma transaction since the schema doesn't declare onDelete: cascade.project_stripe_mocked_v1 — plan transitions sync mock IDs (paid plans get mock_cus_<uuid> / mock_sub_<uuid> populated; free plans clear them). Mirrors the create flow's behavior.src/server/errors/codes.ts: workspace_not_found and workspace_not_authorized.EditWorkspaceDialog + DeleteWorkspaceDialog wired to real fetch with loading state, inline error rendering, dup-name 409 surfacing, and router.refresh() on success. Privacy radio dropped from the edit form since Workspace.type is server-derived from plan (mirrors create flow).tests/e2e/edit-delete-workspace.spec.mts (10 tests). 7 API-level tests passing (PATCH/DELETE happy paths, mock Stripe ID transitions, transactional cascade, authz, unauthenticated). 3 UI-level tests have selector misses against post-rename markup; deferred until a follow-up touch.WorkspaceCardActions, so useState reinitializes from current props after a save → router.refresh updates the workspace name. Previous behavior: dialog stayed mounted across opens, capturing stale name.Modal UX system v2 (quorum-app)
document.body via createPortal. Fixes the card-clipping bug (workspace cards used backdrop-filter, which creates a containing block for position: fixed descendants — modal got rendered inside the card).small=400 / medium=640 / large=800 via size prop on Modal. EditWorkspaceDialog uses medium; DeleteWorkspaceDialog uses small. The 600px workspace tile container + 640px Edit modal gives a 40px breathing room when the modal overlays.oklch(15% 0.014 215 / 0.97) from 8% / 0.94), accent border (oklch(40% 0.02 215 / 0.7)), stacked drop-shadow + 2px inner top highlight (4% white) for a subtle bevel that reads as elevation against the dimmed page.saturate(0.85) at 0.45 dim. Three blockers removed: isolation: isolate from .app-scene (created a stacking context backdrop-filter couldn't see through), nested backdrop-filter from .app-ws-panel and .app-ws-card (Chrome's compositor doesn't cascade nested ones cleanly)..app-modal-swap slide-pattern track for dialogs that need a primary view + sub-view. Mirrors the /new-workspace .app-plan-swap mechanic — outer container clips, inner track is 200%-wide flex with two 50% panels, data-mode controls translateX. JS measures the active panel's height via ResizeObserver so the modal doesn't reserve empty space..app-pill-btn for compact secondary navigation chips inside dialogs. Frosted dark surface, soft border that lights up to accent on hover/focus, fully-rounded.Custom Select component (quorum-app)
src/components/ui/Select.tsx replaces the native <select> in the Edit dialog plan field. Per James's directive: no native dropdowns in this app or flow.document.body (z-index 90, above modal at 80) so the options panel escapes overflow/clip ancestors and works inside the modal without being clipped.oklch(8% 0.01 215 / 0.96) + 14px backdrop blur). Selected row in accent color + bold; highlighted row in subtle blue-tinted overlay. Optional description per option (used for plan blurbs in the Edit dialog)..ap-select-trigger (matching .ap-input aesthetic + chevron that rotates 180° when open). Listbox styled via .ap-select-listbox + .ap-select-option.Toast success tone (quorum-app)
Toast accepts an options object now: showToast(message, { tone?: 'default' | 'success', durationMs? }). Existing slide-from-top animation, 4s hang, single-slot semantics all unchanged.oklch(18% 0.06 145 / 0.92) background + oklch(72% 0.16 145 / 0.45) border + soft inner glow) and a check icon in a circular green pill on the left.EditWorkspaceDialog (echoes what changed: rename / plan / both), DeleteWorkspaceDialog, ChangePlanPanel (existing detailed billing message gets the success tone).Workspace surfaces tweaks (quorum-app)
/workspaces cards wrapped in .app-ws-panel container (max-width 600px, centered, padding 24px, soft border + radius). Quiets the wired-globe behind the workspace block so it reads as a discrete piece of UI. backdrop-filter removed from this container per the modal-blur fix above./w/<id> workspace room stub gets a one-line description next to the Members link: "Roster, roles, and how to invite the next person in." Story 2.1 will rewrite the page; the line is safe to ship ahead of that.Quentin voice pass + locked copy (planning repo)
Kinsley + Luca engagement queued (planning, not started)
Three bundled work streams scoped for one Kinsley + Luca engagement, awaiting trigger:
_bmad-output/planning-artifacts/design-system.md. Inventory existing components (Modal sizes, Select, Toast tones, button system, inputs, cards, pill, tokens, layout patterns). Each component documented with tokens / variants / usage rules / a11y notes / code locations._bmad-output/planning-artifacts/user-flow-map.md. Mermaid diagrams + prose for 10 flows (sign-up funnel, sign-in, first workspace creation, switching, edit, delete-via-archive-future, member management, invite acceptance, plan-change scenarios, solo-to-team auto-promote).Quentin will do voice + a11y pass on Streams 1-2 after Kinsley drafts. Trigger phrases: bring in Kinsley / bring in Luca / bring them both. Sequence: Streams 1 → 2 → 3.
Project memory updates (quorum-app side)
project_workspace_archive_then_delete.md — workspace deletion will go through Archive in a future story (soft-delete first, hard-delete only from Archive view). Two-stage gate prevents one-click destructive accidents (Notion / Linear / Gmail / Stripe pattern). Schema add: archivedAt: DateTime?. Estimated half-day. Indexed in MEMORY.md.Workspace creation features (proposal, not built)
Three new dimensions on workspace creation surfaced for design discussion (no code):
Recommended phasing: Phase 1 = three nullable fields on Workspace, three picks in /new-workspace with skip-for-now defaults, surface on the tile as a small metadata strip. Pretend / mocked (no filesystem provisioning) per the project_stripe_mocked_v1 precedent, labeled honestly as "preview" / "saved for v2." Phase 2 = settings page so users can change later. Phase 3 = real provisioning via a Claude Code skill bridge.
Commits (quorum-app)
d4fd698 — Workspace edit + delete API + modal UX system. One bundled commit because EditWorkspaceDialog carried both API wiring and UX system in the same heavily-rewritten file. 15 files / 1359 insertions / 181 deletions. Lint + typecheck clean. Tier 2 wrap, no push — 6 commits now sit unpushed on local main.Afternoon session — design system route, user flow map, FAQ + a11y polish (quorum-app)
The afternoon picked up uncommitted in-flight work that wasn't recapped in the morning Tier 2 wrap (two new Next routes, TextField component, liquid-glass refresh, ~1.7k line delta). Audited it, fixed real bugs the audit surfaced, then closed all five carried 04-25 visual-review checklist bullets. Tier 3 wrap at the end — five commits pushed to origin/main.
/design-system — internal-facing live reference page (quorum-app)
src/app/design-system/page.tsx (733 lines) + design-system.css. Imports actual Modal, Select, Toast, TextField from the codebase so the doc cannot drift from production. Sections: Tokens / Layout patterns / Components / Planned, with TOC. Internal developer reference; the forward-facing portfolio version is the existing quorum/_bmad-output/planning-artifacts/design-system.md (still a stub).tests/e2e/design-system.spec.mts (29 tests). Covers smoke + structure, TextField states, Select keyboard nav, Modal three sizes + Escape + slide-swap, Toast tones, Pill, Buttons, status badges, workspace card. Includes axe-core WCAG AA passes on /design-system at rest, with Modal open, on /sign-up, and on /sign-in..app-modal__btn-danger (every Delete-workspace button) was 4.05:1 (white on #d74745). Background darkened to oklch(50% 0.18 25) (~5.5:1). Hover and focus tones moved together so the button still lifts visibly on hover..app-ws-card__updated-abs (every workspace card timestamp) was 3.19:1 (#516164 on #010303). Switched the color token from --app-fg-subtle to --app-fg-muted (~5.5:1)./user-flow-map — server-rendered mermaid pipeline (quorum-app)
src/app/user-flow-map/page.tsx. Server component reads docs/user-flow-map.md (50KB, 12 flows) at request time, walks the markdown token stream so mermaid fenced blocks become live <MermaidBlock> client components and everything else renders as static HTML.MermaidBlock lazy-imports mermaid on first use (no SSR touch), renders each block with a stable useId instance, dark theme matching the app's cyan tokens, per-block error fallback, and collapsible mermaid source. marked + mermaid added as deps.docs/_fix_mermaid_syntax.py script was in the repo for exactly these issues but its regex didn't catch enough cases. Three categories of fix landed:[/.../] as a parallelogram shape; embedded slashes in node labels like WS[/w/id], Root[/], MembersPage[/w/id/members] corrupted the parse. Script now wraps any such label content in double quotes regardless of inner slashes.<br/> self-closing tags. Mermaid HTML labels accept <br> but not <br/> — the /> confused the lexer in non-quoted labels. Now globally normalized to <br> inside every mermaid block.; as a newline-equivalent statement separator, so Create membership; mark invite acceptedAt was being read as two statements and the second failed. Script now swaps ; for , inside sequence bodies. (2) Mid-word apostrophe: existing curly-quote regex (\b\w)'(\w) required a word boundary and missed You're. Tightened to (\w)'(\w).TextField component + liquid-glass coherence pass (quorum-app)
src/components/ui/TextField.tsx — floating-label outlined input. Material 3 outlined-variant behavior with Quorum cyan accent. Implementation uses a <fieldset>/<legend> pair to draw the outline + create a natural notch behind the floating label, with :placeholder-shown driving the empty-vs-filled state.CreateWorkspaceForm, EditWorkspaceDialog, DeleteWorkspaceDialog, InviteForm. RHF integration via <Controller>.globals .ap-card, sign-in scene card, sign-up plan tile, sign-up plan-compare card all unified to the app-scene recipe (24px blur + 1.4 saturate + inset highlight + edge ring + softer outer drop). The Modal portal makes nested backdrop-filter on .ap-card safe again. Single visual language across pre-auth and post-auth surfaces./sign-up (the marketing surface) instead of /sign-in. Returning users still reach /sign-in via the footer link there.Sign-up FAQ accordion — predictable layout (quorum-app)
.sp-faq__grid is a 2-col CSS Grid at ≥900px. Default align-items: stretch was making a closed left card grow to match the right card's height when the right card was opened (and vice versa) — confusing because the left card visibly changed without any interaction.align-items: start so each card keeps its natural height. Opening one card now grows only that card; its sibling stays put. Some whitespace appears below the shorter card — explicit trade-off, predictable layout beats packed layout here.Carried 04-25 visual-review checklist — all five bullets closed (quorum-app)
+ New workspace link verified — wired correctly with hover state and /new-workspace target./w/<id>/members Upgrade CTA → invite-form-reveal stagger verified — CSS at globals.css:240-264 still matches the post-TextField + post-Select InviteForm DOM (email TextField div as nth-of-type 1, role wrapper div as nth-of-type 2, submit button — keyframe delays 0/100/200ms)./w/<id>/members "Upgrade to Team Starter →" link verified — points at /sign-up/pay?plan=team_starter with explicit non-bait copy ("Real plan changes for an existing Solo Pro land in a future update").InviteForm role field migrated from native <select> to custom Select via <Controller>. Reuses existing ROLE_OPTIONS retyped as SelectOption<Role>. Label moves from htmlFor= to id= + ariaLabelledBy= since the trigger is a <button>. workspace-upgrade.spec.mts 5/5 still green..app-ws-card and decorations for any teal/cyan border-top or pseudo-element accents; none found. Regression remains fixed.Commits (quorum-app, Tier 3 push)
9d34857 — Design system route + flow map + TextField + liquid-glass refresh. 21 files / ~2.1k insertions.79a6930 — Update edit-delete spec selectors for TextField label rename. (1 file, 4/4.)a16f6ff — Fix all 12 user-flow-map mermaid blocks. (_fix_mermaid_syntax.py upgrade + the markdown source rewrites it produces.)2066710 — Stop FAQ accordion siblings from stretching to match each other.a25db16 — Migrate InviteForm role to custom Select.d4fd698..a25db16 (6 commits, morning + afternoon) pushed to origin/main at Tier 3 wrap. Local main matches origin/main. Verification at push: typecheck clean, lint clean (1 pre-existing useForm.watch() warning in SignUpForm), design-system.spec.mts 29/29, edit-delete-workspace.spec.mts 12/12, workspace-upgrade.spec.mts 5/5, /user-flow-map 12/12 mermaid blocks rendering.
Sign-up funnel polish closeout (quorum-app, morning session)
/sign-up/pay) picked up two finishing CSS edits: comparison Continue button keeps primary-gradient styling at 30% opacity when disabled (replaces the previous "different greyed button" look — now reads as "same button, not actionable yet" with a clear 30%→100% beat on activation); paired Go back styled as a secondary outline using the same accent color the primary's gradient is built on, so the row reads as a paired set rather than primary + neutral.Primary-button system unification (quorum-app)
.ap-btn-primary on /new-workspace / /w/* / /invite/*, .sp-submit and .sp-plan-compare__continue on /sign-up. Color drift (#7cd6e8 sRGB vs oklch(82% 0.15 200) ≈ #7ad7e9), glow box-shadow vs flat, and mismatched disabled opacity (0.4 / 0.6 / 0.1) all collapsed to one treatment.transform: scale(1.03), disabled uniformly at 30% opacity keeping the gradient + accent text intact. James's framing: "the primary buttons need to all have the EXACT same styling [...] consistency is KEY."--sp-accent* (sign-up scene) and --app-accent* (post-auth scene) token sets both alias to globals' --accent / --accent-hover / --accent-ring so the cyan/teal never drifts between scenes again. Single #7cd6e8 source of truth./new-workspace plan-change UX rebuilt (quorum-app)
/sign-up landing with no plan context) with an in-place slide-swap to a comparison grid — same pattern as /sign-up/pay's PayStep. New <ChangePlanPanel> client component owns confirm/comparison modes, swap track with cushioned 480ms ease-in-out, and Continue routing logic./sign-up/pay?plan=<new> (first-time charge needed); Paid→anything stays on /new-workspace?plan=<new> and surfaces a toast naming the proration direction. Stripe stays fully mocked per project_stripe_mocked_v1 — toast signals intent only; real proration lands in v2.ResizeObserver against an inner content wrapper so the swap doesn't reserve empty space below itself in the short confirm mode. Card surface (border + backdrop blur + bg) sits on the panel-content wrapper so both modes share the same visible card chrome — confirm row in a small card, comparison grid in the same card scaled up.Global Toast provider added (quorum-app)
<ToastProvider> + useToast() hook mounted in <AuthenticatedShell>. Top-anchored, slides down from above the viewport on enter, 4s auto-dismiss, manual × close, slide-up on exit, ease-in-out (cubic-bezier(0.4, 0, 0.2, 1)) for both slides at 320ms each, reduced-motion safe. Single-slot for simplicity (replaces and resets timer if a new toast fires while one is showing).Em-dash sweep across user-facing copy (quorum-app)
PayStep.tsx (×2), CredentialsStep.tsx, NewsletterWidget.tsx (×2), UpgradeToTeamCTA.tsx, new-workspace/page.tsx (×2), ChangePlanPanel.tsx (×1).Configurable top nav with "+" modal (planning repo, afternoon session)
NAV_ITEMS constant in _gen_bmad_exports.py. 11 entries: 9 primary doc-type links (planning, case-study, prototype, briefs, portfolio, visual-specs, motion-specs, tech-stack, designs) + 2 right-side CTA pills (change-log, version-control). Each entry carries key, label, slot, default, coming (renders the existing "soon" chip), rel (href relative to exports/), and an optional nav_label override so long modal labels can be abbreviated in the slim nav (e.g., "Tech stack and process" → "Tech stack" in the nav button, full label in the modal).backdrop-filter: blur(6px) (the dim alone was invisible against Quorum's near-black page), scale-in animation 25% → 100% on open via transform: scale() + opacity, three configurable sizes (small 300px, medium 500px default, large 800px) via data-size attribute, semi-transparent surface (rgba(8, 20, 32, 0.78) + 18px backdrop blur) matching the rest of the chrome.updateApplyState() compares current inputs vs saved state on every change). Esc, click-outside, Cancel all dismiss without saving. Apply persists the chosen set to localStorage under quorum-nav-items-v1..am-modal__content as the first child, not as a full-bleed banner. Restyled mid-session to match the rounded callout pattern: success palette (var(--success-bg/border)), 10px radius, 16px (1rem) padding all around, animates open by transitioning max-height + padding + margin + border-width together so it visibly pushes title/list/actions down. Includes a "Close" CTA that dismisses the modal..page-subnav row rendered below the .page-header divider with its own faint bottom border so it reads as a second nav band rather than free-floating. Sub-nav is display: none until populated and uses slightly smaller link font (0.7rem). Distribution rule (in JS applyToDom()): walk PRIMARY_ORDER (injected from Python), first 3 visible items append to .page-nav, rest append to .page-subnav, hidden items park in .page-nav with data-nav-on="false" (CSS [data-nav-on="false"] { display: none !important; }).exports/briefs/index.html, exports/portfolio/index.html, exports/visual-specs/index.html, exports/motion-specs/index.html, exports/tech-stack/index.html, exports/designs/index.html) via a new render_nav_placeholder(slug) helper called from main(). Each page lists planned contents specific to its slug (e.g., briefs lists "Project briefs / Discovery briefs / Stakeholder briefs / Scope-cut summaries"). Same chrome as every other page so the modal still works there..am-modal-overlay had to be added to the exclusion list of BOTH body > *:not(...) rules (the 64rem max-width / centered-column rule AND the position: relative; z-index: 1 rule). Without those exclusions, position: fixed; inset: 0 got overridden into position: relative and the modal rendered inline at the bottom of the page flow instead of as a viewport overlay. Lost two iterations to this before tracing it.data-nav-on is now baked inline in the HTML at render time (not just set by JS on load). Without this, every unchecked nav button was flashing visible during the gap between HTML parse and JS execution — those were the "boxes at the top" James spotted on the first build.white-space: nowrap on .page-nav__link and .page-header__cta so labels never wrap mid-word (earlier "TECH / STACK / AND / PROCESS" rendering when crowded). flex-shrink: 0 on .page-header__actions so the right group never collapses..is-active link). Removed at user's call — hover state on adjacent links made the dots read awkwardly.plus and check entries.master-doc/src/_gen_bmad_exports.py and master-doc/src/_style.py in a separate session so nothing gets overwritten — a comprehensive prompt covering all parts (NAV_ITEMS structure, modal HTML/JS helpers, wrap_page rewrite, full CSS block, the two body > * specificity gotchas, the inline-data-nav-on flash fix, default-state validation checklist) was drafted in conversation and copied off for manual paste. Existing projects (Quorum, Autora, ValorAid) are unaffected — only future master-doc scaffolds will inherit this nav system.Quentin voice pass on plan-change copy (quorum-app, late afternoon)
quorum/_bmad/memory/agent-quentin/) across all three plan-change comparison panels: /new-workspace, /sign-up/pay, /sign-up?plan=.Switch to {targetPlan.name} for plan switches; Pay for {targetPlan.name} on Free→Paid. Names target plan = doubles as confirmation read-back./new-workspace: {currentPlan.name} stays active until you confirm a different plan. Equivalent rewrites on the sign-up surfaces.quorum/_bmad/memory/agent-quentin/sessions/2026-04-26.md.Workspace surfaces v1 (quorum-app, late afternoon / evening)
AuthenticatedHeader. New <WorkspaceSwitcher> client component renders a dropdown trigger between the brand and right-side header group. Visible only when the user is inside /w/<id> AND has 2+ memberships. Click-outside / Escape close. Footer link See all workspaces → /workspaces.AuthenticatedShell made async, fetches lightweight memberships once, passes to header. Four call sites updated to pass userId={user.id}./workspaces picker upgraded to cards. Each card has: workspace icon (placeholder glass tile with first letter, hover reveals pencil overlay → file picker → "Custom icons land in v2" toast), name + soft status badge (computed from existing fields: Just created / Awaiting invites / Active / Quiet), role + plan + member count, last-activity timestamp, and hover-revealed edit + delete action buttons.Learn more disclosure explaining what a workspace is and what's inside (Plan / Design / Build / Members / Portfolio). Native <details> for v1; future story replaces with a dedicated walkthrough page.<Modal> generic shell. Delete dialog follows Quentin's destructive pattern (names what's deleted + type-name-to-confirm). Edit dialog: name + privacy (mapped to Workspace.type) + plan dropdown + members preview with link to /w/<id>/members. All commits fire toasts; real PATCH/DELETE filed as backlog story.Backlog stories filed for future implementation
Three stories drafted today and shared with James in chat for paste-into-planning:
Workspace.status enum + new WorkspaceActivity table replacing today's heuristic-only badges. ~2-3 hrs./workspaces/learn-more (or similar) replacing today's inline <details> once the workspace has concrete sections to depict. Sequenced AFTER Story 2.1 team room.Quorum-app commits today (5, all on local main, none pushed)
| Hash | Title |
|---|---|
cc044ab |
Sign-up funnel polish closeout — primary-button system unified + em-dash sweep |
9db9976 |
/new-workspace — plan-change swap + billing-impact UI + global Toast |
b9780de |
Add CHANGELOG.md mirroring the sibling quorum project-wide change log |
| (afternoon commit 1) | Quentin voice pass on plan-change copy across the three comparison panels |
| (afternoon commit 2) | /workspaces — switcher + picker cards + edit/delete prototype + Modal scaffolding |
GitHub: https://github.com/jcfrank8910/quorum-app/commits/main
Status pill + global select styling (planning repo, late afternoon)
status from a flat subtitle line ("Status: living document") to a proper rounded pill rendered directly under the H1, using the cyan accent palette (var(--accent) text, var(--accent-soft) bg, var(--accent-ring) border). Below the pill, a small mono-font line shows Last updated: <abs date+time> (<relative>) pulled from the source file's actual mtime (not the frontmatter lastUpdated: field, which only carried date and went stale). Injected via re.sub after the first </h1> in the rendered markdown body, so any doc with status: in its frontmatter inherits the treatment automatically (change-log has it now; version-control and future status-bearing docs will pick it up the next time they're regenerated).mtime across all DOC_REGISTRY source files, i.e., "when did anything in the planning tree last actually change." Reflects project liveness, not regeneration time.select styling. Promoted the existing .epics-nav__select rules (dark-glass surface, cyan chevron via embedded SVG data URI, hover/focus states with accent ring, custom optgroup + option color tokens) to apply to every <select> element in the export tree. .epics-nav__select was trimmed down to just width: 100% (its grid-cell layout responsibility). Future selects added anywhere now match the aesthetic without needing a class.<select> popups are rendered by the OS and CSS can't reach inside them. Chrome respects partial option { background, color } overrides; Safari and Firefox ignore most popup styling and fall back to OS chrome. Decision: build a custom JS dropdown widget (option A from the pitch) that replaces every <select> on page load with a fully styleable button + listbox panel — keyboard nav (arrows / Home / End / Enter / Esc / type-to-jump), click-outside-to-close, ARIA combobox/listbox/option roles, optgroup support, scroll-into-view for active option, and MutationObserver so dynamically-changed select content (the epics-nav story-filter logic on the index) stays in sync. Designed but deferred — implementation will land in the next session.Open threads carried into the next session
<select> globally (epics-nav epic + story selectors are the immediate beneficiaries on the index). Original <select> stays in the DOM hidden so form values + change events still work; widget exposes the proper ARIA roles for accessibility. Roughly 80–150 lines of focused JS plus a CSS block for .q-select / .q-select__trigger / .q-select__panel / .q-select__option etc.quorum-app/docs/motion-system.md.SESSION-RESUME-2026-04-25.md): AuthenticatedHeader top-right + New workspace link verification, members-page upgrade CTAs (solo-free upgrade reveal + solo-pro upgrade-to-Team-Starter link), role-dropdown chevron breathing room, teal-line artifact regression check.Workspace.type. If a separate privacy concept is wanted, schema migration goes in Story 2.x (edit + delete API).Cross-repo change-log discipline + promote-queue design + portfolio-push roadmap (afternoon session)
SESSION-RESUME-2026-04-25.md. Stale items removed (Story 1.3 close-out long-since shipped; Story 1.3.2 marathon nearly complete). Actual current state surfaced: top priority is the incomplete visual review of the three sign-up flows (paused mid-eyeball), pending OAuth task blocked on James, hosting deploy still deferred, Autora + ValorAid index propagation still pending.quorum-app/SESSION-RESUME-YYYY-MM-DD.md for cross-repo coverage. (Saved as feedback memory.)jayfrank.info is Framer-hosted; Framer MCP is now installed and connected to Claude Code). New target: Framer-native or Framer-adjacent hosting. Three open questions before design (goal / subdomain vs. subpath / static-import vs. native-rebuild). Investigation deferred to next session.<project>/_bmad-output/promote-to-master-queue.md entry → from master-doc session run review-promote.sh → pick + diff + decide per file → apply to master-doc/src/ → manual commit in master-doc → queue entries auto-marked promoted/declined with audit trail). Always-print reminder: master-doc improvements benefit ONLY newly-scaffolded projects, never backflow into existing ones. Four open design choices to confirm before building (auto-detect downstream vs. explicit list; drift-scan opt-in or skip for v1; queue file visibility; trigger phrase via ~/CLAUDE.md or skill). Build estimate ~20-30 min for v1.time-log.yaml. New project total: 27h 10m (18h 32m pre-existing + 7h 23m morning session committed in c08fc51 + 1h 15m this afternoon).Architectural pivot — master-doc as template / seed model
~/Desktop/projects-inflight/master-doc/) pivoted from a subscribe model to a one-shot template / seed model. publish.sh --apply retired; replaced with publish.sh --init <project-path> (one-time scaffold). downstream.json deprecated.https://github.com/jcfrank8910/master-doc.--init to bring them to the current shared-code state, then sealed off as independent forks. Future master-doc improvements benefit only newly-scaffolded projects.Quorum becomes a downstream consumer of master-doc
_gen_bmad_exports.py and _gen_prd_exports.py refactored to import per-project values from a new project_config.py (DOC_REGISTRY, FEATURED, EPIC_TITLES, SIBLING_APP_ROOT, branding strings).HERO_EYEBROW_BYLINE came across as a placeholder; restored to "Created by James Frank · 2026."7bc677b and pushed to origin/main.Setup zip caught up to the pivot
~/Desktop/projects-inflight/setup/ synced its payload to today's live config: bundled master-doc inside the zip, refreshed scripts and starters, extended PII scrub, updated install steps for master-doc placement.complete-setup-v20260425-0200.zip (938K) — ships the full template model.ValorAid sync committed + pushed
f6480a7 pushed to https://github.com/jcfrank8910/ValorAid.Time-log feature
time-log.yaml in planning-artifacts root for billable hour tracking. Replaces the wall-clock "Build time" stat with a manually-tracked "Hours" stat sourced from time-log.yaml entries.hours (decimal) and/or minutes (int) per entry. Display format: Xh Ym.Change-log feature
change-log.md created as the project-wide change log.Quorum-app Story 1.3.2 marathon (13 commits across 2026-04-24 → 2026-04-25, all pushed to origin/main)
e008e9a): documentation correction citing src/proxy.ts as the actual mechanism for AC #6 (Next 16 renamed middleware.ts → proxy.ts). Status flipped review → done in both story file and sprint-status.yaml.1901a80).signUpAction (daddb88).3cbd97c).f004b41).eb410b2).9102f1d).3590f76).f6be801): no @stripe/* imports, no STRIPE_* env vars; placeholder cus/sub IDs.6f75606): slide-swap animation between credentials and plan-comparison steps, breadcrumb navigation, select-then-Continue flow, button-activation states, a11y/UX pass.0935cd5); copy refinements + filed two known-issue follow-ups (9967326); sprint-status most-recent-action aligned to Story 1.3 (d504526)./sign-up?plan=* axe color-contrast + link-style violations (needs Quentin/Kinsley collab); displayName regex blocks apostrophes (loosen to /^[\p{L}\s\-']+$/u if real users hit it).quorum-app/SESSION-RESUME-2026-04-25.md (Flow 1 /sign-up landing, Flow 2 credentials step, Flow 3 payment step + adjacent surfaces).Three-pillar checkpoint gates landed end-to-end
## Three-Pillar Checkpoint Gates section with per-pillar pass criteria, exit rules, override-with-audit semantics. FRs added: FR25b (terminal verdicts), FR25c (gate-cleared required for allocation), FR25d (override audit + downstream markers). Traceability map updated.lastSaved bumped, recentChanges array added.Planning-export structural upgrades
epic-1.html through epic-11.html) auto-generated from epics.md.<details> accordions with left-aligned status slot.git log, day-grouped, foundation marker for pre-repo work.Coming-soon page
coming-soon/index.html with Quorum branding. Ready for Cloudflare Pages deploy when hosting config lands.Story 1.3 close-out (quorum-app, file-writes)
src/proxy.ts (Next 16 rename of middleware.ts) was the actual mechanism satisfying AC #6 — phase A always had it. Close-out is documentation-only.review → done in story file and sprint-status.yaml.Voice & content-strategy work
voice-drift-audit-2026-04-23.md.Four new content-strategy artifacts
release-notes-format.md v1.0 — Model B workflow (Paige drafts, Quentin polishes), template, 3 worked examples.accessibility-statement.md v0.1 (do-not-publish until v1 + first audit) — pre-MVP commitment framing.error-pages.md v1.0 — copy for 404 / 500 / maintenance / offline / 403 / 401 / 429 / unsupported-browser.voice-drift-audit-2026-04-23.md — full per-file drift log.Story 1.3.2 Voice Pass (quorum-app, uncommitted)
Moments That Matter v0.3
Quentin agent activated
~/.claude/skills/agent-quentin/, vendored into Quorum + Autora + ValorAid + quorum-app._bmad/memory/agent-quentin/ with voice mandate + em-dash scope lock.~/CLAUDE.md step 7b auto-vendors all ~/.claude/skills/agent-* into new projects.Voice & Tone Guide v1.0 + Moments That Matter v0.1 / v0.2 + Case Study v0.1 + Version Control Strategy v0.1
Product roster (in quorum-app)
quorum-app/TEAM.md and quorum-app/src/features/team/roster.ts. Paul replacing Dr. Quinn. Consolidated with Jaymes's TeamPopover work.Export pipeline rebuild — Quorum-branded
_style.py (single source of truth).#02060c bg, #eaf6fa fg, #7cd6e8 accent. Space Grotesk + Source Code Pro. Exact body gradient from globals.css.For days prior to 2026-04-22, see the Project Timeline page (auto-generated from git log) for commit-level granularity. High-level beats from earlier days:
## Change log in voice-tone-guide, moments, etc.): changes specific to that doc's content. The project change log links here for context.