🧭 EBO — 2026-06-28 live-test findings (pipeline + Studio sales-call-prep)

13 behaviors from Mátyás's 2026-06-28 test: post-call sync, reschedule routing, Studio-on-both-stages, booking perf, readable pills, available-only slots, all-event notifications, no-delete-on-second-call, Fireflies bot-free, Studio auto-prep→Figma(MCP), rep fix-loop, deliverables panel.

Personas & jobs-to-be-done

Each journey is walked by a named protagonist (BMAD pattern): a concrete persona with a job-to-be-done trigger, so the spec reads as behaviour rather than abstract requirements.

3 personas13 scenariosslug bnf-2026-06-28-01
P1

Mátyás — pipeline operator logged-in dashboard operator

JTBD: When a lead moves through the funnel I want the board + history to reflect reality instantly so that I never act on stale state.

P2

Lead — prospect booking a call public booking app user, not logged in

JTBD: When I want to book a consultation I want a fast, honest picker so that I pick a real free slot without waiting.

P3

Sales rep (Mátyás) — Studio prep operator preparing a sales call in Studio

JTBD: When a call is booked I want the prospect's site auto-prepped into presentable Figma assets so that I walk into the call with a concrete proposal in minimal clicks.

Scenario catalog

Every distinct leaf path, classified happy / edge / failure / recovery. The proposed test-IDs are the bridge that plan-techspec reads from scenario_map.json to seed acceptance checks.

IDScenarioPersonaPathStepsProposed test-IDs
S1Post-call: card tag + transcript-status pill on the PipelineP1🟢 happy2
S2Post-call: history shows Google Meet call + transcript; reminders removedP1🟢 happy2
S3Manual Log-Call reschedule routes to Sales Call/Proposal when prep is doneP1🟣 recovery1
S4Open-in-Studio button present on BOTH Booked/Sales Call Prep and Sales Call/ProposalP1🟢 happy2
S5Booking app: slot-list load AND confirmation both render fast (<2s)P2🟢 happy2
S6Board-card pills/tags: readable contrast, bigger, uniform per columnP1🟢 happy1
S7Booking picker shows only AVAILABLE slots (no 'slot became occupied' error)P2🟡 edge2
S8Real-time Pipeline notifications for ALL events, not just bookingsP1🟢 happy1
S9Do NOT delete the Google Meet event when booking a NEW second callP1🟡 edge2
S10Fireflies bot-free recording — no prospect-facing consent promptP3🟢 happy1
S11Studio: auto-create on Booked → full-auto prep chain → Figma import (Figma MCP)P3🟢 happy4
S12Studio: rep prep-review-and-fix loop (comment-edit → Save version → back to exportable)P3🟣 recovery3
S13Studio: Deliverables panel — HTML export + embedded Figma + competitor FOMO deck; image-rewrite toggle OFF; Figma link to CRMP3🟢 happy4

Scenarios — click-by-click step tables

Each row is one concrete UI interaction: who acts · the exact element clicked or seen · the copy shown · the system action · the resulting state · where it branches.

S1 — Post-call: card tag + transcript-status pill on the Pipeline 🟢 happy P1

Trigger: A Google Meet sales call with a lead has just ended and Fireflies has the recording.

#ActorUI element (clicked / seen)Copy shownSystem actionResulting stateBranch to
1systemThe lead's board card in the Pipeline view, just after the Google Meet call endspipeline detects the sales call occurred (Fireflies/transcript hook)call_occurred=true
2systemThe transcript-status pill on the same card after the transcript finishes processingtranscript ingest completes + links to the dealtranscript_ready=true

Proposed acceptance test-IDs:

