Video 1: Profile Creation Explainer (~20 to 28s)
Caption font: Fraunces, sentence case. No script fonts. No hyphens or dashes anywhere in overlay copy. No emoji in overlays.
Cast: Maya Ruiz (new persona, not currently in roster.json), woman, interested in men, 28, Williamsburg, NY, height 5'6". Suggested bio for this shoot: "Editor at a small press. I read on the subway and I will talk your ear off about whatever I am reading." Suggested interests: Books, Coffee, Film, Writing (all valid INTEREST_OPTIONS values). Suggested "I'm Open To": Coffee, Museum, Art Gallery, Dinner (all valid DATE_PREF_OPTIONS values). This persona needs to be added to roster.json and seeded by the capture harness before shoot; nothing about her currently exists in prod, so there is no data-collision risk, but the scene coder must create the account first.
Goal: show a brand new user completing the real Greenlight profile wizard, ending on Availability, since that is the product's differentiator (profiles carry real, structured availability rather than a vague "let's see").
Beat 1: Sign up
Open on the sign up screen. Title "Join Greenlight", subtitle "Send date offers. Not likes." Maya fills email, password, confirm password, and date of birth, then taps "Sign up".
Skip point / insert later: email confirmation
Greenlight's sign up flow can require clicking a confirmation link sent to the new account's email before the session exists (Supabase auth; see citation below). This capture cannot click a real inbox link inside a scripted screen recording. Cut here. A later insert, if wanted, would show: a phone or second monitor with the "Check your email" screen on one side and the actual inbox/confirmation email on the other, ending on the click that lands back on Greenlight signed in. Skip straight to Beat 2 for the main cut; the capture harness's existing self auth pattern (see greenlight-demo-capture skill) is the intended way to get a signed in session for this shoot without touching a real inbox on camera.
Beat 2: Role and interests picker (first login modal)
First login shows a two step modal: "Welcome to Greenlight" (I'm a man / I'm a woman / Other), then "Who are you interested in" (Men / Women / Other, multi select) with a "Continue" button. Maya picks "I'm a woman", then "Men", then taps Continue. This is what actually creates her account row server side; only after this does she land on the profile wizard.
Beat 3: Basic Info
Step 1 of 8, "Basic Info". Fields: Name, Age, Height, City (typeahead), Ethnicity (optional chips). Maya fills Maya / 28 / 5'6" / Williamsburg, NY and taps Continue.
Beat 4: Photos
Step 2, "Add Your Photos". Copy: "Upload at least 4 photos. Maximum 6. (Required)". Show 4 to 6 photo slots filling in quick succession (sped up cut), then a quick beat on the optional "Add a Video" row (skip, not required). Continue.
Beat 5: Bio
Step 3, "Your Bio". Copy: "Required. Between 25 and 300 characters." Maya types the bio above; character counter ticks up in the corner. Continue.
Beat 6: Interests and I'm Open To
Step 4, "Your Interests": Maya taps Books, Coffee, Film, Writing. Continue. Step 5, "I'm Open To": Maya taps Coffee, Museum, Art Gallery, Dinner. Continue.
Beat 7: Availability (the differentiator beat)
Step 6, "Your Availability". Copy: "Add at least one time slot. You control exactly when you're available." Walk the real editor in order:
- Pick a day: rolling 7 day horizon, Maya taps a day a few days out
- Window: Morning (9am to 12pm), Afternoon (12pm to 5pm), Evening (6pm to 9pm), Night (9pm to 11pm) — Maya taps Evening
- Start time: 30 minute increments within the window — Maya taps 7:00 PM
- Duration: 1h / 2h / 3h / 4h chips — Maya taps 2h
- Taps "Add this time". Slot appears in the list below as "Evening, [date] · 7:00 PM · 2 hours". Maya adds a second slot on a different day for good measure, then taps Continue.
Beat 8: Preview and Publish
Step 7, "Profile Preview" — quick look at the assembled card, then Step 8 tap "Publish Profile". Ends on the "You're Live" screen: "Your Greenlight profile is published. Others can now view your profile and availability. You're always in control." Hold on this for the out.
Skip point / insert later: ID verification
The published screen offers a "Get verified" card ("It takes about 2 minutes and shows others you're real.") with two buttons: "Get verified" and "Maybe later". Verification is entirely optional and happens only here, after the profile is already live — it is never required before or during profile creation, and no route in the app gates on it. This capture ends on "You're Live" without tapping either button, which is a true, unforced stopping point, not a workaround. If a later insert of the verification flow is wanted, it would show: tapping "Get verified", the Didit verification flow (ID document capture then a liveness selfie), and returning to a "Verified" badge on the profile. That would need a real document and a real face on camera, so it is a separate, deliberate shoot, not part of this one.
Source citations for on screen content
- Sign up screen title, subtitle, fields, and "Check your email" confirmation gate:
artifacts/greenlight/src/pages/SignUp.tsx:59-105(session-vs-confirmation branch),artifacts/greenlight/src/pages/SignUp.tsx:108-111(title/subtitle) - "Send date offers. Not likes." tagline, also on the marketing landing page (canonical source per copy source of truth):
artifacts/greenlight/src/pages/LandingPage.tsx:314-316 - Role / interested in onboarding modal (creates the account row on submit):
artifacts/greenlight/src/components/UserOnboarding.tsx:217-352(step copy),:167-206(submit creates the account, then routes to /create-profile if no profileId) - Wizard step list and order (Basic Info, Photos, Bio, Interests, I'm Open To, Availability, Preview, Publish):
artifacts/greenlight/src/pages/CreateProfile.tsx:339-348 - Basic Info step fields and required-field gate:
artifacts/greenlight/src/pages/CreateProfile.tsx:947-1035, gating logic:352-360 - Photos step copy and 4 minimum / 6 maximum, optional video:
artifacts/greenlight/src/pages/CreateProfile.tsx:797-932, gating:361-362 - Bio step copy and 25 to 300 character bounds:
artifacts/greenlight/src/pages/CreateProfile.tsx:1039-1063, gating:363-366 - Interests step (chip set from
INTEREST_OPTIONS):artifacts/greenlight/src/pages/CreateProfile.tsx:1066-1087,artifacts/greenlight/src/lib/interestOptions.ts:7-30 - "I'm Open To" step (chip set,
DATE_PREF_OPTIONS):artifacts/greenlight/src/pages/CreateProfile.tsx:52-63,1089-1109 - Availability step copy, and the day / window / start time / duration editor UI:
artifacts/greenlight/src/pages/CreateProfile.tsx:1111-1127(step copy),artifacts/greenlight/src/components/AvailabilityEditor.tsx:103-263(Pick a day / Window / Start time / Duration / "Add this time") - Time window labels and ranges (Morning/Afternoon/Evening/Night):
artifacts/greenlight/src/lib/availability.ts:19-26 - Preview step and Publish button:
artifacts/greenlight/src/pages/CreateProfile.tsx:1129-1175(preview),:1324-1350(Publish Profile button) - "You're Live" publish confirmation copy:
artifacts/greenlight/src/pages/CreateProfile.tsx:1236-1253 - "Get verified" card copy and buttons, and confirmation that verification is optional and post publish only:
artifacts/greenlight/src/pages/CreateProfile.tsx:1255-1289 - Confirmation that no route gates on verification (only
RequireAuthgates/verifyitself;RequireProfile— used by Discover, BuildOffer, Offers, Chat, etc. — checks onlyhasPublishedProfile, never a verification flag):artifacts/greenlight/src/App.tsx:246-274(RequireProfile),:550-551(/verifyroute isRequireAuthonly, not a gate on anything else)
Open questions for the capture operator
- Whether the live Supabase project currently has email confirmation ON or OFF cannot be checked from the repo (it is a Supabase dashboard setting, not code) and this session was scoped read only, no login. Treat the "Check your email" screen as a real possible stop; do not assume it can be scripted through.
- Maya Ruiz is a new persona proposed for this shoot, not yet in roster.json and not yet seeded in prod. She needs to be added and seeded (or substituted for an existing unused roster persona) before capture.
Video 2: How Greenlight Works (~26 to 30s)
Caption font: Fraunces, sentence case. No script fonts. No hyphens or dashes anywhere in overlay copy. No emoji in overlays (one tasteful emoji inside captured chat content is fine, matching rev4's precedent).
Cast: Remy (sender, Hoboken NJ, key marcus, display name Remy) throughout. Recipient splits across two beats to avoid touching Sofia's existing rev4 data (see risk note below): Amara Okafor (Astoria, NY, key amara) for the availability / send offer / counter offer beats, Sofia Marchetti (Brooklyn, NY, key sofia) reused only for the messaging and message cap beats, since her accepted offer and unlocked conversation with Remy already exist from the rev4 shoot and do not need to be rebuilt.
Data risk flagged for the scene coder
Sofia and Remy already have a real accepted offer and a 3 message chat thread in prod from the rev4 walkthrough capture (roster/storyboard.md beats 6 to 8). Reusing that same pair for a NEW counter offer beat would either collide with the existing accepted offer or require a second, separate offer between the same two people, which is unusual for this product (typically one active offer per pair) and could confuse the capture. Routing the counter offer beat through Amara instead avoids that collision entirely. Note also that roster.json only carries a seeded availability array for Sofia — Amara has no availability slots in roster.json, so the scene coder must seed Amara with fresh future slots before this shoot (a plausible slot: same shape as Sofia's, e.g. { date, window: "Evening", startTime: "7:00 PM", durationHours: 2 } a few days out). For the messaging beats, reusing Sofia's existing thread means the message counter will not start at 0/20 on camera — open with a fresh line so the counter visibly ticks up rather than claiming a clean start.
Beat 1: Set your availability
Cut to Amara's profile in edit mode, Availability tab. Same editor as profile creation: Pick a day, Window (Morning / Afternoon / Evening / Night), Start time, Duration, "Add this time". Show one slot going in: Evening, a date a few days out, 7:00 PM, 2 hours. This establishes that availability lives on the profile, not buried in a booking form.
Beat 2: Send a Date Offer, not a like
Cut to Remy on Amara's profile, tapping "Send Date Offer". Offer builder shows Amara's real availability slot from Beat 1 in the date / window / start time / duration format. Remy taps through to confirm the slot, picks an activity chip (Rooftop Drinks, matching Amara's stated date prefs), types a short message, and taps "Send Offer" / confirms via "Review Your Offer". Offer confirms as Sent.
Beat 3: Counter offer
Cut to Amara's Received tab. Her incoming offer card shows Remy's name, activity, time, location, and status Pending, with a countdown at top. Three buttons along the bottom: View Profile (outline), Accept (green), Counter (amber outline), Decline (red outline). Amara taps Counter. A bottom sheet opens: "Suggest a Different Time" / "Propose new details for this date. They'll see this as a new offer from you." Fields: Date Idea (same activity chip set as the original offer builder), Date, Time, Duration (1h/2h/3h/4h), Location, Message (optional, 200 char cap). Amara changes the time and taps "Send Counter Offer".
Cut back to Remy's Offers screen: his original sent offer now shows status Countered (amber lamp chip), and a new incoming card appears tagged Counter offer with Amara's proposed details.
Beat 4: Offers expire after 24 hours
Close on a pending offer card's countdown widget: a pulsing dot next to a large numeric countdown (e.g. "23h 41m 09s", ticking live, seconds visible). No separate "expires in" label text exists in the UI beyond this countdown itself, so let the number carry the caption. If room, a quick second shot of an expired state showing the countdown's own "Expired" label once time runs out (this can be a cut to a pre expired test offer rather than waiting out a real 24 hours).
Beat 5: Accept unlocks messaging
Cut to Sofia's device (reusing the existing accepted offer from rev4). Her accepted offer card shows the green check line: "You've been given the Greenlight. Messaging is now unlocked." Tap "Open Messages" into the existing thread with Remy.
Beat 6: Message cap nudges you toward the real date
Inside the Sofia/Remy thread, show the message counter in the top right of the composer area, format "N/20", ticking up as a new message is sent. Send one or two more lines in character (light, no innuendo) to move the counter. If time allows a second cut, show the capped state copy verbatim: composer placeholder "Message limit reached" and the banner "You've reached the limit of 20 messages for this conversation. You can still read new replies." — this can be captured against a seeded test conversation already at 20 messages rather than sending 20 real messages on camera.
Real number confirmation: the cap is a real server constant, MESSAGE_CAP = 20, in artifacts/api-server/src/lib/conversationLifecycle.ts:10 — this matches the team's stated "20 max" exactly. No discrepancy found.
Beat 7: End card (optional, if time remains)
Slogan card, exact copy: A better way to date.
Source citations for on screen content
- Availability editor (Pick a day / Window / Start time / Duration / "Add this time"), reused identically outside profile creation via ProfileView's own-profile edit mode:
artifacts/greenlight/src/components/AvailabilityEditor.tsx:103-263,artifacts/greenlight/src/pages/ProfileView/index.tsx:963(availability tab render),:293-298(?tab=availability&edit=1deep link into edit state) - Time window labels/ranges:
artifacts/greenlight/src/lib/availability.ts:19-26 - "Send date offers. Not likes." tagline:
artifacts/greenlight/src/pages/LandingPage.tsx:314-316, alsoartifacts/greenlight/src/pages/SignUp.tsx:111 - Offer builder activity chip set (
ACTIVITIES, shared with the counter form):artifacts/greenlight/src/lib/activities.ts:9-16 - Received offer card: countdown, status badge, and button row (View Profile / Accept / Counter / Decline), including the note that Counter is hidden on a received counter itself:
artifacts/greenlight/src/pages/Offers.tsx:266-306(card + countdown),:437-500(button row, "traffic light layout" comment at:461-465) - Status badge values, including "Countered" (amber) and the "Counter offer" tag on any row with
counterOfOfferIdset:artifacts/greenlight/src/pages/Offers.tsx:40-73 - Counter offer sheet: title "Suggest a Different Time", description, and field set (Date Idea, Date, Time, Duration, Location, Message with 200 char cap), submit button "Send Counter Offer":
artifacts/greenlight/src/components/CounterOfferSheet.tsx:361-390(sheet chrome),:207-357(form fields and submit button) - 24 hour offer expiry window (earlier of 24h since sent or the scheduled event time):
artifacts/greenlight/src/lib/offerExpiry.ts:8-24 - Countdown widget rendering (pulsing dot + numeric d/h/m/s, "Expired" done state for a pending countdown):
artifacts/greenlight/src/pages/Offers.tsx:113-147 - "Messaging unlocked" banner copy, verbatim:
artifacts/greenlight/src/pages/Offers.tsx:150(GREENLIGHT_NOTEconstant, also rendered inline on an accepted received card at:406-411),artifacts/greenlight/src/pages/Accepted.tsx:143 - Message cap value (20), the "N/20" counter, and the capped banner/composer copy, verbatim: cap constant
artifacts/api-server/src/lib/conversationLifecycle.ts:10; frontend counter and capped stateartifacts/greenlight/src/pages/Chat.tsx:76-96(open/capped state derivation),:582-590(N/20 counter),:592-601(capped banner copy),:605-610(composer placeholder "Message limit reached") - Slogan "A better way to date." — canonical source is the marketing frontend per the team's copy source of truth (see
greenlight-copy-source-of-truthmemory); not independently re-verified in this session beyond that standing rule.
Open questions / risks for the capture operator
- Amara has no seeded
availabilityin roster.json today; a real future slot must be added to her account before this shoot, or Beat 1 will have nothing to show. - Reusing Sofia and Remy's existing rev4 accepted offer and chat thread for Beats 5 and 6 means the message counter will not start at 0/20 on camera. Plan the composer beat around whatever count that thread is actually sitting at rather than assuming a clean start; if a clean 0/20 shot is wanted, use a freshly seeded pair instead (adds another new persona pairing to seed, not attempted here to keep this storyboard grounded in what already exists).
- The 20 message capped state (banner + "Message limit reached" placeholder) was not independently observed live; it is transcribed verbatim from the component's conditional render logic, not from a screenshot of a conversation actually at the cap. Recommend the scene coder seed a test conversation at exactly 20 messages to capture this state for real rather than trusting the citation alone.
- This document does not verify current Supabase email confirmation settings or touch any harness/credentials files, per scope; if the counter offer or messaging beats are shot end to end from a fresh sign up rather than pre seeded accounts, the same email confirmation skip point documented in video 1's storyboard applies.