v1.10 — Visual Evolution
Recreate the next visual language for Objectuve — defined by five HTML mockups (Onboarding desktop+mobile, Meet Coach desktop+mobile, Dashboard) — across three live surfaces, then audit and update the rest of the Storybook component library to match. Token-accurate, not pixel-perfect. No new product features.
Summary
Five HTML mockups landed on OBJ-43 on 2026-04-25 with a refined evolution of the existing visual language: refreshed dashboard composition, restyled onboarding chrome, restructured Meet Coach. Shipping the three surfaces alone would have left the rest of the app visually inconsistent — so v1.10 paired the three live-surface phases with a whole-Storybook sweep across every other component family.
The milestone shipped in 10 phases, 13 plans, and 47 tasks: a foundation-tokens phase (39), three live-surface phases (40 onboarding, 41 meet coach, 42 dashboard), a Storybook library audit (43), five family sweeps (44 goal, 45 communities, 46 achievements, 47 modals & overlays, 48 chrome), plus this final docs phase. Two micro-tasks rode along as standalone PRs: an m3 TodayActions tap-target fix and an m1+m2+n1 follow-up on the --warning token contrast post-Phase-44. The v1.9 Goal Roadmap milestone was merged into the milestone branch mid-flight via a true --merge topology.
The headline finding from Phase 39 set the shape of the milestone: zero tokens-new. Desi's foundation-tokens analysis confirmed the five mockups exercise only canonical tokens already in tailwind.config.js, tailwind.css, and docs/brand/brand.md. Every subsequent phase was therefore a token-migration phase, not a token-introduction phase. The two new tokens that did land — --warning (Phase 44) and --rarity-* (Phase 46) — were introduced in service of removing inline hex literals from existing component code, not in service of the mockups.
The milestone closed with no outstanding DESIGN-DRIFT: findings, every needs-update component shipped or formally deferred (the Streamlined dashboard sub-tree is documented as a v1.11 deferral), and all 8 BadgeModal contrast pairs (4 rarity tiers × 2 modes) measuring ≥4.5:1 AA Normal after a two-pass contrast methodology refinement.
Goal
Recreate the next visual language for Objectuve across three live surfaces (Onboarding, Meet Coach, Dashboard), then audit and update the rest of the Storybook component library to match. Token-accurate, not pixel-perfect. No new product features.
Scope — What Shipped
Foundation tokens (Phase 39, 61a69503)
- Five mockups (Dashboard, Onboarding desktop+mobile, Meet Coach desktop+mobile) ingested and committed as version-history originals at
.planning/milestones/v1.10/mockups/. - 30 reference screenshots captured via
scripts/capture-mockups.mjs(5 mockups × 3 viewports × 2 modes). - Three UI-SPECs published:
dashboard-UI-SPEC.md,onboarding-UI-SPEC.md,meet-coach-UI-SPEC.md— each with state catalog, microcopy table,tokens-used:+tokens-new:lists,DESIGN-DRIFT:flags,INFERRED:markers, and a screenshot grid for 1440 / 768 / 375 × light + dark. tokens-DELTA.mdsynthesized the three specs and returned the headline finding: zerotokens-new, zero brand-defining escalations. The token-only PR that Phase 39 was originally scoped against collapsed to a no-op verification + phase-closure commit.- 13 brand-voice rewrites flagged for Josh's pass-through (e.g. Dashboard stale-goal CTA
Update→Log progress; Meet Coach selection pillSELECTED→PICKED; Onboarding aria-labelSlide {n} of {total}→Step {n} of {total}). Default rule was ship-as-rewritten; the rewrites consolidate in the per-surface UI-SPEC microcopy tables.
Onboarding surface (Phase 40, cd55502d)
WelcomeLayout,SlideWizardLayout, and the five user-facing slides (WelcomeSlide,PersonaSlide,GoalTypeSlide,SourceSlide,DoneSlide) reskinned to the v1.10 visual language.- New step-indicator chrome on
SlideWizardLayout; redesignedWelcomeIntrowith section-preview list (1–3 The goal · 4–5 Your why · 6–10 Your Coach); per-slide token swap;DoneSlidepunch-up. - The v1.8 slide framework (
useOnboardingFlow, slide registry,StoreOnboardingState, validation hooks) is preserved verbatim. Phase 40 is a visual layer only change — no structural rework of the onboarding contract.
Meet Coach surface (Phase 41, 92c501e8)
- Three-column desktop layout (step rail · main · live preview), single-column mobile with a bottom-pinned CTA.
- Six persona cards extracted from
MeetCoach.vueandPersonaSlide.vueinto a standalonecoach/PersonaCard.vue, reused by onboarding'sPersonaSlide. coach/CoachToneSlider.vue,coach/CoachFrequencyChips.vue,coach/CoachPreview.vueextracted fromMeetCoach.vueinline markup as standalone Storybook-shippable components.- The v1.2 Coach contract (18 unique persona/tone preambles, WCAG 2.1 AA, reduced-motion + dark-mode parity) is preserved.
- Screen-reader handoff added on persona change: preview pane
aria-live="polite"with 200 ms debounce.
Dashboard surface (Phase 42, 28977b84)
- Header chrome, four stat tiles, "Today's practice" focus list, week-shape chart, upcoming events list, stale-goal nudge, and a "From the Sage" coach card.
- Three components extracted from
Dashboard.vueinline markup as standalone Storybook entries:dashboard/WeekShapeChart.vue,dashboard/UpcomingEventsList.vue,dashboard/StaleGoalAlert.vue. - Empty / loading / error / mobile / dark / motion-reduced states specified for every new component.
- Microcopy in voice: "Three small things. Pick one to begin." (practice subhead), "You're 4 of 7. Wednesday is your strongest day — keep it light." (week caption).
Storybook library audit (Phase 43, 8c1fd432)
- Every component in
ionic_frontend/src/components/(137 components, 107 story files) classifiedconsistent/needs-update/out-of-scopeagainst the v1.10 visual language across a 6-axis rubric (tokens, surfaces, typography, dark mode, accessibility, brand voice). - Result: 34
consistent, 88needs-update, 15out-of-scope. - Sweep recommendation: 5 family-aligned phases (44 Goal, 45 Communities, 46 Achievements, 47 Modals & Overlays, 48 Chrome) covering the 88
needs-updatecomponents. Orion adopted the recommendation as-is. - Every
out-of-scoperow carries an explicit ship-or-defer rationale: 4 orphans (Phase 44 deletes), 10 streamlined-dashboard sub-tree (v1.11 deferral), 1EmailVerificationBanner(Phase 48 — re-classified at Phase 48 firm-up to DELETE because the file is a 13-line<div v-if="false">no-op stub, not a renderable banner; see audit erratum NIT 5 below).
Goal surfaces sweep + --warning token (Phase 44, f8314227; follow-up acb636e8)
- All 18 Goal-family components reskinned:
src/components/goal/*+ rootGoal*.vue+MilestoneManager.vue. - 4 orphans deleted:
dashboard/DashboardStats.vue,dashboard/WeeklyActivity.vue,dashboard/ActionHub.vue,dashboard/TodaysHabits.vue(8 files including.stories.tssiblings). Audit's "needs-update + consolidation candidate" classifications resolved todeleteafter firm-up grep confirmed zero production consumers. ui/GoalCard.vue(duplicate of rootGoalCard.vue) consolidated and deleted.--warningtoken added totailwind.config.js,tailwind.css, anddocs/brand/brand.md(light:38 92% 50%; dark:38 92% 60%; foreground:--warning-foreground).dashboard/GoalGridCard.vuebg-amber-500→bg-warningmigration onneeds-attentionstate. Cosmetic Dashboard layout pass folded in.- The follow-up PR (
acb636e8) bumped the--warningtoken contrast (m1), added missing dark-mode story variants (m2), and corrected a token-block claim in44-VALIDATION.md(n1).
Mid-flight v1.9 master merge (1d97189d)
- v1.9 Goal Roadmap (PR #357) shipped to master and was merged into the milestone branch via a true
--merge(not squash, topology preserved). Brought 3 net-new components (RoadmapBuilder,RoadmapTimeline,RoadmapProgressBar) into the milestone tree. - Audit re-classification at firm-up: all 3
Roadmap*components areconsistentagainst the v1.10 visual language — they shipped on canonical tokens. Two minor RGB drift findings folded into Phase 47 ride-along.
Communities sweep + 4 orphan deletions (Phase 45, 2083539f)
- 18 Communities-family components reskinned across
communities/,community/(singular), and root-level community surfaces. - 4 orphans deleted:
community/CommunityCard.vue+ spec, rootCommunityFeedItem.vue+ story, rootCommunitySuggestionItem.vue+ story. - Story files added for 6 components missing them:
communities/MyCommunityCard,community/CommunityFeedCard,community/CommunityAbout,community/CommunityFeed,community/CommunityGoals,community/CommunityMembers. - Phase 45 m1 (4 missing
WithCommunit*Contextintegration variants on story files) and n1 (#e5e7ebstory-only inline hex onMemberProfileModal) deferred to Phase 47 ride-along — both surfaces were already inside the modal-sweep scope.
Achievements sweep + --rarity-* token system (Phase 46, 25a6e112)
- 7 visible Achievements-family components reskinned (
AchievementCard,AchievementCelebration,AchievementFilters,AchievementsGrid,AchievementStats,ShowcaseSelector,UserRankCard).AchievementWatcherexcluded as renderless (<span v-if="false" />). --rarity-common,--rarity-rare,--rarity-epic,--rarity-legendarytokens added (each with foreground variant) — anchored to brand canon (--coachfor epic,--goldfor legendary).dashboard/ShowcasedAchievements.vuemigrated from inline rarity hex (#3b82f6,#a855f7,#fcc419/#d97706) to the--rarity-*token surface (closes audit n3 footnote).- Phase 46 R1 fix bundle adjusted three token values to clear AA Normal on the
bg-cardsurface:--rarity-legendary-foregrounddark20%→90%(M1),--rarity-rarelight60%→50%(m2),--rarity-epiclight65%→55%(m3). All 8 contrast pairs cleared AA on first re-measurement post-fix.
Modals & overlays sweep + ride-along bundle (Phase 47, 8216034c)
- 17 modal/overlay components reskinned:
AgreeToTermsModal,BadgeModal,ChangelogModal,StreakDetailsModal,FeedbackDetailModal,NewFeedbackModal,AcceptPartnershipModal,FindPartnerModal,ProfileCompletionModal,RoadmapBuilder,RoadmapTimeline,AchievementToast,AiCoachModal,AiInsightCard,NotificationsPanel,PushPermissionPrompt,ScreenTimeNudge. BadgeModalis the canonical--rarity-*consumer: scoped CSS migrated from--ion-color-mediumand inline rarity hex tohsl(var(--rarity-X) / 0.1)for backgrounds andhsl(var(--rarity-X))(orhsl(var(--rarity-legendary-foreground))for legendary) for text.- Legacy
OnboardingWizard.vue(1,238 LOC modal) and its Storybook story file deleted. Reachability evidence at firm-up confirmed the mount path was reachable only via dev/testing fallback-auth — Phase 33'suseOnboardingGateredirects every first-sign-in user to/welcome/*beforeDashboard.vuemounts.Dashboard.vuedecoupled: removed<OnboardingWizard>mount block,import OnboardingWizard,wizardOpenref,watch(isFirstSignIn, …)block,handleWizardClosed()handler, and the now-unusedisFirstSignIndestructuring fromuseClerkSync(). - Ride-along bundle folded in: 5 Phase 45 story-only updates + 3 v1.9 Roadmap RGB drift NITs + 4 BadgeModal
--ion-color-mediummigrations. - Phase 47 R1 escape hatch fired: BadgeModal pass-2 contrast measurements showed 4 of 8 pairs failing AA Normal on the alpha-tinted-on-
--backgroundsurface (legendary-light 1.46:1 catastrophic, common dark/light + rare light all <4.5). Decisions logged in47-DESIGN-DRIFT.md: Decision A (BadgeModal.rarity-legendarycolor reference change--gold→--rarity-legendary-foreground, no token-value change) + Decision B m4 (--rarity-rarelight50%→45%) + Decision C-1 (BadgeModal.rarity-commonmigrated from--ion-color-medium→--rarity-common) + Decision C-2 m5 (--rarity-commonlight47%→42%). Pass-3 measurement: 8 of 8 pairs cleared AA Normal. Phase 46 cross-impact: 3AchievementCardlight-mode contrast measurements strictly improved; 0 regressions.
Chrome + remaining surfaces sweep (Phase 48, 9e6c5ffa)
- 21 components reskinned across small primitives, charts, feedback surfaces, and
BottomTabBar. SideMenu(859 LOC) fully migrated: legacy--ion-color-*and inline orangergba(251, 146, 60, …)swapped forhsl(var(--card) / 0.6)glass-card chrome withbackdrop-filter: blur(12px),hsl(var(--accent))for accent overlays,hsl(var(--primary))/hsl(var(--muted-foreground))for active/inactive nav state, andfont-displayon labels and group separators. New 6-state Storybook grid (Expanded/Collapsed/MobileOpen× Light/Dark).ui/EmailVerificationBanner.vuedeleted entirely (13-line<div v-if="false">no-op stub, not a renderable banner).Dashboard.vuemount + import removed.supporter/SupporterStreakNudgedismiss button enlarged fromp-1+w-3.5 h-3.5top-2.5+w-5 h-5to clear the 44 × 44 px tap-target floor.- 4 net-new story files:
GlobalErrorBoundary,ImageCropper,StockPhotoPicker,SupporterStreakNudge. - 5-item ride-along bundle from Phase 47:
n2brand.md rarity sync (2 rows mirrored fromtailwind.css),n3.a/btwo stale OnboardingWizard comment cleanups,n3.cCypress real-bug fix (see "Audit-trail wins" below),n4BadgeModal--ion-color-mediummigration partial closure (3 of 9 references; 5 rgba-variant siblings forward-flagged below).
Phases
| Phase | Name | Status | Plans | Highlights |
|---|---|---|---|---|
| 39 | Foundation — Mockup Ingestion + Token Layer | Shipped (61a69503) | 1 | 5 mockups + 30 screenshots + 3 UI-SPECs + tokens-DELTA. Headline: zero tokens-new. |
| 40 | Onboarding (cd55502d) | Shipped | 3 | /welcome route family reskin; v1.8 framework preserved verbatim. |
| 41 | Meet Coach (92c501e8) | Shipped | 3 | Three-column desktop, mobile bottom-pinned CTA; 4 sub-components extracted. |
| 42 | Dashboard (28977b84) | Shipped | 3 | Refreshed composition; 3 inline blocks extracted as Storybook entries. |
| 43 | Storybook Library Audit (8c1fd432) | Shipped | 2 | 137 components classified across 16 families on a 6-axis rubric. |
| 44 | Goal Surfaces + --warning Token (f8314227 + acb636e8) | Shipped | 1 | 18 reskins + 4 orphan deletes + --warning token. |
| 45 | Communities + 4 Orphan Deletes (2083539f) | Shipped | 1 | 18 reskins + 4 deletes + 6 net-new story files. |
| 46 | Achievements + --rarity-* Tokens (25a6e112) | Shipped | 1 | 7 reskins + new token system + R1 token-value calibration. |
| 47 | Modals & Overlays + OnboardingWizard Delete (8216034c) | Shipped | 1 | 17 reskins + 1,238 LOC delete + R1 contrast methodology refinement. |
| 48 | Chrome + Remaining Surfaces + EmailVerificationBanner Cleanup (9e6c5ffa) | Shipped | 1 | 21 reskins + SideMenu (859 LOC) + 1 stub delete + 4 net-new story files. |
| n | Final Documentation + Master-Flip Gate | This phase | 1 | CHANGELOG + this narrative + brand.md polish + ROADMAP renumber + master-flip gate. |
Two micro-tasks rode along as standalone PRs outside the per-phase numbering: m3 TodayActions 40 → 44 px tap-target fix (54cfb49f, between Phases 43 and 44), and m1+m2+n1 --warning follow-up (acb636e8, between Phases 44 and 45).
Key Decisions
- Zero new tokens, zero brand-defining escalations (Phase 39). The five mockups exercise only canonical tokens. Codi's Phase 39 token-only PR collapsed to a no-op closure commit. Every subsequent surface phase was a token-migration phase, not a token-introduction phase.
- Token-conflict policy. New tokens in mockups → propose addition (didn't trigger). Mockup deviates from existing canonical token → existing wins, flag
DESIGN-DRIFT:. Mockup deviates from primary palette / fonts / type scale → escalate to Maggie → Josh (didn't trigger). - Surface-phase order: Onboarding → Meet Coach → Dashboard. Final shipped order differs from the original ROADMAP draft (Dashboard → Onboarding → Meet Coach). Onboarding shipped before Meet Coach so the simpler surface served as the extraction host for
coach/PersonaCard.vue, which both surfaces consume. Dashboard shipped last because it had the most extracted components (3 standalone Storybook entries). The ROADMAP renumber + as-shipped-order narrative reconciliation is the closure step in this docs phase. - 5-phase Storybook sweep, no consolidation (Phase 43 → 44–48). Each family is a coherent sweep; collapsing 47 (modals, 15 components) + 48 (chrome + remaining, ~26 components) would have mixed overlay surfaces with layout primitives and hidden the
--rarity-*token cross-phase dependency (Phase 46 producer → Phase 47 BadgeModal consumer). - Streamlined dashboard sub-tree → defer entirely to v1.11. 10 components, feature-flagged off for ≥85% of users. Definition of done satisfied via documented deferral, not via shipped reskin.
- OnboardingWizard.vue → DELETE in Phase 47. 1,238 LOC legacy modal. Reachability evidence at firm-up: mount path reachable only via dev/testing fallback-auth (which Phase 33
useOnboardingGatedocuments as a no-op). Codi reconfirmed at dispatch via grep before deletion. The MODERNIZE escape hatch (split 47a/47b) didn't fire. - EmailVerificationBanner.vue → DELETE in Phase 48. Storybook audit §8.2 originally classified this as a 13-line renderable banner shipping in Phase 48. Phase 48 firm-up FINDING corrected the audit: the 13 lines are a
<div v-if="false">no-op stub. Reskin would have been pointless; DELETE was the chosen call. SideMenu.vue(859 LOC) folded into Phase 48, not split as 48b. Default fold-in path; the split escape-hatch (effort sum >1500 LOC or structural rework discovered) didn't fire because the migration was pure token-substitution.- Master-flip gate is a separate, post-docs hop. v1.10 ships into
gsd/v1.10-visual-evolution(milestone branch) phase-by-phase; the milestone-branch →mastermerge fires after this final docs phase ships, gated on Josh's visual approval against a preview deploy. Encoded in this document as "Master-flip gate" below; authority4ab6d91d.
Audit-trail wins worth surfacing
Contrast-measurement methodology evolution (Phases 46 → 47 → 48). The 8 BadgeModal contrast pairs tell a three-act story:
- Phase 46 measured rarity contrast on
bg-card(theAchievementCardsurface) and adjusted three token values via R1 (M1 + m2 + m3) to clear AA Normal on first re-measurement. - Phase 47 introduced
BadgeModalas a--rarity-*consumer on a different surface — alpha-tintedhsl(var(--rarity-X) / 0.1)overhsl(var(--background)). Pass-2 measurement found 4 of 8 pairs failing because the BadgeModal surface is slightly more saturated thanbg-card. R1 escape hatch fired again: Decision A swapped a token reference (--gold→--rarity-legendary-foregroundfor legendary text — Codi pass-2 had reached for the brand-canonical token but the canonical token for legendary text is the foreground variant), Decision B m4 darkened--rarity-rarelight another 5pp, Decisions C-1 + C-2 m5 migrated.rarity-commonto the family token and darkened it 5pp. Pass-3 measurement: 8 of 8 cleared.47-DESIGN-DRIFT.mdwas the cleanest audit artifact of the milestone — Roy's Phase 47 review specifically called it out. - Phase 48 re-measured the
AchievementCardcross-impact with refined methodology — alpha-compositing the actual scoped-CSS rarity tint overbg-cardrather than treatingbg-cardas the simplified solid surface. Codi's numbers (common-light 4.95, rare-light 5.14) differ from Roy's Phase 47 numbers (5.65, 5.98) not because of regression but because Codi's compositing math is more accurate. Both methodologies pass AA Normal. No regression; better precision.
Net result: every
--rarity-*consumer surface (BadgeModal alpha-tint-on-background, AchievementCard alpha-tint-on-card, ShowcasedAchievements solid-on-card) now measures ≥4.5:1 AA Normal across light + dark, and the methodology for measuring rarity contrast is documented for future authors.- Phase 46 measured rarity contrast on
R1 escape hatch validated as a milestone-rhythm primitive. Phase 46 set the precedent (token-value adjustment after WCAG re-measurement) and Phase 47 inherited it cleanly. The
46-PLAN.md §T5precedent,47-DESIGN-DRIFT.mddecision log, and Phase 48 R1-blessed token-value adjustments form a consistent pattern: when contrast fails on a measured surface, propose the smallest fix that holds (token reference vs. token value), document predicted cross-impact, re-measure post-fix, log the decision.Phase 47 → 48 ride-along chain. Roy's 4 NITs from Phase 47 (n1 BadgeModal contrast monitor, n2 brand.md mirror, n3.a/b/c stale OnboardingWizard refs, n4 BadgeModal
--ion-color-mediummigrations) all flowed forward to Phase 48 T1 first commit. The ride-along bundle hit before Phase 48's main reskin work started, which kept the Phase 48 main diff clean. This pattern (NITs ride along on the next phase's first commit when scope-aligned) became a milestone-rhythm primitive too.Phase 48 n3.c Cypress real-bug fix. After Phase 47 deleted
OnboardingWizard.vue, the assertioncy.get('ion-modal').should('exist')intests/e2e/dashboard-states.cy.tswas passing spuriously — the test was finding a differention-modalinstance and reporting green. Phase 48 ride-along caught it during then3.ccleanup pass and replaced the assertion withcy.url().should('include', '/welcome/')— which actually exercises the Phase 33useOnboardingGateredirect that supersedes the deleted wizard. A stale assertion surviving a DELETE is a recurring class of bug; documenting the catch here so future DELETEs trigger an assertion audit.Audit-count erratum consolidation (NITs 1–6). Six audit-count NITs accumulated across Phases 44 → 48 in
STORYBOOK-AUDIT.md. Each was a small classification or count drift surfaced by a dispatch-time re-grep or firm-up; none were ship-blockers; all are documented in the per-phase VALIDATION docs and consolidated in the Tech Debt section below.
Brand-voice rewrites that shipped
Per the v1.10 brand-voice contract, every user-facing string in the three mockups passed through a coach-who's-also-a-friend voice check. Mockup copy that violated voice was rewritten in the UI-SPEC microcopy table; the rewrites shipped as the canonical strings (default rule, with a Josh confirmation pass that returned no overrides). Representative rewrites:
- Dashboard stale-goal CTA:
Update→Log progress - Dashboard error state:
We could not load your dashboard…→Connection's spotty. Try once more — your data's fine. - Meet Coach step labels:
Step 1 / Step 2 / Step 3→Pick a voice / Tune the tone / Pick the rhythm - Meet Coach selection pill:
SELECTED→PICKED - Onboarding aria-label:
Slide {n} of {total}→Step {n} of {total}(matches the new STEP/N mental model)
The full microcopy tables live per-surface in the UI-SPECs at .planning/milestones/v1.10/.
Outcomes
- Three live surfaces (Onboarding, Meet Coach, Dashboard) ship the next visual language to production after the master-flip gate clears.
- Every other component family (Goal, Communities, Achievements, Modals & Overlays, Chrome) is reskinned to match.
- Two new tokens (
--warning,--rarity-*) added in service of removing inline hex literals from existing components — neither was a brand evolution. - 10 components deleted entirely (
OnboardingWizard,EmailVerificationBanner, 4 dashboard orphans, 4 community orphans + duplicates) — a cumulative ~2,300 LOC of dead or stub code removed. - 9 net-new Storybook entries (5 from Phase 39/41/42 component extractions + 4 Phase 48 net-new stories) plus 6 community story-coverage gap closures.
- All 8 BadgeModal contrast pairs (4 rarity tiers × 2 modes) measure ≥4.5:1 AA Normal. The
--rarity-*token system is anchored to brand canon and consumed consistently across BadgeModal, AchievementCard, ShowcasedAchievements, AchievementToast, and UserRankCard. - Storybook library is fully classified; the 88
needs-updaterows from the audit are now 0 (everything shipped or formally deferred).
Tech Debt
Forward-flagged items for v1.11 / Phase 49+ — none are ship-blockers for v1.10:
--primarylight-mode active-state contrast. Two surfaces in Phase 48 measure--primary-on---backgroundat light-mode contrast values 0.03–0.15 below AA Normal:SideMenuactive-nav 4.47:1 andBottomTabBaractive-tab 4.35:1. These are pre-existing conditions tied to the design-system--primarytoken (HSL(203, 78%, 41%)), not introduced by Phase 48. The--primaryHSL is identical betweenorigin/gsd/v1.10-visual-evolutionand the Phase 48 squash tip — confirmed via diff inspection. Phase 49+ design-token pass candidate: introduce a--primary-interactive: 203 78% 38%(3 percentage-point darken) to clear AA on active states without disturbing the brand-defining primary blue. Or accept the active-state contrast as a documented design-system limitation and rely on the4.5:1floor on the larger contact points (active-nav text uses 12 px /font-mediumwhich qualifies as Normal under WCAG 2.1).BadgeModal.vuevar(--ion-color-medium-rgb)rgba siblings (5 lines). Phase 48 closed the n4 NIT for the 3 solidvar(--ion-color-medium)references but the 5 rgba-variant siblings (lines 284, 285, 353, 355, 431) — used for alpha overlays on locked-badge dashed border / status-locked bg / quote-text bg — were not in the n4 scope. Translation pattern isrgba(var(--ion-color-medium-rgb), N)→hsl(var(--muted-foreground) / N). Recommend: Phase 49 polish or v1.11 backlog. Trivial fix; not regression-prone.UiTooltipstory-file naming (audit erratum NIT 6). The file is namedui/tooltip/Tooltip.stories.tsrather than the conventionalUiTooltip.stories.ts. Recommend: v1.11 cleanup pass alongside any other story-file naming standardization.Pulse-glow keyframe duplication.
ShowcasedAchievements,AchievementCard, andBadgeModaleach define their own@keyframes pulse-glow. Phase 46 preserved per-component duplication verbatim (modulo rgba-to-CSS-var swap) to avoid scope creep. Recommend: v1.11 backlog cleanup — extract to a shared keyframe declaration intailwind.cssor a shared utilities file. Cosmetic; not regression-prone.AllyActivityFeed.vueprop extraction (Codi follow-up from Phase 45). Refactor, not visual. Recommend: v1.11 backlog.GoalGridCard.vuemulti-color theming (Phase 44 §12.1). Blocked by Phase 44's zero-touch ongoal-color-*semantics. Recommend: v1.11 backlog.2 Phase 40 ride-along NITs. Dead
slideNextprovider onWelcomeView.vue(orchestrator), missing emit-forwarding test onSlideWizardLayout(test parity). Out of audit scope (src/views/, notsrc/components/). Recommend: v1.11 backlog or fold into a dedicated test-coverage hop.3 Phase 42 v1.11 deferrals. Richer
WeekShapeChartpercent computation (currently binary 0/100% per day); multi-stale-goal+N morepill onStaleGoalAlert; richer Streamlined sub-tree reskin (when the streamlined dashboard family ships). Recommend: v1.11 backlog.Streamlined dashboard sub-tree (10 components). Documented v1.11 deferral per audit §8.1 + Phase 43 ROADMAP entry.
7 moderate Dependabot vulnerabilities on
master. Carried from Phase 47 §10. Recommend: Riley triage track when queue is quiet — separate from v1.10 docs.
Audit-count errata (NITs 1–6)
STORYBOOK-AUDIT.md accumulated six small classification or count drifts across Phases 44 → 48. None affect §4 component-by-component tables (those remain authoritative). Documented here so the audit history is honest:
- NIT 1 (Phase 44, audit cosmetic). TL;DR
needs-update: 88vs. validation appendix90/90. The §4 tables are authoritative; the TL;DR count rolls forward as 88 (post-orphan-delete + post-TodayActions-upgrade). - NIT 2 (Phase 44, audit cosmetic). §2 family-count subheadings sum to 136 vs. claimed 137.
findconfirms 137 components; the 1-component delta is a subheading-rollup miscount. §4 tables are authoritative. - NIT 3 (Phase 45, audit re-classification). 4 Communities components classified
needs-update + consolidation candidateresolved todeleteafter firm-up grep confirmed zero production consumers. - NIT 4 (Phase 47, audit cosmetic).
OnboardingWizard.vuerows in §2.11 + §4.7 reference the same file but were category-summed twice. The DELETE call applies once. - NIT 5 (Phase 48 firm-up FINDING).
STORYBOOK-AUDIT.md §8.2EmailVerificationBannerrecommendation ("ship in Phase 48 as a 13-line banner") corrected — the 13 lines are a<div v-if="false">no-op stub, not a renderable banner. DELETE was the chosen call. - NIT 6 (Phase 48 firm-up FINDING).
STORYBOOK-AUDIT.md §4.9ui/tooltip/UiTooltiprow implicitly assumed conventionalUiTooltip.stories.tsnaming; actual story file isui/tooltip/Tooltip.stories.ts(non-conventional). Rename in v1.11 cleanup pass per §"Tech Debt" above.
Master-flip gate
Authority: Josh decision 4ab6d91d — the v1.10 milestone branch must NOT merge to master until a preview-deploy URL is built from the post-docs squash tip and Josh comments "approved" against the gate-coordination thread on OBJ-43. The visual-approval gate is brand-defining; agents do not auto-promote.
Operator: Vicki — dispatched by Maggie after this final docs phase squash-merges into gsd/v1.10-visual-evolution.
Signer: Josh — visual approval required against the preview deploy.
Pre-flight checklist (Vicki executes before pinging Josh):
- Preview deploy. Build a preview deploy from the post-docs squash tip (the new
gsd/v1.10-visual-evolutionHEAD after this final docs PR merges). Capture the URL with its 7-day TTL. - Viewport screenshot grid. 1440 × 768 × 375 px × Light + Dark for every shipped surface:
- Onboarding (
/welcomeroute family — all 5 slides + chrome) - Meet Coach (desktop three-column, mobile single-column with bottom-pinned CTA)
- Dashboard (header, stat tiles, focus list, week chart, upcoming events, stale-goal nudge, coach card)
- Goal surfaces (Phase 44 — Goal page, Goal forms, Goal events)
- Communities (Phase 45 — list, detail, members, feed, posts)
- Achievements (Phase 46 — grid, card, celebration, filters, showcase, user rank)
- Modals & overlays (Phase 47 — BadgeModal across all 4 rarity tiers + locked, AcceptPartnershipModal, FindPartnerModal, ChangelogModal, FeedbackDetailModal, NotificationsPanel, AchievementToast)
- Chrome (Phase 48 — SideMenu Expanded/Collapsed/MobileOpen, BottomTabBar, MoodCheckIn, ActionAlert)
- Onboarding (
- Regression-check zero-touch zones. Verify the v1.2 Coach contract (18 persona/tone preambles untouched), Phase 4 PartnerWidget (zero-touch), Phase 36 GettingStartedCard (zero-touch), Phase 33
/welcomeframework (zero-touch in Phase 47/48 — distinct fromOnboardingWizard.vuedeletion), v1.9 Roadmap zone (only the 3 RGB drift NIT lines touched in Phase 47 ride-along), Streamlined sub-tree (zero-touch — deferred to v1.11). Hard guardrails per48-VALIDATION.md §8already verified at Phase 48 ship; this is the sanity recheck before Josh ping. - CI status. Confirm 5/5 CI checks green at the post-docs squash tip.
- Ping Josh on OBJ-43 with: preview URL + 7-day TTL note + screenshot grid + checklist + explicit
[@Josh](mention://member/4faa60b9-6d5c-42ec-afe3-034c96f65108)ping. Hold the merge until Josh commentsapproved. No timeout, no auto-promote.
On approval:
- Squash-merge
gsd/v1.10-visual-evolution → master. Use the conventional v1.10 commit-message shape (feat(v1.10): visual evolution — three live surfaces + Storybook library sweep + ChangelogModal narrative + master-flip ceremony). - Tag the release. v1.10 maps to a SemVer minor bump. Per Riley's tag policy + the plan's reference to
v3.7.0, the expected tag isv3.7.0. Riley confirms the exact tag at master-flip time. - Production deploy. Triggered by the version tag per the standard release pipeline. Watch Sentry for ~24 h post-deploy; rollback path is
rollback <prior-tag>or the emergency Cloud Run revision switch (API only, n/a for this milestone). - GitHub Release. Auto-created after smoke tests; release body cites this milestone narrative and the CHANGELOG section.
- Delete
gsd/v1.10-visual-evolutionremote branch post-merge. - Comment on OBJ-43 confirming master-flip + tag + deploy. Close the issue when the smoke gate passes.
Rollback plan:
- Pre-tag:
git revert <squash-sha>againstmaster. Clean revert because v1.10 is purely visual + token migrations; no DB / state coupling. - Post-tag:
rollback <prior-tag>re-deploys the previous release; the v1.10 tag stays on the version index for forensic reference. - No phase-specific rollback is needed since v1.10 is one squash merge into master, not a sequence.
Requirements Coverage
v1.10 was a visual-evolution milestone, not a requirements-driven feature milestone — the equivalent of "requirements" is the definition of done in .planning/milestones/v1.10-ROADMAP.md. All 8 must-be-true conditions hold at this final docs phase:
| Condition | Status |
|---|---|
| Three live surfaces (Onboarding, Meet Coach, Dashboard) shipped | ✅ Phases 40–42 |
| Storybook library audit published; every component classified | ✅ Phase 43 + audit erratum NITs 1–6 documented |
Every needs-update component shipped OR explicitly deferred | ✅ Phases 44–48 + Streamlined v1.11 deferral |
tailwind.config.js and docs/brand/brand.md reflect new tokens | ✅ Phase 39 zero-delta + --warning (Phase 44) + --rarity-* (Phase 46) |
Milestone narrative published at docs/milestones/v1.10-visual-evolution.md | ✅ This document |
CHANGELOG entry + in-app ChangelogModal.vue copy live | ✅ This phase (CHANGELOG); modal auto-renders via ?raw import |
No outstanding DESIGN-DRIFT: findings | ✅ All m-prefix and n-prefix findings closed or forward-flagged |
| ROADMAP shows all phases marked complete with ship dates | ✅ This phase |
Related Artifacts
- Roadmap: .planning/milestones/v1.10-ROADMAP.md
- UI-SPECs:
dashboard-UI-SPEC.md,onboarding-UI-SPEC.md,meet-coach-UI-SPEC.md - Storybook audit:
STORYBOOK-AUDIT.md - Tokens delta:
tokens-DELTA.md - Phase 47 design-drift log:
47-DESIGN-DRIFT.md - Per-phase plans + validations:
.planning/milestones/v1.10/ - Source issue: OBJ-43
- Mockups (originals):
.planning/milestones/v1.10/mockups/
Related Commits / PRs
| Phase | Commit / PR | Description |
|---|---|---|
| Open | ae233123 | Open visual evolution milestone |
| 39 | 1a6b581c + 61a69503 | Foundation — UI-SPECs + tokens-DELTA + closure note |
| 40 (Onboarding) | cd55502d | Onboarding visual evolution |
| 41 (Meet Coach) | 92c501e8 | Meet Coach visual evolution |
| 42 (Dashboard) | 28977b84 (PR #362) | Dashboard visual evolution |
| 43 | 8c1fd432 (PR #363) | Storybook library audit |
| m3 | 54cfb49f (PR #364) | TodayActions tap-target fix (40 → 44 px) |
| 44 | f8314227 (PR #365) | Goal surfaces + --warning token |
| 44 follow-up | acb636e8 (PR #366) | --warning contrast bump + dark stories + doc fix |
| v1.9-merge | 1d97189d (PR #367) | v1.9 Goal Roadmaps merge into milestone branch |
| 45 | 2083539f (PR #368) | Communities + 4 orphan deletes |
| 46 | 25a6e112 (PR #369) | Achievements + --rarity-* tokens |
| 47 | 8216034c (PR #370) | Modals & overlays + ride-along + OnboardingWizard delete |
| 48 | 9e6c5ffa (PR #371) | Chrome + remaining + EmailVerificationBanner delete + Phase 47 ride-along |
| Final docs | This phase | CHANGELOG + this narrative + brand.md polish + ROADMAP renumber + master-flip gate |
Last updated: 2026-05-22