Expected-Behavior Oracle — the answer key the tests assert against
#You doYou should seeElement that changes (copy · look · where)What changes underneathMust NOT happenUX suggestions
1The lead's board card in the Pipeline view, just after the Google Meet call endsOn the card, a tag 'Sales call megtörtént' appears AND a separate transcript-status pill 'Átirat feldolgozása…'.Copy: Tag: 'Sales call megtörtént' · Pill: 'Átirat feldolgozása…' · Look: two distinct pills/tags; the status pill is a coloured pill (amber=processing) · Where: on the lead's board card, in the Booked/Sales Call Prep or Sales Call/Proposal columndeal flagged call_occurred=true; transcript ingest pendingthe pipeline does not react to the call at all (no tag, no pill)• Use distinct shapes — a solid 'Sales call megtörtént' tag vs a live status pill — so the two signals are never confused at a glance.
• Fade the pill in when the call is detected so the operator notices the card changed without a full board refresh.
• Guard against duplicate detection: a re-fired call should update the existing tag, not stack a second one.
2The transcript-status pill on the same card after the transcript finishes processingThe transcript-status pill flips from 'Átirat feldolgozása…' to 'Kész'.Copy: 'Kész' · Look: the status pill flips colour (amber→green) — a status pill that changes state · Where: same position on the card, next to the 'Sales call megtörtént' tagtranscript stored + linked to the dealthe pill stays stuck on 'Átirat feldolgozása…' after the transcript is ready; the system mistakes the call for a notification-only event• Make the flip a colour+icon change (amber spinner → green check) so 'done' reads instantly without text.
• Make the 'Kész' pill click-through to the transcript so signal→content is one click.
• Add a failure state ('Átirat sikertelen — újra') so a stuck transcript is recoverable, not silently pending forever.
Sub-flow — what the user sees & does (arrows carry the system detail)
flowchart TD
  S1U1["The lead's board card in the Pipeline view, just after the Goog…"]
  S1U2["The transcript-status pill on the same card after the transcrip…"]
  S1U1 -->|pipeline detects the sales call occurred (Fir…| S1U2
S2 — Post-call: history shows Google Meet call + transcript; reminders removed 🟢 happy P1

Trigger: The sales call happened; Mátyás opens the lead's history.

#ActorUI element (clicked / seen)Copy shownSystem actionResulting stateBranch to
1userClick '🕘 Előzmények' (history) on the lead card and expand the call entryhistory rendered
2systemThe scheduled appointment-reminder email rows in the same history, after the callon call-occurred, remove appointment-reminder rows + cancel any still-pending scheduled reminderspending_reminders_cancelled

Proposed acceptance test-IDs:

Expected-Behavior Oracle — the answer key the tests assert against
#You doYou should seeElement that changes (copy · look · where)What changes underneathMust NOT happenUX suggestions
1Click '🕘 Előzmények' (history) on the lead card and expand the call entryA history entry 'Google Meet hívás (Xp Ym)' with the call duration in parentheses, and an expandable block containing the full transcript text.Copy: 'Google Meet hívás (Xp Ym)' + expandable transcript · Look: history row with a duration in parentheses + a collapsible transcript panel · Where: in the 🕘 Előzmények history listthe call is logged in history as a Google Meet call with duration + the full transcriptthe call is labelled 'phone call'; the transcript is missing or truncated• Collapse the transcript by default behind a one-line AI summary; expand on demand to avoid a wall of text.
• Label with a Meet icon + exact duration so it's unmistakably a Google Meet call, not a phone log.
• Add 'Copy transcript' / 'Open in Fireflies' affordances for fast sharing without leaving the card.
2The scheduled appointment-reminder email rows in the same history, after the callThe scheduled appointment-reminder email rows are gone from the history; no reminder email goes out after the call.Copy: (the reminder rows disappear) · Look: the reminder history rows are removed · Where: 🕘 Előzmények history liststill-pending scheduled reminders are cancelled; if the booking was too soon for the full sequence, only the leftover reminders are removeda reminder email is sent to the lead AFTER the call already happened• Leave a subtle greyed audit line ('3 emlékeztető törölve a hívás után') so the removal is explained, not silent.
• Cancel pending sends transactionally so a reminder can't slip out in the race between 'call done' and 'reminder fires'.
• If the booking was too soon for the full sequence, show which reminders never sent vs were cancelled.
Sub-flow — what the user sees & does (arrows carry the system detail)
flowchart TD
  S2U1(["Click '🕘 Előzmények' (history) on the lead card and expand the…"])
  S2U2["The scheduled appointment-reminder email rows in the same histo…"]
  S2U1 -->|history rendered| S2U2
S3 — Manual Log-Call reschedule routes to Sales Call/Proposal when prep is done 🟣 recovery P1

Trigger: A lead is in 'Booked / Sales Call Prep' with prep already done; Mátyás reschedules via the Log Call panel.

#ActorUI element (clicked / seen)Copy shownSystem actionResulting stateBranch to
1userOn a Booked/Sales Call Prep card (prep_done=true), click 'Log Call' → 'Book Appointment', enter a new meeting time, savemanual reschedule via the Log-Call booking pathstage routed by prep_done

Proposed acceptance test-IDs:

Expected-Behavior Oracle — the answer key the tests assert against
#You doYou should seeElement that changes (copy · look · where)What changes underneathMust NOT happenUX suggestions
1On a Booked/Sales Call Prep card (prep_done=true), click 'Log Call' → 'Book Appointment', enter a new meeting time, saveThe card moves to the 'Sales Call / Proposal' column (NOT back to 'Booked / Sales Call Prep'), showing the new meeting time.Copy: new call date/time on the card · Look: card now in the Sales Call/Proposal column · Where: Sales Call / Proposal columnbecause prep was already done, the reschedule routes to Sales Call/Proposal; callAt updated; old date replacedthe card lands back in 'Booked / Sales Call Prep' when prep was already done; the No-Show+Reschedule (S10 of the prior run) behavior is unchanged• Flash/scroll-to the moved card in its new column so the operator sees where it landed.
• Show a toast explaining the routing ('prep done → Sales Call/Proposal') so the decision is transparent.
• Preview the destination column on the booking panel before saving so the move is never a surprise.
Sub-flow — what the user sees & does (arrows carry the system detail)
flowchart TD
  S3U1(["On a Booked/Sales Call Prep card (prep_done=true), click 'Log C…"])
S4 — Open-in-Studio button present on BOTH Booked/Sales Call Prep and Sales Call/Proposal 🟢 happy P1

Trigger: A lead enters the Booked/Sales Call Prep stage and later Sales Call/Proposal.

#ActorUI element (clicked / seen)Copy shownSystem actionResulting stateBranch to
1userLook at a card the moment it enters the 'Booked / Sales Call Prep' columncard in appt_booked
2userLook at the same lead's card in the 'Sales Call / Proposal' columncard in sales_call

Proposed acceptance test-IDs:

Expected-Behavior Oracle — the answer key the tests assert against
#You doYou should seeElement that changes (copy · look · where)What changes underneathMust NOT happenUX suggestions
1Look at a card the moment it enters the 'Booked / Sales Call Prep' columnThe 'Open in Studio' button is present on the card from the moment it enters Booked / Sales Call Prep.Copy: 'Open in Studio' · Look: button on the card · Where: on the Booked/Sales Call Prep cardstudio deep-link available for the dealthe button is missing on entry to Booked/Sales Call Prep• Render the button optimistically the instant the card enters the column, not after the next poll, so it's never briefly missing.
• Show a Studio-status dot (grey/amber/green) so the operator knows if the project is still generating.
• If project creation failed, offer a 'retry create' affordance instead of a dead button.
2Look at the same lead's card in the 'Sales Call / Proposal' columnThe 'Open in Studio' button is ALSO present on the Sales Call / Proposal card.Copy: 'Open in Studio' · Look: button on the card · Where: on the Sales Call/Proposal cardstudio deep-link available in this stage toothe button is present on one stage but missing on the other (must be on both)• Keep the button visually identical across both columns so it reads as the same action.
• Deep-link to the right Studio view (prep vs deliverables) based on stage, saving a navigation step.
• Disable + tooltip the button while generating rather than letting a click 404.
Sub-flow — what the user sees & does (arrows carry the system detail)
flowchart TD
  S4U1(["Look at a card the moment it enters the 'Booked / Sales Call Pr…"])
  S4U2(["Look at the same lead's card in the 'Sales Call / Proposal' col…"])
  S4U1 -->|card in appt_booked| S4U2
S5 — Booking app: slot-list load AND confirmation both render fast (<2s) 🟢 happy P2

Trigger: A lead books a call on the public booking page.

#ActorUI element (clicked / seen)Copy shownSystem actionResulting stateBranch to
1userOn the booking page, pick a date and watch the time-slot list loadslots loaded
2userPick a time slot and click 'Foglalás megerősítése'submit booking; heavy side-effects run off the response pathbooking confirmed

Proposed acceptance test-IDs:

Expected-Behavior Oracle — the answer key the tests assert against
#You doYou should seeElement that changes (copy · look · where)What changes underneathMust NOT happenUX suggestions
1On the booking page, pick a date and watch the time-slot list loadThe time-slot list renders quickly (well under 2s) after picking a date.Copy: time-slot buttons · Look: slot list appears without a long spinner · Where: booking page, slot areaslot availability fetched fasta multi-second wait / spinner stall when loading slots• Skeleton-load placeholder slots so the picker feels instant while availability resolves.
• Prefetch slot data on date-hover so the list is ready the moment a date is clicked.
• Cache the month's availability client-side so switching dates doesn't re-hit the server each time.
2Pick a time slot and click 'Foglalás megerősítése'The confirm/success screen appears in UNDER 2 seconds of submitting.Copy: success / 'Foglalás megerősítve' screen · Look: fast confirm screen, no long spinner · Where: booking page, post-submitsubmit→confirm <2s; CRM write / gcal / email still happen in the background≥2s wait; the old ~5s delay; a dropped side-effect (email/CRM/gcal must still happen)• Show the success screen optimistically with a 'finalising…' micro-state while side-effects finish in the background.
• Disable + spin the confirm button on click to prevent double-submits.
• If a background side-effect fails, reconcile quietly (retry/queue) without blocking or alarming the user.
Sub-flow — what the user sees & does (arrows carry the system detail)
flowchart TD
  S5U1(["On the booking page, pick a date and watch the time-slot list l…"])
  S5U2(["Pick a time slot and click 'Foglalás megerősítése'"])
  S5U1 -->|slots loaded| S5U2
S6 — Board-card pills/tags: readable contrast, bigger, uniform per column 🟢 happy P1

Trigger: Mátyás looks at the board cards (sequence pills, per-email pills, status tags).

#ActorUI element (clicked / seen)Copy shownSystem actionResulting stateBranch to
1userLook at the pills/tags on the board cards (e.g. 'Automated sequence', 'Email 1/2 (sent/unsent)', status tags)

Proposed acceptance test-IDs:

Expected-Behavior Oracle — the answer key the tests assert against
#You doYou should seeElement that changes (copy · look · where)What changes underneathMust NOT happenUX suggestions
1Look at the pills/tags on the board cards (e.g. 'Automated sequence', 'Email 1/2 (sent/unsent)', status tags)The pills/tags are clearly readable (strong contrast, not faint), BIGGER than before, and uniform in design within each column.Copy: same tag text (Automated sequence, Email N …) · Look: darker/stronger colour + larger size; one consistent pill style per column · Where: on the board cards, across all columnsfaint/low-contrast pills (as in the attached screenshot); inconsistent pill styles within a single column; overflow/overlap from the larger size• Extract ONE shared pill component (tokens: size/radius/weight/contrast) so uniformity is structural, not per-card.
• Lock a colour-semantics legend (sent=green, unsent=grey, sequence=indigo, status=amber) applied everywhere.
• Cap pills to 1–2 lines with ellipsis and meet WCAG-AA at the larger size so bigger never means overflow.
Sub-flow — what the user sees & does (arrows carry the system detail)
flowchart TD
  S6U1(["Look at the pills/tags on the board cards (e.g. 'Automated sequ…"])
S7 — Booking picker shows only AVAILABLE slots (no 'slot became occupied' error) 🟡 edge P2

Trigger: A lead (or Mátyás) opens the booking or reschedule slot picker.

#ActorUI element (clicked / seen)Copy shownSystem actionResulting stateBranch to
1userOpen the booking / reschedule slot picker and view the offered timespicker queries live availability and omits already-booked slotsonly-free slots shown
2systemThe server response when two people race for the same slotserver-side slot-taken guardrace rejected

Proposed acceptance test-IDs:

Expected-Behavior Oracle — the answer key the tests assert against
#You doYou should seeElement that changes (copy · look · where)What changes underneathMust NOT happenUX suggestions
1Open the booking / reschedule slot picker and view the offered timesOnly AVAILABLE slots are shown; already-booked times are not offered at all.Copy: only free time slots · Look: no greyed/taken slots in the list · Where: booking + reschedule slot picker (both)picker filters out booked slots in both the initial-booking and reschedule pickersan already-booked slot is shown as selectable, producing the 'ez az időpont közben foglalt lett' error in the normal flow• Group free slots by morning/afternoon with day headers so a sparse list stays scannable.
• Grey out fully-booked dates in the date picker with 'nincs szabad időpont' so users don't open empty days.
• Live-refresh slots (~30s / on focus) so a slot taken elsewhere disappears before the user picks it.
2The server response when two people race for the same slotIn the rare race (two pick the same free slot), the server still returns the friendly 'please choose another' message as a last-resort backstop.Copy: 'ez az időpont közben foglalt lett, kérlek válassz másikat' (race fallback only) · Look: friendly inline message · Where: booking pickerthe server guard remains as a race backstop, just not normally hita real double-booking; removing the guard entirely• Keep the friendly race message but auto-refresh the picker so the now-taken slot vanishes immediately.
• On the race, auto-suggest the nearest free slot so the user isn't left re-hunting.
• Log race hits so a real concurrency problem is distinguishable from a stale-cache one.
Sub-flow — what the user sees & does (arrows carry the system detail)
flowchart TD
  S7U1(["Open the booking / reschedule slot picker and view the offered…"])
  S7U2["The server response when two people race for the same slot"]
  S7U1 -->|picker queries live availability and omits al…| S7U2
S8 — Real-time Pipeline notifications for ALL events, not just bookings 🟢 happy P1

Trigger: Any pipeline-relevant event occurs while Mátyás watches the Pipeline view.

#ActorUI element (clicked / seen)Copy shownSystem actionResulting stateBranch to
1systemThe Pipeline view while events occur (new lead, inbound reply, booking, reschedule, cancellation, sales-call-occurred, proposal sent, payment)each event pushes a real-time notification to the Pipeline viewlive notification per event

Proposed acceptance test-IDs:

Expected-Behavior Oracle — the answer key the tests assert against
#You doYou should seeElement that changes (copy · look · where)What changes underneathMust NOT happenUX suggestions
1The Pipeline view while events occur (new lead, inbound reply, booking, reschedule, cancellation, sales-call-occurred, proposal sent, payment)Each of these events surfaces a real-time notification on the Pipeline view (like booking already does): new lead, inbound reply, booking, reschedule, cancellation, sales-call-occurred, proposal sent, payment.Copy: per-event notification text · Look: real-time toast/banner/badge on the Pipeline view · Where: Pipeline viewall listed events emit a real-time Pipeline notification, not only bookingsonly the booking event notifies; an event passes silently with no real-time signal• Use one Pipeline notification feed/bell with per-event icons + colour instead of scattered toasts.
• Let the operator mute/filter event types (e.g. mute inbound-reply) so the firehose stays useful.
• Deep-link each notification to the relevant card and collapse bursts ('3 new leads') to cut noise.
Sub-flow — what the user sees & does (arrows carry the system detail)
flowchart TD
  S8U1["The Pipeline view while events occur (new lead, inbound reply,…"]
S9 — Do NOT delete the Google Meet event when booking a NEW second call 🟡 edge P1

Trigger: A lead already had a Google Meet call; a new meeting gets booked — either a reschedule or a genuinely new second call.

#ActorUI element (clicked / seen)Copy shownSystem actionResulting stateBranch to
1userBook a NEW (second) Google Meet call for the lead via Book Appointment (NOT a reschedule)new-call booking pathsecond event created, prior kept
2userPerform an actual reschedule of an upcoming call (No-Show+Reschedule or reschedule action)reschedule pathfuture event replaced

Proposed acceptance test-IDs:

Expected-Behavior Oracle — the answer key the tests assert against
#You doYou should seeElement that changes (copy · look · where)What changes underneathMust NOT happenUX suggestions
1Book a NEW (second) Google Meet call for the lead via Book Appointment (NOT a reschedule)The prior Google Meet event remains on the calendar; a new separate event is created for the second call.Copy: two calendar events (prior + new) · Look: both events present · Where: Mátyás's Google Calendara NEW (non-reschedule) booking keeps the prior calendar_event_id and adds a new eventthe prior Google Meet event is deleted when it was a new second call rather than a reschedule• Make intent explicit at booking: 'Reschedule existing call' vs 'Book an additional call' — this is what drives keep-vs-delete.
• List multiple calls as distinct history entries (Call 1, Call 2) so a second call reads as additive.
• Never delete a past/occurred event regardless of action, as a safety floor.
2Perform an actual reschedule of an upcoming call (No-Show+Reschedule or reschedule action)On a real reschedule, the prior (upcoming) event is replaced and a new event + invite is created.Copy: new event/invite · Look: old upcoming event removed, new one created · Where: Mátyás's Google Calendarthe reschedule path (distinguished by action) deletes the prior upcoming event and creates the new onea reschedule leaves a stale duplicate; OR a non-reschedule deletes a prior event• Confirm 'this replaces the upcoming call on <date>' so a deletion is never a surprise.
• Only delete the future un-occurred event, never a past one, even on reschedule.
• Keep an audit line linking the old and new event so the history stays traceable.
Sub-flow — what the user sees & does (arrows carry the system detail)
flowchart TD
  S9U1(["Book a NEW (second) Google Meet call for the lead via Book Appo…"])
  S9U2(["Perform an actual reschedule of an upcoming call (No-Show+Resch…"])
  S9U1 -->|new-call booking path| S9U2
S10 — Fireflies bot-free recording — no prospect-facing consent prompt 🟢 happy P3

Trigger: The rep wants a Fireflies transcript of the Google Meet without the prospect seeing any Fireflies bot or consent prompt (verbal consent obtained separately).

#ActorUI element (clicked / seen)Copy shownSystem actionResulting stateBranch to
1userRecord the Google Meet via the Fireflies Chrome extension (Fireflies auto-join disabled), verified through Chrome DevToolsbot-free local capture; transcript ingests + links to the leadtranscript captured bot-free

Proposed acceptance test-IDs:

Expected-Behavior Oracle — the answer key the tests assert against
#You doYou should seeElement that changes (copy · look · where)What changes underneathMust NOT happenUX suggestions
1Record the Google Meet via the Fireflies Chrome extension (Fireflies auto-join disabled), verified through Chrome DevToolsNo Fireflies bot/participant and no Fireflies/Meet consent prompt appear to the PROSPECT; the rep still gets a transcript that links to the right lead.Copy: (nothing shown to the prospect) · Look: no extra participant, no consent modal on the prospect side · Where: the Google Meet call as the prospect sees itFireflies auto-join is OFF; capture is via the Chrome extension (or desktop app); the transcript still reaches the pipeline and links to the deala prospect-facing consent modal or a visible Fireflies bot participant appears (which could make the prospect decline to join)• Pre-call checklist chip on the prep card ('Recording: Chrome ext ✓ · bot OFF') so the rep confirms setup before joining.
• One-click 'Start recording (extension)' + a verbal-consent reminder that saves a timestamped note (GDPR basis).
• Post-call 'transcript linked to <lead>' confirmation so the rep knows the bot-free capture reached the pipeline.
Sub-flow — what the user sees & does (arrows carry the system detail)
flowchart TD
  S10U1(["Record the Google Meet via the Fireflies Chrome extension (Fire…"])
S11 — Studio: auto-create on Booked → full-auto prep chain → Figma import (Figma MCP) 🟢 happy P3

Trigger: A deal reaches the 'Booked an appointment' stage; Studio prepares the sales-call materials.

#ActorUI element (clicked / seen)Copy shownSystem actionResulting stateBranch to
1systemThe board card when the deal reaches 'Booked an appointment'auto-create a Studio project named after the prospect's business (deferred if no website URL)studio_project_id set
2systemThe Studio Lab run for the project (English UI)full-auto prep chain runs: scrape → images → rankings → keywords → generate → fix → competitors → copyguide → refineprep chain runs unattended
3systemThe Figma import step at the end of the prep chainvia Figma MCP, import the generated HTMLs into a NEW Figma file named after the client's business, rendered as Figma design objects (HTML-to-Figma equivalent)figma_file_url set
4userHover over the arrow between two prep steps in the Studio runreveal per-step re-run controlsre-run available

Proposed acceptance test-IDs:

Expected-Behavior Oracle — the answer key the tests assert against
#You doYou should seeElement that changes (copy · look · where)What changes underneathMust NOT happenUX suggestions
1The board card when the deal reaches 'Booked an appointment'A Studio project is auto-created for the deal, named after the client's business; if the website URL is missing, the card shows a prompt to add it.Copy: Studio project (business name) / 'add website URL' prompt when missing · Look: deep-link live on the card; inline URL prompt when no URL · Where: board card + StudioStudio project created on Booked; URL captured via card prompt (booking is never blocked on the URL)no project is created; the booking form is forced to require a URL• Make the missing-URL prompt a one-field inline 'add URL → start prep' on the card so it's fixed in place.
• Name the project from the verified business name (not the raw domain) so it's recognisable in Figma/CRM.
• Idempotent create: re-entering Booked must not spawn a duplicate Studio project.
2The Studio Lab run for the project (English UI)The whole prep chain runs full-auto (no mid-chain click), each step showing its status, up to the Figma import.Copy: English step/card labels with status · Look: auto-running step cards (English UI) · Where: Studio Lab viewfull_auto is the default for booking-created projects; image-rewrite swap is OFF by default (S13)the chain stalls waiting for a manual click mid-chain; any Hungarian in the Studio interface• Show a single progress timeline (scrape→…→Figma) with per-step status + ETA so the rep sees how far it got.
• Surface failures per-step with a one-click retry rather than failing the whole chain silently.
• Keep keyword curation a non-blocking inline edit so it never stalls the auto-run.
3The Figma import step at the end of the prep chainA new Figma file named after the client's business is created, containing the generated pages imported as Figma design objects (not flat PNGs).Copy: Figma file named after the business · Look: pages rendered as editable Figma design objects · Where: Figma + a link shown in StudioHTMLs imported to Figma via Figma MCP; the Figma file URL is saved to a CRM custom field on the deal (see S13)PNG-only import; no Figma file; a file not named after the business; the link not persisted• Import as real Figma design objects (layers/frames), not flat images, so the rep can tweak in Figma.
• Name + structure the Figma file by page so navigation matches the site structure.
• If the MCP import partially fails, report which pages imported vs not rather than an all-or-nothing error.
4Hover over the arrow between two prep steps in the Studio runHovering an arrow reveals two buttons: 'Rerun next step' and 'Rerun all steps from here'.Copy: 'Rerun next step' · 'Rerun all steps from here' · Look: two buttons revealed on hover over the step arrow · Where: between step cards in the Studio Lab runre-running recomputes from the chosen step onwardno re-run controls; a re-run silently discards later manual edits without warning• Label the re-run buttons with what they re-run ('Rerun from Generate →') so the scope is obvious.
• Warn (with a confirm) before a re-run that would discard downstream manual edits.
• Show a 'last run' timestamp per step so the rep knows what's stale before re-running.
Sub-flow — what the user sees & does (arrows carry the system detail)
flowchart TD
  S11U1["The board card when the deal reaches 'Booked an appointment'"]
  S11U2["The Studio Lab run for the project (English UI)"]
  S11U3["The Figma import step at the end of the prep chain"]
  S11U4(["Hover over the arrow between two prep steps in the Studio run"])
  S11U1 -->|auto-create a Studio project named after the…| S11U2
  S11U2 -->|full-auto prep chain runs: scrape → images →…| S11U3
  S11U3 -->|via Figma MCP, import the generated HTMLs int…| S11U4
S12 — Studio: rep prep-review-and-fix loop (comment-edit → Save version → back to exportable) 🟣 recovery P3

Trigger: Before the sales call, the rep reviews the prep materials and finds the generated HTML isn't good enough.

#ActorUI element (clicked / seen)Copy shownSystem actionResulting stateBranch to
1userOpen Studio to the generated page from the board cardreviewing prep
2userIn the commenter UI, put the current HTML version into the comment and use the comment feature to edit the mistakes in the frontendcomment-driven edit applies to the working-version draftworking draft updated
3userClick 'Save version'save the new HTML versionversion saved

Proposed acceptance test-IDs:

Expected-Behavior Oracle — the answer key the tests assert against
#You doYou should seeElement that changes (copy · look · where)What changes underneathMust NOT happenUX suggestions
1Open Studio to the generated page from the board cardThe rep can open Studio to the generated page to review quality before the call.Copy: Open in Studio → generated page · Look: the generated page in the Studio commenter UI · Where: Studiorep is reviewing the working versionno way to open the generated page for review• Open straight to the page that needs work (deep-link), not the project root, saving navigation.
• Surface quality signals (broken-image / empty-section flags) so the rep spots issues fast.
• Offer a side-by-side 'generated vs original site' so quality is judged in context.
2In the commenter UI, put the current HTML version into the comment and use the comment feature to edit the mistakes in the frontendUsing the comment feature, the rep edits the mistakes in the frontend; the change applies to the page.Copy: comment with the current HTML + the requested fixes · Look: the page section updates from the comment · Where: Studio commenter UIthe working-version draft is updated from the rep's comment-editthe edit is lost or applies to the wrong section• Inline-preview the comment-edit applied before committing so the rep sees the result.
• Scope each comment to its section visually so an edit can't land on the wrong block.
• Auto-resolve the comment to done with a one-click inline undo — fast yet reversible.
3Click 'Save version'A notification 'HTML updated' pops up, and the view returns to the exportable Studio view where the asset sits alongside the other sales-call-prep assets.Copy: notification: 'HTML updated' (English UI) · Look: toast/notification, then the deliverables/exportable view · Where: Studio — returns to the deliverables viewa new HTML version is saved and is exportable alongside the other prep assetsno save action; no 'HTML updated' notification; the view does not return to the exportable deliverables view• Make the 'HTML updated' toast link straight to the deliverable ('view in Deliverables').
• Keep a version-history dropdown so the rep can revert if an edit made it worse.
• Auto-return to the deliverables view on save so the rep doesn't navigate back manually.
Sub-flow — what the user sees & does (arrows carry the system detail)
flowchart TD
  S12U1(["Open Studio to the generated page from the board card"])
  S12U2(["In the commenter UI, put the current HTML version into the comm…"])
  S12U3(["Click 'Save version'"])
  S12U1 -->|reviewing prep| S12U2
  S12U2 -->|comment-driven edit applies to the working-ve…| S12U3
S13 — Studio: Deliverables panel — HTML export + embedded Figma + competitor FOMO deck; image-rewrite toggle OFF; Figma link to CRM 🟢 happy P3

Trigger: The prep assets are ready; the rep opens the deliverables view (English UI).

#ActorUI element (clicked / seen)Copy shownSystem actionResulting stateBranch to
1userOpen the 'Deliverables' panel in Studiodeliverables shown
2userOpen the competitor-SEO FOMO deckrender the competitor/keyword/ranking data into a client-facing HTML deckdeck available
3systemThe image-rewrite copy step in the prep chain (toggle in the Refine card)skip image swap by default; pre-LLM swap guard so ON is safeskip_image_swap=true by default
4systemThe deal's CRM record after the Figma file is createdwrite the Figma file URL to a CRM custom fieldcrm figma field set

Proposed acceptance test-IDs:

Expected-Behavior Oracle — the answer key the tests assert against
#You doYou should seeElement that changes (copy · look · where)What changes underneathMust NOT happenUX suggestions
1Open the 'Deliverables' panel in StudioOne Deliverables panel (English UI) shows, side by side: HTML export, the embedded Figma file (the business-named file), and the competitor-SEO FOMO deck.Copy: 'Export HTML' · embedded Figma · 'Competitor insights' deck (English) · Look: one co-located panel, three controls side by side · Where: Studio project — single Deliverables panelexport + Figma embed + competitor deck co-located in one panelthe controls are split across two places; any Hungarian in the panel• Co-locate export + Figma + FOMO deck in one panel so there's no two-place hunt.
• Add 'Copy all prep links' (site + Figma + deck + export) so the rep grabs the whole bundle in one click.
• Keep the panel English with consistent button styling so it reads as one cohesive deliverables hub.
2Open the competitor-SEO FOMO deckA polished, client-facing HTML competitor-insight deck (FOMO-oriented: what competitors do, what to learn, what they lose by waiting), available BOTH as a standalone share URL AND bundled in the export.Copy: competitor-insight deck (FOMO framing) · Look: designed client-facing HTML, presentable · Where: standalone share URL + inside the export bundlethe deck is served at a share-token URL AND included in the export packagethe competitor data exists only as internal PNGs; the deck is not shareable• Lead with one punchy stat ('3 competitors rank for X — you don't') to maximise FOMO, then the detail.
• Serve a share-token URL AND bundle a copy in the export so it works pre-meeting and offline.
• Make competitor rows scannable (logo + top keywords + a gap callout) so the client gets it in seconds.
3The image-rewrite copy step in the prep chain (toggle in the Refine card)The image-rewrite copy step is an on/off toggle, OFF by default; with it OFF, refined pages keep their original images intact.Copy: image-rewrite toggle (OFF by default) · Look: an on/off toggle on the Refine card · Where: Studio Refine stepimage swap is skipped by default; when ON, the swap runs on pre-LLM HTML / a src-restore guard prevents the copy LLM from breaking imagesrefined pages have broken/mismatched images by default; the toggle defaults to ON• Default the toggle OFF and label the risk ('may alter images') so ON is a deliberate choice.
• Run the swap on pre-LLM HTML / add a src-restore guard so turning it ON later never breaks images.
• Show a before/after image preview when ON so the rep can verify nothing broke.
4The deal's CRM record after the Figma file is createdThe Figma file URL is stored on the deal in a dedicated CRM custom field.Copy: CRM field: Studio/Figma link · Look: plain CRM field value (a Figma URL) · Where: the deal's CRM custom fieldsa new CRM custom field carries the Figma link; a Studio→pipeline channel writes it backthe Figma link is created but never persisted to the CRM• Write the link to CRM immediately on Figma-file creation so it's never lost if the rep closes Studio.
• Make the CRM field a clickable link (not raw text) so it opens Figma in one click.
• Retry/queue the write-back if the Studio→pipeline channel is briefly down, so the link always lands.
Sub-flow — what the user sees & does (arrows carry the system detail)
flowchart TD
  S13U1(["Open the 'Deliverables' panel in Studio"])
  S13U2(["Open the competitor-SEO FOMO deck"])
  S13U3["The image-rewrite copy step in the prep chain (toggle in the Re…"]
  S13U4["The deal's CRM record after the Figma file is created"]
  S13U1 -->|deliverables shown| S13U2
  S13U2 -->|render the competitor/keyword/ranking data in…| S13U3
  S13U3 -->|skip image swap by default; pre-LLM swap guar…| S13U4

Global branching flowchart

Conditions on the arrows; colours follow the path-type legend. Per-scenario sub-flows appear inside each scenario above.

No global flowchart supplied — see per-scenario sub-flows above.

Copy index — message · copy · source · mode · status

No copy index supplied.

State reference

StateMeaningEntered byExits to
appt_bookedBooked / Sales Call Prepbooking / manual book / dragsales_call (prep done) / back on reschedule
sales_callSales Call / Proposalprep done or manual reschedule when prep_donewon / lost / reschedule
call_occurredthe Google Meet sales call has happenedFireflies/transcript hooktranscript_ready

Generated by the user-journeys skill on 2026-06-28 · hosted at https://bnf-2026-06-28-01-journeys.pages.dev. Rendering: Mermaid flowchart syntax. No screenshots — this is a behavioral spec, not a visual QA artifact.