feat(varitea-landing): motion-led landing + business-email-only conversion#17
Open
ninan-versioning wants to merge 1 commit into
Open
feat(varitea-landing): motion-led landing + business-email-only conversion#17ninan-versioning wants to merge 1 commit into
ninan-versioning wants to merge 1 commit into
Conversation
…rsion Dogfood Varitea landing page. Hero embeds @shoploop/twin-renderer (typed stub + alias until the real package lands). Waitlist conversion is gated to business email: client check for instant feedback, server re-validates as the source of truth (shape + free-provider + disposable + DNS MX), subscribes to Klaviyo (409 = success), backs up to var/waitlist.jsonl, and fires a GA4 waitlist_submit event with email_domain only. Generic 200 to the client for existence-revealing rejects to avoid enumeration; specific reasons logged. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
New Next.js 15 app at
apps/varitea-landing/— the motion-led Varitea dogfood landing, with conversion gated to business email only. Text guides; images / video / the 3D twin are the medium.The hero embeds the parallel
@shoploop/twin-renderer. Until that package lands on disk it resolves to a typed stub (lib/twin-renderer.stub.tsx) via an alias intsconfig.json/vitest.config.ts. Swapping in the real renderer = add the dep, delete the stub, drop the aliases (TODO noted in-file).Page sections
<ProductTwin>(auto-rotate, pauses on interaction, subtle scroll drift). One-line headline + subline; bottom-right "Get early access" scrolls to#reserve.google_drive). A journey, not a feature list.<ProductTwin>+<VariantSelector>; loose-leaf flavors switch the twin live.Conversion gate rationale
Business-email-only is a positioning move, not a security one: we're starting with operators and teams, so free/consumer and disposable mailboxes get warm rejection copy ("please use a work email"). The serious-operator filter is the message.
Validation runs twice:
EmailGate.tsx) — HTML5type=email+ regex + free-provider check for instant feedback. Never trusted.app/api/waitlist/route.ts, source of truth) — same shape + free + disposable checks, then DNS MX lookup (lib/mx.ts, skippable viaWAITLIST_SKIP_MX=true), then Klaviyo subscribe (409 = success, idempotent), then best-effort append tovar/waitlist.jsonl.BLOCKED_FREE_DOMAINSis a single editable array inlib/email-gate.ts; disposable domains are a vendored snapshot (source cited in-file).Response contract: always 200.
{ ok: true }on success. Rejections return{ ok: false }— exceptfree_domain/invalid_shape(client-actionable, reveal nothing about mailbox existence) which includereason.disposable/no_mx/klaviyo_errorare logged server-side only to avoid email enumeration + infra leakage.GA4:
waitlist_submitfires client-side after success withemail_domainonly — never the full address.Env vars
KLAVIYO_API_KEYWAITLIST_LIST_IDWAITLIST_SKIP_MXtrueskips DNS MX (CI/test)NEXT_PUBLIC_GA4_IDAccessibility checklist
prefers-reduced-motiondisables auto-rotate, scroll transforms, smooth scroll, video autoplayrole="img"+aria-label("Interactive 3D product view …")role="alert"+aria-invalid+aria-describedbyradiogroupVerification
pnpm typecheck✓ ·pnpm lint✓ ·pnpm test✓ (40 tests: email-gate, mx, route happy-path + every reject reason + Klaviyo error + MX-skip flag, Hero mount/CTA) ·pnpm build✓ · dev server smoke-tested (home 200, API reject paths correct).Decision gate
Screenshots
🤖 Generated with Claude Code