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 scenariosslugbnf-2026-06-28-01
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.
JTBD: When I want to book a consultation I want a fast, honest picker so that I pick a real free slot without waiting.
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.
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.
| ID | Scenario | Persona | Path | Steps | Proposed test-IDs |
|---|---|---|---|---|---|
| S1 | Post-call: card tag + transcript-status pill on the Pipeline | P1 | 🟢 happy | 2 | — |
| S2 | Post-call: history shows Google Meet call + transcript; reminders removed | P1 | 🟢 happy | 2 | — |
| S3 | Manual Log-Call reschedule routes to Sales Call/Proposal when prep is done | P1 | 🟣 recovery | 1 | — |
| S4 | Open-in-Studio button present on BOTH Booked/Sales Call Prep and Sales Call/Proposal | P1 | 🟢 happy | 2 | — |
| S5 | Booking app: slot-list load AND confirmation both render fast (<2s) | P2 | 🟢 happy | 2 | — |
| S6 | Board-card pills/tags: readable contrast, bigger, uniform per column | P1 | 🟢 happy | 1 | — |
| S7 | Booking picker shows only AVAILABLE slots (no 'slot became occupied' error) | P2 | 🟡 edge | 2 | — |
| S8 | Real-time Pipeline notifications for ALL events, not just bookings | P1 | 🟢 happy | 1 | — |
| S9 | Do NOT delete the Google Meet event when booking a NEW second call | P1 | 🟡 edge | 2 | — |
| S10 | Fireflies bot-free recording — no prospect-facing consent prompt | P3 | 🟢 happy | 1 | — |
| S11 | Studio: auto-create on Booked → full-auto prep chain → Figma import (Figma MCP) | P3 | 🟢 happy | 4 | — |
| S12 | Studio: rep prep-review-and-fix loop (comment-edit → Save version → back to exportable) | P3 | 🟣 recovery | 3 | — |
| S13 | Studio: Deliverables panel — HTML export + embedded Figma + competitor FOMO deck; image-rewrite toggle OFF; Figma link to CRM | P3 | 🟢 happy | 4 | — |
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.
Trigger: A Google Meet sales call with a lead has just ended and Fireflies has the recording.
| # | Actor | UI element (clicked / seen) | Copy shown | System action | Resulting state | Branch to |
|---|---|---|---|---|---|---|
| 1 | system | The lead's board card in the Pipeline view, just after the Google Meet call ends | — | pipeline detects the sales call occurred (Fireflies/transcript hook) | call_occurred=true | — |
| 2 | system | The transcript-status pill on the same card after the transcript finishes processing | — | transcript ingest completes + links to the deal | transcript_ready=true | — |
Proposed acceptance test-IDs: —
| # | You do | You should see | Element that changes (copy · look · where) | What changes underneath | Must NOT happen | UX suggestions |
|---|---|---|---|---|---|---|
| 1 | The lead's board card in the Pipeline view, just after the Google Meet call ends | On 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 column | deal flagged call_occurred=true; transcript ingest pending | the 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. |
| 2 | The transcript-status pill on the same card after the transcript finishes processing | The 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' tag | transcript stored + linked to the deal | the 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. |
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
Trigger: The sales call happened; Mátyás opens the lead's history.
| # | Actor | UI element (clicked / seen) | Copy shown | System action | Resulting state | Branch to |
|---|---|---|---|---|---|---|
| 1 | user | Click '🕘 Előzmények' (history) on the lead card and expand the call entry | — | — | history rendered | — |
| 2 | system | The scheduled appointment-reminder email rows in the same history, after the call | — | on call-occurred, remove appointment-reminder rows + cancel any still-pending scheduled reminders | pending_reminders_cancelled | — |
Proposed acceptance test-IDs: —
| # | You do | You should see | Element that changes (copy · look · where) | What changes underneath | Must NOT happen | UX suggestions |
|---|---|---|---|---|---|---|
| 1 | Click '🕘 Előzmények' (history) on the lead card and expand the call entry | A 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 list | the call is logged in history as a Google Meet call with duration + the full transcript | the 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. |
| 2 | The scheduled appointment-reminder email rows in the same history, after the call | The 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 list | still-pending scheduled reminders are cancelled; if the booking was too soon for the full sequence, only the leftover reminders are removed | a 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. |
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
Trigger: A lead is in 'Booked / Sales Call Prep' with prep already done; Mátyás reschedules via the Log Call panel.
| # | Actor | UI element (clicked / seen) | Copy shown | System action | Resulting state | Branch to |
|---|---|---|---|---|---|---|
| 1 | user | On a Booked/Sales Call Prep card (prep_done=true), click 'Log Call' → 'Book Appointment', enter a new meeting time, save | — | manual reschedule via the Log-Call booking path | stage routed by prep_done | — |
Proposed acceptance test-IDs: —
| # | You do | You should see | Element that changes (copy · look · where) | What changes underneath | Must NOT happen | UX suggestions |
|---|---|---|---|---|---|---|
| 1 | On a Booked/Sales Call Prep card (prep_done=true), click 'Log Call' → 'Book Appointment', enter a new meeting time, save | The 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 column | because prep was already done, the reschedule routes to Sales Call/Proposal; callAt updated; old date replaced | the 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. |
flowchart TD S3U1(["On a Booked/Sales Call Prep card (prep_done=true), click 'Log C…"])
Trigger: A lead enters the Booked/Sales Call Prep stage and later Sales Call/Proposal.
| # | Actor | UI element (clicked / seen) | Copy shown | System action | Resulting state | Branch to |
|---|---|---|---|---|---|---|
| 1 | user | Look at a card the moment it enters the 'Booked / Sales Call Prep' column | — | — | card in appt_booked | — |
| 2 | user | Look at the same lead's card in the 'Sales Call / Proposal' column | — | — | card in sales_call | — |
Proposed acceptance test-IDs: —
| # | You do | You should see | Element that changes (copy · look · where) | What changes underneath | Must NOT happen | UX suggestions |
|---|---|---|---|---|---|---|
| 1 | Look at a card the moment it enters the 'Booked / Sales Call Prep' column | The '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 card | studio deep-link available for the deal | the 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. |
| 2 | Look at the same lead's card in the 'Sales Call / Proposal' column | The '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 card | studio deep-link available in this stage too | the 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. |
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
Trigger: A lead books a call on the public booking page.
| # | Actor | UI element (clicked / seen) | Copy shown | System action | Resulting state | Branch to |
|---|---|---|---|---|---|---|
| 1 | user | On the booking page, pick a date and watch the time-slot list load | — | — | slots loaded | — |
| 2 | user | Pick a time slot and click 'Foglalás megerősítése' | — | submit booking; heavy side-effects run off the response path | booking confirmed | — |
Proposed acceptance test-IDs: —
| # | You do | You should see | Element that changes (copy · look · where) | What changes underneath | Must NOT happen | UX suggestions |
|---|---|---|---|---|---|---|
| 1 | On the booking page, pick a date and watch the time-slot list load | The 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 area | slot availability fetched fast | a 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. |
| 2 | Pick 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-submit | submit→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. |
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
Trigger: Mátyás looks at the board cards (sequence pills, per-email pills, status tags).
| # | Actor | UI element (clicked / seen) | Copy shown | System action | Resulting state | Branch to |
|---|---|---|---|---|---|---|
| 1 | user | Look at the pills/tags on the board cards (e.g. 'Automated sequence', 'Email 1/2 (sent/unsent)', status tags) | — | — | — | — |
Proposed acceptance test-IDs: —
| # | You do | You should see | Element that changes (copy · look · where) | What changes underneath | Must NOT happen | UX suggestions |
|---|---|---|---|---|---|---|
| 1 | Look 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 columns | — | faint/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. |
flowchart TD S6U1(["Look at the pills/tags on the board cards (e.g. 'Automated sequ…"])
Trigger: A lead (or Mátyás) opens the booking or reschedule slot picker.
| # | Actor | UI element (clicked / seen) | Copy shown | System action | Resulting state | Branch to |
|---|---|---|---|---|---|---|
| 1 | user | Open the booking / reschedule slot picker and view the offered times | — | picker queries live availability and omits already-booked slots | only-free slots shown | — |
| 2 | system | The server response when two people race for the same slot | — | server-side slot-taken guard | race rejected | — |
Proposed acceptance test-IDs: —
| # | You do | You should see | Element that changes (copy · look · where) | What changes underneath | Must NOT happen | UX suggestions |
|---|---|---|---|---|---|---|
| 1 | Open the booking / reschedule slot picker and view the offered times | Only 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 pickers | an 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. |
| 2 | The server response when two people race for the same slot | In 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 picker | the server guard remains as a race backstop, just not normally hit | a 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. |
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
Trigger: Any pipeline-relevant event occurs while Mátyás watches the Pipeline view.
| # | Actor | UI element (clicked / seen) | Copy shown | System action | Resulting state | Branch to |
|---|---|---|---|---|---|---|
| 1 | system | The 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 view | live notification per event | — |
Proposed acceptance test-IDs: —
| # | You do | You should see | Element that changes (copy · look · where) | What changes underneath | Must NOT happen | UX suggestions |
|---|---|---|---|---|---|---|
| 1 | The 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 view | all listed events emit a real-time Pipeline notification, not only bookings | only 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. |
flowchart TD S8U1["The Pipeline view while events occur (new lead, inbound reply,…"]
Trigger: A lead already had a Google Meet call; a new meeting gets booked — either a reschedule or a genuinely new second call.
| # | Actor | UI element (clicked / seen) | Copy shown | System action | Resulting state | Branch to |
|---|---|---|---|---|---|---|
| 1 | user | Book a NEW (second) Google Meet call for the lead via Book Appointment (NOT a reschedule) | — | new-call booking path | second event created, prior kept | — |
| 2 | user | Perform an actual reschedule of an upcoming call (No-Show+Reschedule or reschedule action) | — | reschedule path | future event replaced | — |
Proposed acceptance test-IDs: —
| # | You do | You should see | Element that changes (copy · look · where) | What changes underneath | Must NOT happen | UX suggestions |
|---|---|---|---|---|---|---|
| 1 | Book 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 Calendar | a NEW (non-reschedule) booking keeps the prior calendar_event_id and adds a new event | the 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. |
| 2 | Perform 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 Calendar | the reschedule path (distinguished by action) deletes the prior upcoming event and creates the new one | a 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. |
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
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).
| # | Actor | UI element (clicked / seen) | Copy shown | System action | Resulting state | Branch to |
|---|---|---|---|---|---|---|
| 1 | user | Record the Google Meet via the Fireflies Chrome extension (Fireflies auto-join disabled), verified through Chrome DevTools | — | bot-free local capture; transcript ingests + links to the lead | transcript captured bot-free | — |
Proposed acceptance test-IDs: —
| # | You do | You should see | Element that changes (copy · look · where) | What changes underneath | Must NOT happen | UX suggestions |
|---|---|---|---|---|---|---|
| 1 | Record the Google Meet via the Fireflies Chrome extension (Fireflies auto-join disabled), verified through Chrome DevTools | No 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 it | Fireflies auto-join is OFF; capture is via the Chrome extension (or desktop app); the transcript still reaches the pipeline and links to the deal | a 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. |
flowchart TD S10U1(["Record the Google Meet via the Fireflies Chrome extension (Fire…"])
Trigger: A deal reaches the 'Booked an appointment' stage; Studio prepares the sales-call materials.
| # | Actor | UI element (clicked / seen) | Copy shown | System action | Resulting state | Branch to |
|---|---|---|---|---|---|---|
| 1 | system | The 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 | — |
| 2 | system | The Studio Lab run for the project (English UI) | — | full-auto prep chain runs: scrape → images → rankings → keywords → generate → fix → competitors → copyguide → refine | prep chain runs unattended | — |
| 3 | system | The Figma import step at the end of the prep chain | — | via 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 | — |
| 4 | user | Hover over the arrow between two prep steps in the Studio run | — | reveal per-step re-run controls | re-run available | — |
Proposed acceptance test-IDs: —
| # | You do | You should see | Element that changes (copy · look · where) | What changes underneath | Must NOT happen | UX suggestions |
|---|---|---|---|---|---|---|
| 1 | The 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 + Studio | Studio 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. |
| 2 | The 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 view | full_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. |
| 3 | The Figma import step at the end of the prep chain | A 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 Studio | HTMLs 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. |
| 4 | Hover over the arrow between two prep steps in the Studio run | Hovering 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 run | re-running recomputes from the chosen step onward | no 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. |
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
Trigger: Before the sales call, the rep reviews the prep materials and finds the generated HTML isn't good enough.
| # | Actor | UI element (clicked / seen) | Copy shown | System action | Resulting state | Branch to |
|---|---|---|---|---|---|---|
| 1 | user | Open Studio to the generated page from the board card | — | — | reviewing prep | — |
| 2 | user | In the commenter UI, put the current HTML version into the comment and use the comment feature to edit the mistakes in the frontend | — | comment-driven edit applies to the working-version draft | working draft updated | — |
| 3 | user | Click 'Save version' | — | save the new HTML version | version saved | — |
Proposed acceptance test-IDs: —
| # | You do | You should see | Element that changes (copy · look · where) | What changes underneath | Must NOT happen | UX suggestions |
|---|---|---|---|---|---|---|
| 1 | Open Studio to the generated page from the board card | The 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: Studio | rep is reviewing the working version | no 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. |
| 2 | In the commenter UI, put the current HTML version into the comment and use the comment feature to edit the mistakes in the frontend | Using 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 UI | the working-version draft is updated from the rep's comment-edit | the 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. |
| 3 | Click '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 view | a new HTML version is saved and is exportable alongside the other prep assets | no 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. |
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
Trigger: The prep assets are ready; the rep opens the deliverables view (English UI).
| # | Actor | UI element (clicked / seen) | Copy shown | System action | Resulting state | Branch to |
|---|---|---|---|---|---|---|
| 1 | user | Open the 'Deliverables' panel in Studio | — | — | deliverables shown | — |
| 2 | user | Open the competitor-SEO FOMO deck | — | render the competitor/keyword/ranking data into a client-facing HTML deck | deck available | — |
| 3 | system | The 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 safe | skip_image_swap=true by default | — |
| 4 | system | The deal's CRM record after the Figma file is created | — | write the Figma file URL to a CRM custom field | crm figma field set | — |
Proposed acceptance test-IDs: —
| # | You do | You should see | Element that changes (copy · look · where) | What changes underneath | Must NOT happen | UX suggestions |
|---|---|---|---|---|---|---|
| 1 | Open the 'Deliverables' panel in Studio | One 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 panel | export + Figma embed + competitor deck co-located in one panel | the 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. |
| 2 | Open the competitor-SEO FOMO deck | A 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 bundle | the deck is served at a share-token URL AND included in the export package | the 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. |
| 3 | The 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 step | image swap is skipped by default; when ON, the swap runs on pre-LLM HTML / a src-restore guard prevents the copy LLM from breaking images | refined 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. |
| 4 | The deal's CRM record after the Figma file is created | The 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 fields | a new CRM custom field carries the Figma link; a Studio→pipeline channel writes it back | the 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. |
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
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.
No copy index supplied.
| State | Meaning | Entered by | Exits to |
|---|---|---|---|
appt_booked | Booked / Sales Call Prep | booking / manual book / drag | sales_call (prep done) / back on reschedule |
sales_call | Sales Call / Proposal | prep done or manual reschedule when prep_done | won / lost / reschedule |
call_occurred | the Google Meet sales call has happened | Fireflies/transcript hook | transcript_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.