Skip to content

Onboarding (first-run experience) — Screen Review

Status: 🟢 Validated — meets the brief · 🟢 flow consolidation resolved (revalidated 2026-07-20) · 🟡 one open design item: OTP channel = email (ADR-0008) · Last reviewed: 2026-07-20

Flow consolidation — resolved (revalidated 2026-07-20)

The WelcomeStory ↔ Onboarding redundancy is fixed. WelcomeStory now passes ?type=business|individual (+ &ref=) to Onboarding, and Onboarding removed its splash / launch / welcome / product-intro stages and its fork question — its flow now starts at auth. Details in Consolidation plan.

Validation of the reimagined first-run onboarding (prototype/onboarding/Onboarding.dc.html, 83.9 KB; the prior version is archived as Onboarding_v1.dc.html). Checked against the First-Run Onboarding Experience brief and the Profile/Settings/Onboarding field brief. The whole journey is one DC file driven by a pos cursor over a computed flow, with type (business/individual), referral, and resume as scenario toggles.

Stage coverage — all 12 present

Brief stagePresentEvidence
1 Splashsplash screen + ob-01-splash.png
2 Launch animationqrPop/obPop CSS keyframes, tap-to-skip
3 Welcomewelcome beat, Hinglish line "Aapka business, ab online"
4 Product introductionintroI/storyI story cards, "Digital Bharat" vision beat present
5 Authentication (production-look, placeholder)authTab signup/login, authMode phone/email, OTP flow, forgot-password, "Continue with Google"
6 Initial setup + account-type forktype: 'business'|'individual', "For my business" / "For myself"
7 Optional permissionspermissions step, notification prompt, skippable
8 Business profile onboardingbrand → industry → location steps (business only)
9 Live value preview + feature highlightslive card preview, highlights step
10 First-time guidancedashboard get-started checklist
11 Successful completionceleb step, confetti (obFall) + tick (obTick), share action, slug/public URL shown
12 Landing on Dashboard (first-run)dashboard hand-off with checklist/empty-guidance

Both baked-in decisions honored: auth is production visual quality with placeholder wiring; the story is lightweight/skippable (CSS-SVG only, Skip on every intro screen) and performance-safe.

Recommended extras — all implemented: referral-aware entry (referral: "Priya invited you" scenario), save & resume (resume: On → "Welcome back" re-entry), and the live Service Card preview.

Design-language compliance — clean

  • 0 native <select> (custom country/industry pickers instead), 0 em dashes.
  • prefers-reduced-motion media query present — all animation collapses to instant.
  • Tokens throughout. The only raw hex are #fff (foreground-on-accent, house style) and the four official Google logo colours (#4285F4/#EA4335/#FBBC05/#34A853) inside the "Continue with Google" SVG — a legitimate brand-mark exception (like the chart-colour exception), not a token violation.
  • Light + dark both handled (a Light/Dark display toggle in demoState).

The account-type fork works correctly

buildFlow(type) computes the step list: business = ['name','brand','industry','location',…] + ['permissions','highlights','celeb',…]; the individual path drops brand and industry, so an individual gets the visibly shorter flow the brief required and is never forced a business identity (matches the locked dual-audience decision and ADR-0001 D3).

Notes (not defects)

  1. Field naming is camelCase prototype state, not DB snake_casefullName, mobile, brand, pin, industryIdx, country, stateVal, city, slug. Correct for a design prototype; the implementation must map these to the real columns (full_name, mobile_number, brand_name, pin_code, business_domain_id, …) per the field brief. No gstin in onboarding — correct, it belongs to the Profile screen, not first-run.
  2. Backend dependency (carry-over, still open): the completion screen shows the public URL (slug), but manage-profile currently drops slug, gstin, and onboarding_completed from its upsert allow-list (see tracker). This design is correct; the ~two-line Edge-Function allow-list fix must land with implementation or the URL the completion screen promises will not persist. This is a backend task, not a design finding.

Verdict

Meets expectations across all 12 stages, both product decisions, the design-language rules, and the recommended activation extras. No design-fixable findings. The only outstanding item is the pre-existing backend allow-list fix, which is tracked and belongs to implementation.

Flow consolidation plan (WelcomeStory ↔ Onboarding)

WelcomeStory.dc.html was reviewed 2026-07-19. It is strong — 6 bilingual (Hindi + English) autoplay scenes, lightweight CSS/SVG (no video), tokens, prefers-reduced-motion, skip/replay/pace/theme controls, and a culturally excellent Aadhaar-as-business-identity analogy (scene 3). But it overlaps Onboarding.dc.html.

The redundancy

ConcernWelcomeStoryOnboarding.dc.html
Brand splash / revealopening sceneStage 1 Splash + Stage 2 Launch anim
Welcome / hookscenes 1–2Stage 3 Welcome
Product storyall 6 scenesStage 4 Product introduction
Account-type forkfinal sceneStage 6 setup fork

WelcomeStory's fork choice is discarded — both choices are href:'Onboarding.dc.html' with no param, so the question is asked twice and the first answer lost.

App launch → WelcomeStory → Onboarding → Dashboard.

  • WelcomeStory owns why + who: splash + story + fork. Fork links carry the choice — Onboarding.dc.html?type=business|individual.
  • Onboarding owns setup: remove Stages 1–4 (splash, launch anim, welcome, product intro) and the Stage-6 fork question; start at Auth, read ?type=, then setup → permissions → live preview/highlights → completion → dashboard. Returning users skip WelcomeStory → login.
  • File hygiene: ship only WelcomeStory.dc.html (story) + Onboarding.dc.html (setup). Treat OnboardingStory.dc.html as a storyboard reference (not a runnable screen); confirm uploads/QRSetuOnboarding.dc.html is dead and remove.

