diff --git a/packages/shared/src/features/onboarding/steps/FunnelPersonaQuiz.module.css b/packages/shared/src/features/onboarding/steps/FunnelPersonaQuiz.module.css index 1b00cc35f6..53fedf2d56 100644 --- a/packages/shared/src/features/onboarding/steps/FunnelPersonaQuiz.module.css +++ b/packages/shared/src/features/onboarding/steps/FunnelPersonaQuiz.module.css @@ -42,15 +42,507 @@ } .revealName { - animation: reveal-rise 0.5s ease 0.15s both; + animation: reveal-rise 0.5s ease 0.5s both; } .revealTagline { - animation: reveal-rise 0.5s ease 0.3s both; + animation: reveal-rise 0.5s ease 0.64s both; } .revealActions { - animation: reveal-rise 0.5s ease 0.45s both; + animation: reveal-rise 0.5s ease 0.78s both; +} + +/* ─── Reveal celebration ────────────────────────────────────────────────── + * The genie's verdict lands as an event: a glowing persona "amulet" springs + * in, a shockwave ring snaps out, spokes of light spin behind it, and a burst + * of brand-coloured confetti scatters. `--persona` (the persona's brand colour) + * is set inline on the .emblem and inherited by every layer. */ +.emblem { + position: relative; + display: grid; + place-items: center; + width: 9rem; + height: 9rem; +} + +@keyframes emblem-pop { + 0% { + transform: scale(0) rotate(-28deg); + opacity: 0; + } + 62% { + transform: scale(1.14) rotate(6deg); + opacity: 1; + } + 100% { + transform: scale(1) rotate(0); + opacity: 1; + } +} + +@keyframes emblem-glow { + 0%, + 100% { + box-shadow: 0 0 0 1px + color-mix(in srgb, var(--persona) 55%, transparent), + 0 14px 44px -10px color-mix(in srgb, var(--persona) 55%, transparent); + } + 50% { + box-shadow: 0 0 0 1px color-mix(in srgb, var(--persona) 85%, transparent), + 0 18px 64px -8px color-mix(in srgb, var(--persona) 85%, transparent); + } +} + +.emblemCoin { + position: relative; + z-index: 2; + display: grid; + place-items: center; + width: 7rem; + height: 7rem; + border-radius: 9999px; + background: radial-gradient( + circle at 36% 28%, + color-mix(in srgb, var(--persona) 10%, white) 0%, + transparent 46% + ), + color-mix(in srgb, var(--persona) 32%, var(--theme-surface-float)); + border: 1px solid color-mix(in srgb, var(--persona) 65%, transparent); + animation: emblem-pop 0.6s cubic-bezier(0.18, 0.9, 0.32, 1.4) both, + emblem-glow 2.6s ease-in-out 0.65s infinite; +} + +.emblemEmoji { + font-size: 3.25rem; + line-height: 1; + filter: drop-shadow(0 3px 8px rgb(0 0 0 / 0.4)); +} + +@keyframes shockwave { + 0% { + transform: scale(0.55); + opacity: 0.85; + } + 100% { + transform: scale(2.7); + opacity: 0; + } +} + +.emblemFlash { + position: absolute; + z-index: 1; + width: 7rem; + height: 7rem; + border-radius: 9999px; + border: 2px solid color-mix(in srgb, var(--persona) 70%, transparent); + animation: shockwave 0.85s ease-out 0.1s both; +} + +/* Firework burst: glowing dots (same family as the floating dust) explode + * outward from the emblem centre, decelerate, sag a touch with gravity, then + * fade — like a firework going off where the icon is. */ +@keyframes firework { + 0% { + transform: translate(-50%, -50%) scale(0.3); + opacity: 0; + } + 12% { + opacity: 1; + } + 70% { + opacity: 1; + } + 100% { + transform: translate(calc(-50% + var(--dx)), calc(-50% + var(--dy))) + scale(0.6); + opacity: 0; + } +} + +.fireworkSpark { + position: absolute; + left: 50%; + top: 50%; + z-index: 0; + width: var(--sw, 5px); + height: var(--sw, 5px); + border-radius: 9999px; + background: var(--sc); + box-shadow: 0 0 10px 1px color-mix(in srgb, var(--sc) 65%, transparent); + animation: firework var(--sd, 1.3s) cubic-bezier(0.12, 0.75, 0.25, 1) + var(--sdelay, 0s) both; +} + +/* ─── Casino / arcade micro-interactions ────────────────────────────────── + * Patchy is a genie, so the whole step leans into a "make a wish" slot-machine + * feel: the primary CTA breathes a neon halo and flashes a shine sweep on + * hover, the yes/no answers behave like tactile chips with a color-coded glow, + * and the option cards light up as you reach for them. Everything is paired + * with cheap transform/opacity work and fully disabled under reduced motion. */ + +/* White CTA sitting in a spotlight: a soft luminous halo that breathes, so the + * button reads as the lit object on the stage. Neutral white light with the + * faintest cabbage rim — never tints the white fill. */ +@keyframes cta-pulse { + 0%, + 100% { + box-shadow: 0 10px 34px -16px rgb(255 255 255 / 35%); + } + 50% { + box-shadow: 0 12px 42px -14px rgb(255 255 255 / 55%), + 0 0 24px -6px + color-mix(in srgb, var(--theme-accent-cabbage-default) 45%, transparent); + } +} + +@keyframes shine-sweep { + from { + transform: translateX(-180%) skewX(-16deg); + } + to { + transform: translateX(320%) skewX(-16deg); + } +} + +@keyframes bar-shimmer { + to { + background-position: -200% 0; + } +} + +@keyframes tick-pop { + 0% { + transform: scale(0.4); + opacity: 0; + } + 60% { + transform: scale(1.18); + } + 100% { + transform: scale(1); + opacity: 1; + } +} + +@keyframes aurora-drift { + from { + transform: translate(-58%, -3%) scale(1); + } + to { + transform: translate(-42%, 5%) scale(1.08); + } +} + +@keyframes star-twinkle { + 0%, + 100% { + opacity: 0.35; + } + 50% { + opacity: 0.7; + } +} + +/* "Stage" backdrop. Full-bleed via `fixed` so it never gets clipped by the + * content column, and sits behind the content through a negative z-index inside + * the isolated stage. A faint pool of lamp-light glows up from the base and a + * vignette pulls focus to the centre — the top stays clean and dark. */ +.stageBackdrop { + position: fixed; + inset: 0; + z-index: -1; + pointer-events: none; + overflow: hidden; + background: radial-gradient( + 120% 95% at 50% 32%, + transparent 52%, + rgb(0 0 0 / 55%) 100% + ), + radial-gradient( + 46% 36% at 50% 104%, + color-mix(in srgb, var(--theme-accent-cabbage-default) 18%, transparent), + transparent 72% + ); +} + +/* Slow-drifting aurora blob rising from the base — gives the lamp-light life + * and a colour shift without lighting up the top of the screen. */ +.stageBackdrop::before { + content: ''; + position: absolute; + left: 50%; + bottom: -28%; + width: 90vw; + height: 60vh; + transform: translate(-50%, 0); + background: radial-gradient( + closest-side, + color-mix(in srgb, var(--theme-accent-cabbage-default) 24%, transparent), + transparent + ); + filter: blur(48px); + animation: aurora-drift 16s ease-in-out infinite alternate; +} + +/* Sparse "magic dust" starfield — subtle, masked to the stage centre. */ +.stageBackdrop::after { + content: ''; + position: absolute; + inset: 0; + background-image: radial-gradient( + 1.5px 1.5px at 18% 24%, + color-mix(in srgb, var(--theme-text-primary) 55%, transparent), + transparent + ), + radial-gradient( + 1.5px 1.5px at 72% 16%, + color-mix(in srgb, var(--theme-text-primary) 45%, transparent), + transparent + ), + radial-gradient( + 1px 1px at 84% 60%, + color-mix(in srgb, var(--theme-text-primary) 45%, transparent), + transparent + ), + radial-gradient( + 1px 1px at 30% 72%, + color-mix(in srgb, var(--theme-text-primary) 40%, transparent), + transparent + ), + radial-gradient( + 1.5px 1.5px at 58% 84%, + color-mix(in srgb, var(--theme-text-primary) 40%, transparent), + transparent + ), + radial-gradient( + 1px 1px at 8% 54%, + color-mix(in srgb, var(--theme-text-primary) 40%, transparent), + transparent + ); + animation: star-twinkle 5s ease-in-out infinite; + mask-image: radial-gradient(75% 70% at 50% 35%, #000, transparent 80%); +} + +/* Second aurora in a cooler hue. It drifts the opposite way and breathes its + * opacity out of phase with the cabbage one, so the spotlight slowly shifts + * colour — purple → blue → purple — like magic settling over the stage. */ +@keyframes aurora-shift { + 0%, + 100% { + opacity: 0.25; + transform: translate(-38%, 4%) scale(1); + } + 50% { + opacity: 0.6; + transform: translate(-58%, -4%) scale(1.12); + } +} + +.auroraAlt { + position: absolute; + left: 50%; + bottom: -30%; + width: 80vw; + height: 58vh; + background: radial-gradient( + closest-side, + color-mix(in srgb, var(--theme-accent-blueCheese-default) 26%, transparent), + transparent + ); + filter: blur(54px); + animation: aurora-shift 13s ease-in-out infinite; +} + +/* Floating "magic dust": specks that lift off the bottom edge, drift steadily + * up, and fade out by the time they reach ~25% of the screen height. Linear + * timing keeps them continuously moving (never parked mid-screen). */ +@keyframes particle-rise { + 0% { + transform: translateY(0) scale(0.5); + opacity: 0; + } + 12% { + opacity: 1; + } + 70% { + opacity: 0.9; + } + 100% { + transform: translateY(-26vh) scale(1); + opacity: 0; + } +} + +.magicParticle { + position: absolute; + bottom: 0; + width: 4px; + height: 4px; + border-radius: 9999px; + background: color-mix(in srgb, var(--theme-accent-cabbage-default) 75%, white); + box-shadow: 0 0 8px 1px + color-mix(in srgb, var(--theme-accent-cabbage-default) 60%, transparent); + animation: particle-rise var(--particle-duration, 6s) linear infinite; + animation-delay: var(--particle-delay, 0s); +} + +/* Thought-cloud connector: glassy circles that trail from the panel toward + * Patchy, so the message reads as coming from the avatar. */ +.bubbleDot { + border-radius: 9999px; + background: color-mix(in srgb, var(--theme-surface-float) 50%, transparent); + backdrop-filter: blur(18px) saturate(1.1); + -webkit-backdrop-filter: blur(18px) saturate(1.1); + border: 1px solid + color-mix(in srgb, var(--theme-text-primary) 12%, transparent); +} + +/* Frosted-glass panel for Patchy's lines: translucent, blurred, with a glass + * top-edge highlight. Replaces the flat bordered speech bubble. */ +.panel { + border-radius: 24px; + background: color-mix(in srgb, var(--theme-surface-float) 50%, transparent); + backdrop-filter: blur(18px) saturate(1.1); + -webkit-backdrop-filter: blur(18px) saturate(1.1); + border: 1px solid + color-mix(in srgb, var(--theme-text-primary) 12%, transparent); + box-shadow: 0 28px 64px -34px rgb(0 0 0 / 65%), + inset 0 1px 0 0 color-mix(in srgb, var(--theme-text-primary) 10%, transparent); +} + +/* Primary "play" button: a living halo plus a shine that sweeps across on + * hover. overflow-hidden clips the shine; the pseudo-element never eats + * pointer events so the click target is unchanged. */ +.cta { + position: relative; + overflow: hidden; + isolation: isolate; + animation: cta-pulse 2.6s ease-in-out infinite; +} + +.cta::after { + content: ''; + position: absolute; + top: 0; + bottom: 0; + left: 0; + width: 36%; + transform: translateX(-180%) skewX(-16deg); + background: linear-gradient( + 90deg, + transparent, + rgb(255 255 255 / 45%), + transparent + ); + pointer-events: none; +} + +.cta:hover::after { + animation: shine-sweep 0.8s ease-out; +} + +/* Yes / No answers. Flat — no tile background or border. Just a colour-filled + * circle (the icon) beside a plain label; the two circles sit close together in + * the middle with the labels flanking the outer edges. On hover the circle + * fills solid, glows and lifts. */ +.answer { + background: transparent; + border: none; + transition: transform 0.18s ease; +} + +/* Icon circle: a colour-tinted disc that brightens to a solid fill on hover. */ +.answerBadge { + display: inline-flex; + align-items: center; + justify-content: center; + border-radius: 9999px; + transition: transform 0.2s ease, background-color 0.2s ease, color 0.2s ease, + box-shadow 0.2s ease; +} + +.answerYes .answerBadge { + background: color-mix(in srgb, var(--theme-accent-avocado-default) 22%, transparent); + color: var(--theme-accent-avocado-default); +} + +.answerNo .answerBadge { + background: color-mix(in srgb, var(--theme-accent-ketchup-default) 22%, transparent); + color: var(--theme-accent-ketchup-default); +} + +/* Scaling the badge (not the svg) keeps the downvote's `rotate-180` intact. */ +.answerYes:hover .answerBadge { + background: var(--theme-accent-avocado-default); + color: var(--theme-surface-invert); + transform: scale(1.08); + box-shadow: 0 0 28px -4px + color-mix(in srgb, var(--theme-accent-avocado-default) 75%, transparent); +} + +.answerNo:hover .answerBadge { + background: var(--theme-accent-ketchup-default); + color: var(--theme-surface-invert); + transform: scale(1.08); + box-shadow: 0 0 28px -4px + color-mix(in srgb, var(--theme-accent-ketchup-default) 75%, transparent); +} + +/* "Not sure": a clearly secondary ghost pill — visible, but lighter than the + * answer tiles. Dashed hairline + muted label that warms on hover. */ +.notSure { + border-radius: 9999px; + border: 1px dashed + color-mix(in srgb, var(--theme-text-primary) 22%, transparent); + background: color-mix(in srgb, var(--theme-surface-float) 30%, transparent); + color: var(--theme-text-secondary); + transition: transform 0.16s ease, color 0.18s ease, border-color 0.18s ease, + background-color 0.18s ease; +} + +.notSure:hover { + color: var(--theme-text-primary); + border-color: color-mix(in srgb, var(--theme-text-primary) 40%, transparent); + background: color-mix(in srgb, var(--theme-surface-float) 55%, transparent); +} + +/* Persona / option cards: reach-for-it glow + emoji wink. */ +.card { + transition: transform 0.2s ease, box-shadow 0.2s ease, border-color 0.2s ease; +} + +.card:hover { + box-shadow: 0 14px 34px -16px + color-mix(in srgb, var(--theme-accent-cabbage-default) 90%, transparent); +} + +.cardEmoji { + transition: transform 0.2s ease; +} + +.card:hover .cardEmoji { + transform: scale(1.16) rotate(-6deg); +} + +/* Selected modifier tick. */ +.tick { + animation: tick-pop 0.28s ease both; +} + +/* Progress fill: a slow gold→grape shimmer so the bar feels alive while it + * fills, not a static block. */ +.progressFill { + background-image: linear-gradient( + 90deg, + var(--theme-accent-cabbage-default), + var(--theme-accent-bacon-default), + var(--theme-accent-cheese-default), + var(--theme-accent-cabbage-default) + ); + background-size: 200% 100%; + animation: bar-shimmer 3s linear infinite; } @media (prefers-reduced-motion: reduce) { @@ -58,7 +550,26 @@ .dot, .revealName, .revealTagline, - .revealActions { + .revealActions, + .cta, + .progressFill, + .tick, + .stageBackdrop::before, + .stageBackdrop::after, + .auroraAlt, + .magicParticle, + .emblemCoin, + .emblemFlash { animation: none; } + + .magicParticle, + .emblemFlash, + .fireworkSpark { + display: none; + } + + .cta::after { + display: none; + } } diff --git a/packages/shared/src/features/onboarding/steps/FunnelPersonaQuiz.tsx b/packages/shared/src/features/onboarding/steps/FunnelPersonaQuiz.tsx index 5187b25125..61bf9eb229 100644 --- a/packages/shared/src/features/onboarding/steps/FunnelPersonaQuiz.tsx +++ b/packages/shared/src/features/onboarding/steps/FunnelPersonaQuiz.tsx @@ -11,10 +11,10 @@ import type { FunnelStepPersonaQuiz } from '../types/funnel'; import { FunnelStepTransitionType } from '../types/funnel'; import { withIsActiveGuard } from '../shared/withActiveGuard'; import { - Button, ButtonSize, + ButtonV2, ButtonVariant, -} from '../../../components/buttons/Button'; +} from '../../../components/buttons/ButtonV2'; import { Typography, TypographyColor, @@ -22,6 +22,7 @@ import { TypographyType, } from '../../../components/typography/Typography'; import { DownvoteIcon, UpvoteIcon } from '../../../components/icons'; +import { IconSize } from '../../../components/Icon'; import { usePersonaQuiz } from './persona/usePersonaQuiz'; import type { AnswerValue } from './persona/engine'; import type { DeveloperPersona } from './persona/data'; @@ -297,21 +298,30 @@ const SpeechBubble = ({ }): ReactElement => (
{children} - {/* On mobile Patchy sits above the bubble, so the tail points up. */} + {/* Thought-cloud trailing toward Patchy: up on mobile (he sits above), + * out to the right on laptop (he sits beside). */} - {/* On laptop Patchy sits to the right, so the tail points right. */} + className="absolute bottom-full left-1/2 mb-2 flex -translate-x-1/2 flex-col-reverse items-center gap-1.5 laptop:hidden" + > + + + + + className="absolute left-full top-1/2 ml-3 hidden -translate-y-1/2 items-center gap-2 laptop:flex" + > + + + +
); @@ -323,6 +333,74 @@ interface QuizStageProps { children: ReactNode; } +// Fixed configs (left column / size / timing) so the floating dust is stable +// across SSR and re-renders instead of jumping on every paint. +const MAGIC_PARTICLES = [ + { left: '10%', size: 3, delay: '0s', duration: '5s' }, + { left: '22%', size: 5, delay: '1.6s', duration: '6.2s' }, + { left: '34%', size: 3, delay: '3.2s', duration: '4.6s' }, + { left: '44%', size: 4, delay: '0.8s', duration: '5.6s' }, + { left: '52%', size: 6, delay: '2.4s', duration: '6.8s' }, + { left: '61%', size: 3, delay: '4s', duration: '5.2s' }, + { left: '70%', size: 5, delay: '0.4s', duration: '6s' }, + { left: '79%', size: 4, delay: '3s', duration: '4.4s' }, + { left: '88%', size: 3, delay: '1.2s', duration: '6.4s' }, + { left: '16%', size: 4, delay: '3.8s', duration: '5.4s' }, + { left: '66%', size: 3, delay: '4.6s', duration: '4.8s' }, + { left: '93%', size: 5, delay: '2s', duration: '7s' }, +]; + +// Reveal firework: glowing dots (same family as the floating dust) explode +// radially from the emblem centre. Generated once (deterministic, no +// randomness) so it's SSR-stable. +const FIREWORK_COLORS = [ + 'var(--theme-accent-cabbage-default)', + 'var(--theme-accent-cabbage-bolder)', + 'var(--theme-accent-cabbage-subtler)', + 'var(--theme-accent-onion-default)', + 'var(--theme-accent-onion-bolder)', + 'var(--theme-accent-onion-subtler)', +]; + +const REVEAL_FIREWORK = Array.from({ length: 30 }, (_, index) => { + // Even radial spread + slight per-spoke jitter so it reads organic. + const angle = (index / 30) * Math.PI * 2 + (index % 2 ? 0.12 : -0.12); + const distance = 95 + (index % 4) * 48; // 95 → 239px rings + const gravity = 24 + (index % 3) * 16; // gentle downward sag + return { + id: index, + dx: `${Math.round(Math.cos(angle) * distance)}px`, + dy: `${Math.round(Math.sin(angle) * distance + gravity)}px`, + sw: `${4 + (index % 3) * 2}px`, + sc: FIREWORK_COLORS[index % FIREWORK_COLORS.length], + sd: `${1.1 + (index % 4) * 0.2}s`, + sdelay: `${(index % 3) * 0.05}s`, + }; +}); + +// Decorative spotlight-stage layer: a colour-shifting aurora plus floating +// "magic dust" rising from the lamp. Purely presentational, behind content. +const StageBackdrop = (): ReactElement => ( +
+ + {MAGIC_PARTICLES.map((particle) => ( + + ))} +
+); + // Shared skeleton for the intro, question and reveal screens: a top progress // header (reserved on every screen) above the bubble + Patchy. On mobile Patchy // stacks on top with actions anchored to the bottom thumb zone; on laptop they @@ -332,7 +410,8 @@ const QuizStage = ({ mascot, children, }: QuizStageProps): ReactElement => ( -
+
+
@@ -385,12 +467,16 @@ const PersonaCard = ({ key={persona.id} type="button" onClick={() => onSelect(persona.id)} - className="flex flex-col items-center gap-2 rounded-16 border-2 border-border-subtlest-tertiary bg-surface-float p-6 text-center transition-all hover:-translate-y-1 hover:border-accent-cabbage-default tablet:p-8" + className={classNames( + styles.card, + 'flex flex-col items-center gap-2 rounded-16 border-2 border-border-subtlest-tertiary bg-surface-float p-6 text-center hover:-translate-y-1 hover:border-accent-cabbage-default active:translate-y-0 active:scale-[0.98] tablet:p-8', + )} > {persona.emoji} @@ -410,6 +496,42 @@ const PersonaCard = ({ ); +// The celebratory persona "amulet" for the reveal: a glowing coin in the +// persona's brand colour with a shockwave ring, and a firework of glowing dots +// that explodes outward from the icon. `--persona` cascades to every layer. +const PersonaEmblem = ({ + persona, +}: { + persona: DeveloperPersona; +}): ReactElement => ( +
+ + {REVEAL_FIREWORK.map((spark) => ( + + ))} + + {persona.emoji} + +
+); + function FunnelPersonaQuizComponent({ parameters: { headline, explainer, cta, mascotVideoBaseUrl }, onTransition, @@ -439,24 +561,6 @@ function FunnelPersonaQuizComponent({ // Which clip plays during the thinking beat, chosen per answer. const [thinkingClip, setThinkingClip] = useState('thinking'); - // On the reveal we hold the answer back until Patchy finishes his animation. - const [revealReady, setRevealReady] = useState(false); - - useEffect(() => { - if (phase !== 'reveal') { - return undefined; - } - setRevealReady(false); - // Patchy now plays the reveal on every breakpoint, so wait for his - // animation whenever there is a video to wait for. - if (!mascotVideoBaseUrl) { - setRevealReady(true); - return undefined; - } - // Fallback in case the video never reports progress (e.g. blocked autoplay). - const timeout = setTimeout(() => setRevealReady(true), 2500); - return () => clearTimeout(timeout); - }, [phase, mascotVideoBaseUrl]); const handleAnswer = (value: AnswerValue) => { if (isThinking) { @@ -515,23 +619,27 @@ function FunnelPersonaQuizComponent({
- - +
@@ -542,8 +650,9 @@ function FunnelPersonaQuizComponent({ return (
+ Who are you, really? @@ -559,10 +668,16 @@ function FunnelPersonaQuizComponent({ key={persona.id} type="button" onClick={() => selectPersona(persona.id)} - className="flex w-full items-center gap-4 rounded-16 border border-border-subtlest-tertiary bg-surface-float p-4 text-left transition-colors hover:border-accent-cabbage-default" + className={classNames( + styles.card, + 'flex w-full items-center gap-4 rounded-16 border border-border-subtlest-tertiary bg-surface-float p-4 text-left hover:translate-x-1 hover:border-accent-cabbage-default active:scale-[0.99]', + )} > {persona.emoji} @@ -673,15 +788,15 @@ function FunnelPersonaQuizComponent({ /> ))}
- +
); @@ -731,13 +846,19 @@ function FunnelPersonaQuizComponent({ aria-checked={checked} onClick={() => toggleModifier(modifier.id)} className={classNames( - 'flex w-full items-center gap-4 rounded-16 border-2 p-4 text-left transition-colors', + styles.card, + 'flex w-full items-center gap-4 rounded-16 border-2 p-4 text-left active:scale-[0.99]', checked ? 'border-accent-cabbage-default bg-surface-float' - : 'border-border-subtlest-tertiary bg-surface-float hover:border-text-quaternary', + : 'border-border-subtlest-tertiary bg-surface-float hover:translate-x-1 hover:border-accent-cabbage-default', )} > - + {modifier.emoji} @@ -753,21 +874,24 @@ function FunnelPersonaQuizComponent({ - {checked ? '✓' : ''} + {checked && } ); })}
- - - - - )} +
+ + + {personaRevealPhrase(persona.name)} + + + {persona.tagline} + +
+ + {cta || "Yes, that's me!"} + + + Nah, I'll pick myself + +
); @@ -890,47 +1012,68 @@ function FunnelPersonaQuizComponent({ {questionText} -
+
-
- - + + + + + + No + +
- + + Not sure + +
{isThinking && ( diff --git a/packages/webapp/pages/onboarding-persona-demo.tsx b/packages/webapp/pages/onboarding-persona-demo.tsx index 3194a06e95..cafdc0714c 100644 --- a/packages/webapp/pages/onboarding-persona-demo.tsx +++ b/packages/webapp/pages/onboarding-persona-demo.tsx @@ -26,7 +26,7 @@ function PersonaQuizDemo(): ReactElement { type: FunnelStepType.PersonaQuiz, isActive: true, parameters: { - backgroundType: FunnelBackgroundVariant.Default, + backgroundType: FunnelBackgroundVariant.Blank, mascotVideoBaseUrl: '/onboarding/patchy', }, transitions: [],