UX Phase D — Professional-Side Surfaces Polish
UX Phase D — Professional-Side Surfaces Polish
Section titled “UX Phase D — Professional-Side Surfaces Polish”Date: 2026-04-20 Status: Draft Scope: Full pro-side polish to Airbnb/Linear-tier — dashboard, calendar, requests, earnings, credentials (self + admin), onboarding wizard (7 steps + welcome + complete) Phase mapping: Phase D (stretch) of UX overhaul — follows Phase A (hero) + Phase C (consumer tabs) + Phase B (SOS live) Related specs:
plans/ideony-ux-overhaul-plan.md(master)plans/specs/2026-04-19-ux-phase-a-design.md(consumer hero flow)plans/specs/2026-04-19-pro-onboarding-design.md(onboarding logic + gating)plans/specs/2026-04-19-pro-credentials-design.md(credential pipeline + trust score).impeccable.md(brand/bans)
Executive Summary
Section titled “Executive Summary”Phase D brings every professional-facing screen up to the same Airbnb-warm + Linear-precise bar established in consumer flows (Phase A/C). Pros currently get a functional surface with inconsistent typography (mixed StyleSheet + NativeWind, two sibling header styles), no motion language differentiation from consumer, underpowered empty/error states, and a dashboard that reads as a metrics dump rather than an operator’s cockpit. Phase D rebuilds these surfaces around a pro-specific motion language (calmer, denser, data-forward), consistent Gambarino/Switzer treatment, first-class trust-tier visuals, and a real earnings surface with chart + payout transparency.
User Value — Why Pros Deserve Polish
Section titled “User Value — Why Pros Deserve Polish”- Retention: pros switch apps faster than consumers (they work daily in them). A dashboard that respects their time keeps them open between jobs instead of flipping to WhatsApp.
- Trust: Italian tradespeople are skeptical of “tech bro” tools. Warm, grounded typography + Italian editorial density signals “built for you, not Silicon Valley.”
- Activation: current completion rate of 7-step onboarding is the single biggest pro-funnel leak. Each polish point on onboarding directly converts signups to active pros who can accept bookings.
- Commercial upside: pros with polished dashboards recommend the platform to peers — referral channel Ideony cannot buy.
- Operational accuracy: a calendar that feels trustworthy → pros keep availability up-to-date → fewer missed jobs → fewer consumer complaints.
Screen Catalog — Current State + Gap List
Section titled “Screen Catalog — Current State + Gap List”Scale 1–5 (1 = raw/functional, 5 = Airbnb-tier polished). Reference: .impeccable.md.
Tabs (4)
Section titled “Tabs (4)”(professional)/dashboard.tsx — Current: 3/5
Section titled “(professional)/dashboard.tsx — Current: 3/5”Strengths: FadeInDown stagger on stat cards; online toggle with haptics (Light on press, Success/Warning on result); avatar with online indicator; shadows.sm from design tokens. Gaps:
- Stat grid reads as “big number + small label hero metric” template — hard-ban per impeccable. Must redesign as a cockpit strip or activity timeline.
- Title uses Switzer Bold at 22 for name but no Gambarino headline — loses Italian editorial voice for a primary surface.
- “Quick actions” section = two identical primary-subtle tiles, feels placeholder.
- No trust-tier surface anywhere — pros can’t see their standing at a glance.
- Empty state for “today bookings” = generic grey pill. No illustration, no forward motion.
- No dark mode awareness (
bg-neutral-50hardcoded). - StyleSheet remnants: none — NativeWind ✓. Target: 5/5 — operator-cockpit layout with Gambarino day-greeting, activity ribbon, trust tier card, calendar-slice preview, jobs-queue peek, earnings ticker.
(professional)/requests.tsx — Current: 3/5
Section titled “(professional)/requests.tsx — Current: 3/5”Strengths: FadeInDown staggered cards; accept/decline with confirmation Alert + Warning/Success haptics; skeleton loaders; error retry state; refresh control. Gaps:
- Uses inline Alert.alert for accept/decline — feels native-OS, not on-brand. Replace with in-screen bottom sheet confirmation with job preview + price reminder.
- Count badge
bg-accent-500w/ raw numeral alongside the Switzer-Bold title — composition reads as decoration, not info. - Card layout: category · description · address · €price · buttons — no time-since-received, no urgency ranking, no distance indicator. Pros need “how fresh is this?” at a glance.
- Mixes
className+style={{ fontFamily }}— sign NativeWind font stack not wired into tailwind config as utilities. - No dark mode. Target: 5/5 — freshness-ranked cards with countdown-to-stale pill, distance chip, consumer trust signals (prior-customer flag), swipe-to-accept gesture option.
(professional)/calendar.tsx — Current: 2.5/5
Section titled “(professional)/calendar.tsx — Current: 2.5/5”Strengths: react-native-calendars themed with Sole tokens; marked dates distinguish recurring (primary) vs specific (accent); AvailabilityEditor modal for slot edits.
Gaps:
- Hardcoded
bg-[#FAF6EE]hex instead ofcolors.backgroundorbg-backgroundtoken utility — token leak. react-native-calendarsis a heavy, non-Reanimated library with limited theming — check if it fights NativeWind/dark mode. Flagged as candidate for swap.- Title is Switzer-Bold 28 — should be Gambarino per hero-screen convention.
- Two empty states layered (one in the non-id branch, one under the calendar) — confusing UX.
- No haptic on day-select.
- No week/month toggle, no “today” quick-jump, no booked-slot preview on tap. Target: 4.5/5 — custom Reanimated calendar OR tightly-themed alt library, Gambarino month header, animated day selection, booking preview drawer.
(professional)/earnings.tsx — Current: 2/5 (worst offender)
Section titled “(professional)/earnings.tsx — Current: 2/5 (worst offender)”Strengths: Memoized totals; skeleton list; refresh control; EmptyState component; animated list items. Gaps:
- Uses
StyleSheet.createentirely — Phase A convention breach (should be NativeWind like other tabs). - Summary card is
bg: colors.primary(solid terracotta) withcolor: "#FFFFFF"— pure white banned per impeccable. - “big number + small label” summary card = the exact hero-metric template banned.
- No chart, no payout schedule, no pending/cleared split, no category breakdown. For a pro this is the single-most-consulted screen after dashboard.
- Single-row transaction list with no grouping (by month, by category).
- No skeleton alignment with final layout (skeleton list vs final grouped list visual mismatch).
- No privacy toggle (sensitive amounts in public situations).
- No dark mode. Target: 5/5 — full earnings studio with monthly-trend chart, payout timeline, pending/cleared split, category breakdown, exportable CSV, privacy-blur gesture.
Stack Surfaces (2)
Section titled “Stack Surfaces (2)”(professional)/credentials.tsx — Current: 3.5/5
Section titled “(professional)/credentials.tsx — Current: 3.5/5”Strengths: Trust tier badge surface; upload progress banner with cancel; FAB pattern; FadeInDown stagger; Gambarino title; proper Switzer stack; i18n throughout. Gaps:
bghardcoded viacolors.backgroundinline style — not via Tailwindbg-backgroundutility, inconsistent with dashboard NativeWind approach.- FAB uses
#FAF6EEhex inline for button text — token leak. - No animation on trust score change when a credential gets approved mid-session.
- Upload progress banner position competes with tab bar — needs safe-area awareness.
- No visual ladder from BASIC → VERIFIED → ELITE showing what’s needed next.
- Rate-limit feedback is missing (“you’ve used 8/10 uploads today”). Target: 5/5 — ladder progression card, animated trust-score counter on approval event, tier-up celebration moment.
(admin)/credentials.tsx — Current: 3/5
Section titled “(admin)/credentials.tsx — Current: 3/5”Strengths: Gambarino header; FadeInDown list; refresh control; review sheet; proper role-gating via hook. Gaps:
- Pure
StyleSheetinline — no NativeWind. - Queue row is a flat list — no filters (by type, by age, by pro trust tier).
- No keyboard shortcuts (J/K next/prev, A approve, R reject) even though admin is power user.
- No batch actions.
- No SLA indicator (“24-48h target, this one: 37h in queue — red flag”).
- Approve/Reject live inside a sheet — no side-by-side doc + metadata.
- Pro context missing — who submitted, their current trust tier, their completion history. Target: 5/5 — filter chips, SLA-colored rows, keyboard-first interactions, pro-context sidebar, batch tools.
Onboarding Wizard (9 screens)
Section titled “Onboarding Wizard (9 screens)”onboarding/_layout.tsx — Current: 4/5
Section titled “onboarding/_layout.tsx — Current: 4/5”Strengths: Progress bar, step counter, back affordance, consistent safe-area, slide-right Stack animation.
Gaps: Progress bar is static fill — no spring/interpolation when step advances. No skip-to-step affordance for resume users. Header background = colors.background but with a hard border-b — slightly abrupt; consider subtle surface-elevated shelf.
onboarding/index.tsx (welcome) — Current: 4/5
Section titled “onboarding/index.tsx (welcome) — Current: 4/5”Strengths: Gambarino 32 title, duotone Briefcase icon, bullet-list highlights card, resume vs start branching. Gaps: Welcome hero has no imagery / illustration — a photograph or custom illustration per impeccable imagery strategy would elevate. No “how long this takes” badge (“~15 min”).
onboarding/profile.tsx — Current: 4/5
Section titled “onboarding/profile.tsx — Current: 4/5”Strengths: Clean form layout, chips for languages, bio + years + languages validation inline. Gaps: No character counter on bio (1000 limit invisible). No autosave — if pro backs out mid-typing, input lost. No “show me an example bio” tooltip. Error surface is a plain red text line — should be inline w/ the field.
onboarding/area.tsx — Current: 4/5
Section titled “onboarding/area.tsx — Current: 4/5”Strengths: Debounced Mapbox autocomplete, radius stepper with +/- buttons, loading spinner in input. Gaps: No map preview — pros select a city + radius but never see their service area on a map. Critical gap: the core UI affordance promised by the spec. Radius stepper is five-step increments — feels coarse vs a slider with snap.
onboarding/stripe.tsx — Current: 4/5
Section titled “onboarding/stripe.tsx — Current: 4/5”Strengths: Clear card-within-screen, benefits list, external-browser handoff with refetchStatus on return, ArrowSquareOut icon signals external. Gaps: No “you’ll be back in ~2 min” reassurance. No security badge (“Stripe, livello PCI-DSS”) though it’s mentioned in subtitle. No handling for “partial return” (user bounced without completing on Stripe side — needs explicit resume CTA).
onboarding/identity.tsx — Current: 3.5/5
Section titled “onboarding/identity.tsx — Current: 3.5/5”Strengths: IdentificationCard duotone, secondary-subtle skip notice, verify + skip dual CTA.
Gaps: The actual Stripe Identity sheet is not wired — startIdentity just advances the flow. Phase D must finish the wire-up to @stripe/stripe-react-native Identity sheet. Skip CTA is too prominent — moves pro to BASIC tier without warning about search-ranking consequence.
onboarding/credentials.tsx — Current: 3.5/5
Section titled “onboarding/credentials.tsx — Current: 3.5/5”Strengths: Reuses CredentialCard; AddCredentialSheet integration; smart CTA text (skip vs next). Gaps: No trust-score preview (“adding P_IVA raises you from 20 → 50”). Empty state is a grey dashed box — should illustrate the payoff (illustration of badges).
onboarding/pricing.tsx — Current: 3.5/5
Section titled “onboarding/pricing.tsx — Current: 3.5/5”Strengths: Category chips (8), model toggle (3), min/max price inputs with € prefix, description.
Gaps: Only one category can be priced in this screen — pro is routed to portfolio after a single submit. Pros offering multiple categories need a list view w/ add-another affordance. Price field shows 25/80 placeholder but no unit hint (”€/h” vs ”€ fixed”). Model toggle is 3 equal pills — fixed-vs-hourly are the two main choices and should be visually dominant, quote-on-request secondary.
onboarding/portfolio.tsx — Current: 4/5
Section titled “onboarding/portfolio.tsx — Current: 4/5”Strengths: 3-column grid, delete affordance, permission handling, empty dashed box w/ ImageSquare, MIN_TO_PUBLISH gate, MAX_IMAGES cap.
Gaps: No reorder (drag-to-reorder — pros have a hero image, matters). No caption entry (spec’s PortfolioImage.caption unused in UI). No category tagging per image. Count indicator (“2 of 10”) is Switzer-Regular tertiary — should be more prominent + color-shift when approaching min (3 to publish).
onboarding/complete.tsx — Current: 4.5/5
Section titled “onboarding/complete.tsx — Current: 4.5/5”Strengths: CheckCircle duotone, Gambarino celebration copy, Sparkle accent, trust card with score + tier, next-step bullets, go-live CTA. Gaps: No confetti or Lottie moment of delight (spec’s “one moment of delight per flow” unfulfilled here — this is the natural spot). Trust score is static — should count up from 0 to actual value with easing.
Summary scores
Section titled “Summary scores”| Surface | Current | Target |
|---|---|---|
| dashboard | 3 | 5 |
| requests | 3 | 5 |
| calendar | 2.5 | 4.5 |
| earnings | 2 | 5 |
| credentials (pro) | 3.5 | 5 |
| credentials (admin) | 3 | 5 |
| onboarding/_layout | 4 | 4.5 |
| onboarding/index | 4 | 4.5 |
| onboarding/profile | 4 | 4.5 |
| onboarding/area | 4 | 5 |
| onboarding/stripe | 4 | 4.5 |
| onboarding/identity | 3.5 | 5 |
| onboarding/credentials | 3.5 | 4.5 |
| onboarding/pricing | 3.5 | 4.5 |
| onboarding/portfolio | 4 | 4.5 |
| onboarding/complete | 4.5 | 5 |
Key Journeys to Polish
Section titled “Key Journeys to Polish”J1 — Morning check-in: Dashboard → Earnings → Availability
Section titled “J1 — Morning check-in: Dashboard → Earnings → Availability”Pro opens app, sees last-24h activity + today’s bookings + pending payout + calendar slice. Taps earnings tile → full earnings studio. Back → taps calendar → adjusts this afternoon’s availability. Total: 3 taps, <10 seconds, zero friction.
J2 — Onboarding wizard (15-min target)
Section titled “J2 — Onboarding wizard (15-min target)”Welcome → Profile → Area → Stripe (external) → Identity (Stripe sheet) → Credentials (skippable) → Pricing → Portfolio → Complete w/ confetti. Each step has an “autosave on blur” safety net + visible progress + correct resume behavior.
J3 — Request-to-accept flow
Section titled “J3 — Request-to-accept flow”Push notification arrives → deep-link to requests tab → top card has freshness badge + distance + fixed/hourly price → swipe-right to accept → confirmation sheet with job details + consumer name + address → confirm → card animates out + success haptic + booking ribbon appears on dashboard.
J4 — Credential upload → approval → trust-tier-up
Section titled “J4 — Credential upload → approval → trust-tier-up”Credentials screen → Add → picker → upload progress (with cancel) → Pending state with “Review in 24-48h” → push arrives on approval → opens to credentials screen → score counts up + tier badge transitions with haptic Success + brief Sparkle animation → if crossed a tier threshold, modal “You’re now VERIFIED. Your rank in search improves immediately.”
Pro-Specific Motion Language
Section titled “Pro-Specific Motion Language”Different from consumer? — Yes. Consumer motion is romantic (staggered reveals, parallax hero photos, warm fades). Pro motion is operational:
| Axis | Consumer | Pro |
|---|---|---|
| Entry | 400ms spring stagger | 250ms ease-out, lighter delay (40ms vs 80ms) |
| Hero | Parallax photo on scroll | Static cockpit — content density over scenic reveal |
| Feedback | Warm (heart flutter, scale bounce) | Tactile (short haptic, quick color flash, no scale) |
| Empty states | Illustrated, generous whitespace | Smaller illustration, denser instruction |
| Success | Confetti, full-screen celebration | Checkmark pulse + ribbon banner, stays on-task |
| Scroll | Elastic/bouncy | Damped, precise |
Implementation: share @/lib/motion/pro.ts with pro-specific presets — proEnter, proStagger, proSuccessPulse, proTap. Consumer keeps existing Reanimated defaults.
Pro-Specific Empty/Error Catalog
Section titled “Pro-Specific Empty/Error Catalog”| Surface | State | Copy (IT) | Illustration | Action |
|---|---|---|---|---|
| Dashboard | No bookings today | ”Oggi nessun appuntamento. Buona occasione per aggiornare il profilo.” | Calendar + sun illustration | CTA: Update profile |
| Requests | No pending requests | ”Nessuna richiesta al momento. Ti avviseremo appena arriva.” | Mailbox illustration | CTA: Check availability |
| Requests | Network error | ”Connessione interrotta. Riprova.” | Disconnected icon | Retry button |
| Calendar | No availability set | ”Imposta la tua disponibilità per iniziare a ricevere richieste.” | Week-grid illustration | CTA: Add first slot |
| Calendar | All week booked | ”Settimana piena. Buon lavoro!” (positive framing) | Checkmark streak | CTA: View next week |
| Earnings | No history | ”I tuoi guadagni appariranno qui dopo il primo lavoro.” | Empty wallet illustration | CTA: Complete onboarding if not done |
| Earnings | This-month zero but history exists | ”Ancora nessun guadagno questo mese.” + trendline of prior months | Small sparkline | — |
| Credentials | None uploaded | ”Carica la tua prima certificazione per salire di livello.” | Badge stack illustration | CTA: Add credential |
| Credentials | Pending review | ”In revisione · Ti avviseremo in 24-48h.” + estimated completion chip | Pending badge spinner | — |
| Credentials | Rejected | ”Documento non approvato. Vedi motivo →“ | Warning badge | CTA: View reason + re-upload |
| Admin queue | Empty | ”Coda vuota. Niente da revisionare.” | Empty inbox | — |
| Onboarding resume | Partial progress | ”Hai completato 4 di 7 passi. Riprendi da dove eri.” | Stepper illustration | CTA: Resume |
All empty-state illustrations: hybrid imagery strategy → source Humaaans-customized for pro characters + custom Italian-palette vector drops, OR defer to illustrator engagement (open decision — see Phase A plan).
Trust Tier Visual Treatment
Section titled “Trust Tier Visual Treatment”Badge shapes
Section titled “Badge shapes”- BASIC (0–30): subtle surface —
bg: colors.surface,border: colors.border, icon:Userduotone olive. NO prominent badge in results. “In costruzione” sub-label permitted. - VERIFIED (31–70): solid olive pill
bg: #6E7F3C+ cream#FAF6EEtext +ShieldCheckweight=“fill” icon. The Sole trust color anchored. - ELITE (71+): solid terracotta pill
bg: #B35F3B+ cream text +Starweight=“fill” icon (gold strokeWidth 0.5). No gradient — composition relies on icon + texture, not color-gradient text or multi-stop fill (bans respected).
Placement
Section titled “Placement”- Dashboard: small tier badge in header area next to name + avatar — always visible, low prominence.
- Credentials tab: large tier badge w/ score — heroic placement.
- Pro profile (consumer side): tier badge in header (already designed in Phase A).
- Results cards (consumer side): tier badge in corner (already designed in Phase A).
- Onboarding complete: tier badge in trust card — already present, polish moment of delight.
Tier-up moment
Section titled “Tier-up moment”On server notification that trust score crossed a tier boundary (WebSocket or push-then-open):
- Haptic:
Haptics.notificationAsync(Success). - Score counter animates from old to new (Reanimated, 800ms ease-out).
- Badge swaps via crossfade (200ms) + pulse scale 1.0 → 1.08 → 1.0 (400ms spring).
- One-time modal: “Sei ora VERIFICATO. La tua posizione nei risultati migliora subito.”
- Analytics event
pro.tier_upwith old + new tier.
Ladder card on credentials screen always visible — shows score progress + next tier threshold + which credential type would advance fastest (using trust-score formula from credentials spec). This is the self-service growth loop.
Earnings Screen Spec
Section titled “Earnings Screen Spec”Chart library choice: victory-native v41 (Skia-backed, Reanimated-compatible, tree-shakeable) vs react-native-gifted-charts vs react-native-svg-charts.
Recommendation: victory-native — Skia-backed renderer is a step-change for mobile perf + looks-right on iOS + Android + Web. Handles Reanimated gesture-driven interactions natively. Accepts custom palette (Sole). Tree-shakeable. ~250KB gzipped for what we need (bar + line).
Fallback: react-native-gifted-charts if victory-native has Expo Web issues — pure-JS, slightly less polished but universally compatible.
Layout:
┌─────────────────────────────────────────┐│ Guadagni [privacy 👁] │ header├─────────────────────────────────────────┤│ ││ €2.347,50 │ Gambarino 42, terracotta│ Questo mese │ Switzer-Regular 14 secondary│ ││ ↗ +18% vs mese scorso │ Switzer-Medium 13 success│ ││ [sparkline: 30 days, interactive] │ Skia chart│ │├─────────────────────────────────────────┤│ Prossimo pagamento ││ ┌─────────────────────────────────────┐ ││ │ €1.230,00 → venerdì 24 │ │ payout card│ │ Saldo Stripe │ ││ └─────────────────────────────────────┘ │├─────────────────────────────────────────┤│ Per categoria ││ Idraulica ████████████ €1.450 │ horizontal bar│ Elettrica ██████ € 650 ││ Caldaie ██ € 247 │├─────────────────────────────────────────┤│ Storico [csv export] ││ [grouped transactions by month] │└─────────────────────────────────────────┘Privacy toggle: eye icon top-right. On tap: numbers replace with dots (•••• €) in all amount surfaces for 30s session (resettable). For quick public-space checks.
Payout timing UX: read Stripe::Payout API via BE proxy (new route GET /professionals/me/payouts/next). Show:
- Amount ready to pay out
- Expected arrival date (from Stripe payout schedule, typically T+2 for EU)
- “On hold” amount separately (disputed, in-process refunds)
- Stripe-deep-link “Vedi dettagli su Stripe” for authoritative view
Privacy considerations:
- Amounts never in push notification body (only generic “Nuovo pagamento in arrivo”).
- Privacy toggle must not persist across sessions (always visible fresh on app open).
- Screenshots: flag
FLAG_SECUREon Android for the earnings screen (prevents screenshot in some contexts + suppresses from recent-apps preview). - iOS equivalent: hide content when app backgrounds via existing ExpoSecureStore pattern, or manual
AppStatelistener + overlay.
CSV export: server-side generation (GET /professionals/me/earnings/export.csv date-range param) — leverages existing booking records. Share via system share sheet.
Milestones
Section titled “Milestones”Each milestone ships as a standalone PR, 1–3 days each, dependency-ordered.
M-D1: Token unification + pro-motion library (2 days)
Section titled “M-D1: Token unification + pro-motion library (2 days)”- Replace remaining StyleSheet usage in
earnings.tsxwith NativeWind + design tokens - Replace hex-literal backgrounds with token utilities (
bg-[#FAF6EE]→bg-background) - Wire Switzer/Gambarino into
tailwind.config.jsas font utilities (no more inlinefontFamilystyle) - Create
@/lib/motion/pro.tswithproEnter,proStagger,proSuccessPulse,proTappresets - Depends on: —
- Risk: low
- Unblocks: all downstream pro milestones
M-D2: Dashboard cockpit redesign (3 days)
Section titled “M-D2: Dashboard cockpit redesign (3 days)”- Replace stat grid with activity ribbon + earnings ticker + trust tier card + today preview + upcoming-week strip
- Gambarino day-greeting headline (“Buongiorno, Marco”)
- Integrate pro-motion library for entry staggers
- Dark mode awareness
- Depends on: M-D1
- Risk: medium — cockpit density requires iteration
M-D3: Earnings studio (3 days)
Section titled “M-D3: Earnings studio (3 days)”- Install
victory-native+ Skia - Implement layout above (sparkline, category bars, payout card, transaction history)
- Privacy toggle
- CSV export endpoint + client integration
- New BE route
GET /professionals/me/payouts/next - Depends on: M-D1
- Risk: medium — chart lib integration + Skia Expo Web compat
M-D4: Requests list redesign (2 days)
Section titled “M-D4: Requests list redesign (2 days)”- Freshness pill (time-since-received, red after 30min pending)
- Distance chip
- Swipe-to-accept gesture (react-native-gesture-handler)
- In-screen bottom sheet confirmation replacing native Alert
- Pro-motion entry
- Depends on: M-D1
- Risk: low
M-D5: Calendar polish (2 days)
Section titled “M-D5: Calendar polish (2 days)”- Evaluate: keep
react-native-calendarsthemed deeper OR swap for Reanimated custom calendar - Gambarino month header
- Haptic on day-select
- Booking-preview drawer on day tap (shows that day’s bookings + availability slots)
- Single coherent empty state
- Depends on: M-D1
- Risk: medium — calendar library decision has scope impact
M-D6: Credentials screen + tier ladder (2 days)
Section titled “M-D6: Credentials screen + tier ladder (2 days)”- Ladder progression card (BASIC → VERIFIED → ELITE with next-step hint)
- Animated trust score counter
- Tier-up celebration moment (haptic + crossfade + scale pulse + modal)
- Rate-limit feedback surface
- Safe-area-aware upload progress banner
- Depends on: M-D1, trust-tier-up WebSocket or push event (BE work)
- Risk: medium — requires BE event wiring
M-D7: Admin queue redesign (2 days)
Section titled “M-D7: Admin queue redesign (2 days)”- Filter chips (type, age, pro-tier)
- SLA-colored rows (green <24h, yellow 24–48h, red >48h)
- Keyboard shortcuts (J/K/A/R)
- Pro-context sidebar (pro completion history + current tier + prior approvals/rejections)
- Side-by-side doc + metadata layout (tablet-optimized, collapses on phone)
- Batch approve/reject
- Depends on: M-D1
- Risk: low
M-D8: Onboarding wizard polish — part 1 (1.5 days)
Section titled “M-D8: Onboarding wizard polish — part 1 (1.5 days)”- Welcome screen: add imagery + “~15 min” badge
- Profile screen: bio character counter, autosave, error-inline
- Area screen: Mapbox map preview with radius circle (critical missing UI)
- Complete screen: Lottie confetti + score count-up
- Depends on: M-D1
- Risk: low (mostly additive)
M-D9: Onboarding wizard polish — part 2 (2 days)
Section titled “M-D9: Onboarding wizard polish — part 2 (2 days)”- Identity screen: finish Stripe Identity sheet wiring + consequence warning on skip
- Credentials screen: trust-score preview + illustrated empty state
- Pricing screen: multi-category list + dominant fixed-vs-hourly toggle + unit hints
- Portfolio screen: drag-to-reorder + caption entry + category tagging
- Progress bar spring animation on step advance
- Depends on: M-D1, M-D8
- Risk: medium — Stripe Identity wire-up has external-dependency surface
M-D10: Pro-specific empty/error component pack (1 day)
Section titled “M-D10: Pro-specific empty/error component pack (1 day)”- Canonical
ProEmptyState+ProErrorStatecomponents wrappingEmptyStatewith pro motion + illustration slot - Port illustrations (sourced from decision in Phase A illustration pack question)
- Replace every pro-surface empty/error with these components
- Depends on: M-D1, Phase A illustration decision (blocker if still open)
- Risk: blocked if illustration source not decided
M-D11: Accessibility + dark mode pass (1.5 days)
Section titled “M-D11: Accessibility + dark mode pass (1.5 days)”- Every pro screen: dark variants via NativeWind class modifiers
- Every interactive element: accessibilityLabel + accessibilityRole + accessibilityState
- Focus-visible rings on web
- Screen-reader labels on chart surfaces (earnings)
- Depends on: M-D1 through M-D9
- Risk: low
M-D12: Preview system coverage + visual regression snapshot (1 day)
Section titled “M-D12: Preview system coverage + visual regression snapshot (1 day)”- Add every pro route + state permutation to Playwright tour (
persona=pro) - Seed fixtures for: empty earnings, full earnings, all tier states, pending credentials, rejected credentials, partial onboarding at each step
- Establish baseline snapshots on first main-merge
- Depends on: M-D1 through M-D11
- Risk: low
Total estimated: 22 days (≈4.5 weeks), but many can parallelize post M-D1 across agents/worktrees.
Open Decisions
Section titled “Open Decisions”Genuine unknowns. No speculation.
react-native-calendarsswap? Keep themed or replace with custom Reanimated calendar? Swap cost vs theming-limit risk unclear. Spike: 4hrs to check dark-mode + token compatibility.victory-nativevsreact-native-gifted-chartsfor earnings chart — needs Expo Web compatibility test. If victory-native Skia fails on web, fallback.- Illustration pack decision (inherited from master plan) — blocks M-D10. Escalate: decide this before Phase D starts or M-D10 becomes blocked.
- Trust tier-up delivery mechanism — WebSocket via existing Socket.IO gateway, or push notification only? WebSocket is snappier but adds screen-specific socket subscription cost. Decide before M-D6.
- Batch actions in admin queue — needed for MVP 0 or Phase D+? Low admin volume means maybe post-MVP. Confirm with admin user volume projection.
- CSV export location — server-side generated endpoint (heavier BE work) vs client-side generation from cached bookings (simpler, but may be slow for >1000 records). Recommend server-side.
- Earnings screenshot prevention — iOS lacks direct FLAG_SECURE equivalent. Manual overlay on AppState change is a workaround but UX-fragile. Accept the limitation or invest in native module? Recommend accept.
Hard Bans — Reconfirm
Section titled “Hard Bans — Reconfirm”All pro surfaces inherit the brand hard bans from .impeccable.md:
- No side-stripe borders >1px
- No gradient text
- No glassmorphism
- No pure black/white (always tint to Sole palette — replace
#FFFFFFin earnings summary with cream#FAF6EE) - No big-number-hero metric decoration
- No reflex-default fonts
- No side-stripe accents
Current Phase D audit already flagged violations:
earnings.tsx:#FFFFFFtext on terracotta → replace with creamdashboard.tsxstat grid: big-number-hero template → redesign as cockpit ribboncalendar.tsx: hardcoded#FAF6EEhex → usecolors.backgroundtoken
Success Criteria
Section titled “Success Criteria”- Every pro screen uses NativeWind + design tokens (zero StyleSheet.create, zero hex literals)
- Every pro screen uses Gambarino for headlines + Switzer for body (font utilities in Tailwind config)
- Every pro surface has branded empty + error states (not generic grey boxes)
- Dashboard redesigned away from big-number hero template (impeccable compliance)
- Earnings screen includes chart + payout timeline + privacy toggle + CSV export
- Trust tier has 3 distinct visual treatments + tier-up celebration moment
- Onboarding completes in <15 min for 80% of new pros (instrument + measure)
- Admin queue has keyboard shortcuts + filters + SLA coloring
- Every pro screen dark-mode compatible
- Every pro route covered in Playwright tour + visual regression baselines
- Phase D Lost Pixel diff < 5% on post-merge runs (change intentional, not chaotic)
Change Log
Section titled “Change Log”- 2026-04-20 — Spec created. Inventoried 16 pro-side surfaces, scored current polish (average 3.4/5), drafted 12 milestones totaling ~22 days, identified 7 open decisions. Trust tier visual treatment locked (3 tiers, no gradient, icon+color anchored). Earnings spec includes
victory-nativechart library choice + privacy toggle + CSV export. Pro motion language documented as distinct-from-consumer (operational vs romantic).