WelcomeStory design-fixable prompt (paste into Claude Designs)

markdown
In this project, prototype/onboarding/WelcomeStory.dc.html and prototype/onboarding/Onboarding.dc.html duplicate
the story and the account-type fork. Consolidate to one canonical flow: WelcomeStory (story + fork) →
Onboarding (auth + setup) → dashboard.

1. WelcomeStory final scene: the two choices ("I run a business" / "I'm building my identity") currently both
   link to a bare Onboarding.dc.html. Make them pass the choice: Onboarding.dc.html?type=business and
   ?type=individual.
2. Onboarding.dc.html: read the ?type= param, skip its own account-type fork step, and REMOVE its splash, launch
   animation, welcome, and product-introduction stages (WelcomeStory now owns all of that). Onboarding should
   START at authentication, then go straight into the (pre-branched) setup steps.
3. WelcomeStory language: it is Hindi-first with English subtitles, but QRSetu supports en/mr/hi and serves
   non-Hindi regions. Add a language choice up front (or follow device language) with Marathi + English scene
   copy, and a visible language toggle. Do not hard-lock Hindi.
4. WelcomeStory autoplay: add a visible pause/play control in the header (auto-advancing content must be
   pausable). Keep Skip and the reduced-motion behaviour.
5. WelcomeStory final scene copy: the Hindi ("डिजिटल भारत की नई पहचान") and English ("Choose how you'll use QR
   setu") don't match; align them (every other scene is a faithful translation).
6. If the user arrived via a referral link (?ref=), acknowledge it on the opening scene ("Priya invited you"),
   consistent with the Invite & Earn program. Design with-referral and without-referral variants.

Keep the Aadhaar analogy scene, the bilingual copy, the token usage, reduced-motion, and the lightweight
CSS/SVG animation (no video) — those are all correct.

When applied, ask to revalidate onboarding — the files are re-fetched and this page updated in place.

Revalidation — 2026-07-20 (consolidation applied) 🟢

Re-fetched both files. Every consolidation item landed:

WelcomeStory.dc.html:

  • ✅ Fork now links Onboarding.dc.html?type=business / ?type=individual, and appends &ref= when a referral is present — the choice is carried forward, not discarded.
  • ✅ Trilingual: hi / mr / en scene copy via a mk() builder; device-language auto-detect (navigator.language) and a header language toggle (हिं / मर / EN).
  • ✅ Visible pause/play control in the header (togglePlay, pause/play icons); Skip + reduced-motion retained.
  • ✅ Final scene copy aligned across languages ("Choose how you'll use QR setu" / "तय करें, आप QR setu का उपयोग कैसे करेंगे।").
  • ✅ Referral-aware: referralName() reads ?ref=, shows a double-sided-reward chip on scene 0 (trilingual).
  • Remaining low-priority (runtime/build, not design): "remember seen" so returning users skip the film, and full-bleed on real mobile instead of the prototype's phone-in-page frame.

Onboarding.dc.html:

  • ✅ Flow is now ['auth', 'otp', ...setup, ...post]starts at auth; splash, launch animation, welcome, and product-introduction stages are gone.
  • ✅ No in-flow account-type fork; type is read from the URL via urlParam('type').
  • ✅ Pre-branched setup preserved: business = name/brand/industry/location/slug (+ permissions/highlights/ celebrate/dashboard); individual = name/location/slug (+ highlights/celebrate/dashboard).
  • Safe default: type initializes to 'business' and only an explicit ?type=individual switches to the shorter path — a direct visitor or missing param gets the complete flow, never the truncated one.

The canonical flow is now clean: WelcomeStory (story + fork) → Onboarding (auth → setup → … → dashboard) → Dashboard, each thing happening exactly once. Nothing outstanding on this flow.

New finding — OTP channel is email, not phone (design-fixable, 2026-07-20) 🟡

ADR-0008 is now accepted with OTP delivered by email (ZeptoMail) — no SMS/WhatsApp provider in the first release. The prototype's auth step offers a phone OTP mode (authMode phone/email, and the otp step copy implies a code sent to a mobile number). The verification affordance must be re-specified so the OTP is sent to and entered from the user's email, and the copy reads "we sent a code to your email" (not to a phone). Mobile number is still collected as a profile field (mobile_number), but it is not the OTP channel for launch.

Prompt for Claude Design (paste into the project):

markdown
In prototype/onboarding/Onboarding.dc.html, the authentication + OTP step currently supports a phone-OTP mode
(authMode phone/email) and the OTP verification copy implies a code sent to a mobile number. Product has decided OTP
is delivered by EMAIL for the first release (no SMS/WhatsApp).

1. Make EMAIL the verification channel: after signup/login, the OTP is sent to the user's email address, and the OTP
   entry screen copy reads "We've sent a 6-digit code to <email>" with a "Resend code" and "Change email" affordance.
2. Keep collecting mobile number as a profile field (it is saved to mobile_number), but do NOT present phone as an OTP
   verification channel. Remove or hide the phone-OTP mode, or repurpose the phone field as profile-only input.
3. "Continue with Google" stays as-is (no OTP needed for that path).
Keep the production-look visual quality, tokens, light/dark, and reduced-motion behaviour.

When applied, ask to revalidate onboarding.