Template
Oblaan
Before a fundraiser organiser is sent to an external payments partner to verify identity and link a bank, this interstitial explains why and reassures them about security. It turns an abrupt domain change into an expected, trusted step.
Redirect-to-partner interstitial with trust points · App screen: confirmation · Small tools and apps · full-stack app (auth + DB)
A mock-up of the screen, drawn from its layout, palette and typefaces. A build follows the full prompt below.
Start from this screenRead the build prompt
Typefaces
The catalog's own faces. A screen composed into a template is drawn in that template's typefaces.
- FigtreeHeadings: Figtree 700 22px headline, -0.01em, line-height 1.3
- FigtreeBody: Figtree 400 16px / 1.5; trust titles 16px 700
Patterns
- handoff interstitial before third-party redirect
- icon + heading + one-line trust bullets
- single full-width dark primary button naming the destination
- back button in rounded square
- centered wordmark header
States it is designed for
- ready
- creating session (button busy)
- error creating session
- returned: verified
- returned: pending review
- returned: action required with reason
- already verified (interstitial skipped)
Who it is for
- fundraiser organisers withdrawing money
- first-time users completing identity checks
Layout
- Header: centred wordmark with a 1px bottom border
- Content column (max 440px) offset right of a back button on desktop: headline over two lines
- Two trust rows: circular tinted icon (lock, check) + bold title + one-line explanation
- Full-width dark rounded button 'Continue to <partner>'
- Help bubble fixed bottom-right
- Mobile: back button sits above the headline; button pinned to bottom with safe-area padding
Palette
Calm, reassuring, minimal - a pause before leaving the product.
- page
#ffffff - text
#2b2b2b - muted text
#5f6368 - primary
#333333 - on primary
#ffffff - icon circle
#e6f0ef - icon
#1f6f68 - brand green
#02a95c - border
#dcdcdc - focus ring
#1f6f68
Every checked pair, measured again
| Sample | Where | Ratio | Needs |
|---|---|---|---|
| Aa | headline on white | 14.16:1 | 4.5:1 |
| Aa | muted explanation on white | 6.05:1 | 4.5:1 |
| Aa | button label on dark | 12.63:1 | 4.5:1 |
| icon on tinted circle | 5.12:1 | 3:1 | |
| focus ring on white | 5.95:1 | 3:1 | |
| back button border on white | 6.05:1 | 3:1 |
As vibld’s tokens
The palette on the fifteen colour tokens vibld styles a project with, each text colour on the fill it is read on. Marked tokens are solved from the palette, because no swatch held that role at 4.5:1.
- background
- card
- muted
- primary
- secondary
- accent
- destructive *
Type scale
- Display
- Figtree 700 22px headline, -0.01em, line-height 1.3
- Body
- Figtree 400 16px / 1.5; trust titles 16px 700
Similar to the observed rounded grotesk.
Spacing and imagery
Airy; 4px base, 64px top margin, 24px between trust rows, 32px before the button; radius 10px on button and back button; no shadows.
Two 36px circular tinted icon badges only.
Components
- CenteredHeader
- BackButton
- InterstitialHeadline
- TrustPoint (icon badge, title, text)
- ContinueButton
- HelpBubble
Interactions
- Continue shows a spinner, creates a partner onboarding session, then does a full-page redirect
- Back returns to the withdrawal screen
- If the session URL fails to create, an inline error appears above the button with Try again
- Returning from the partner lands on a status page (verified, pending, needs more info)
Data
Organizer{id, user_id, verification_status (none|pending|verified|action_required)}PartnerSession{id, organizer_id, url, expires_at, created_at}Payout{id, organizer_id, amount, status}
Guardrails
Experience
- Say why the user is leaving and who they are going to, before the click
- Keep reassurance to two short points
- One button only; Back is secondary and iconic
- Never open the partner in a new tab by surprise
Accessibility
- Headline is the page h1; trust points are a list
- Button text names the destination so users know they are leaving
- Icons are decorative (aria-hidden) because titles carry the meaning
- Visible focus ring on back and continue buttons
- Return page status is announced in a live region
Security
- Create partner sessions server-side only; keep the partner secret in function secrets
- Validate the return request (state token) before trusting status
- Only the organiser can start verification for their own account (RLS)
- Collect no identity data in this app - the partner does
- Log verification attempts for support
Build prompt
The baseline every prompt in the catalog assumes, then this design’s own ten sections, from goal to guardrails.
The baseline
### How to use these prompts Paste an entry's build prompt into your coding agent as the first message. Each prompt names its own stack, tokens and acceptance criteria; the rules below apply to all of them and can be prepended once per project. ### Engineering baseline - TypeScript strict mode, no `any`, small typed components, feature folders, and one source of truth for design tokens (CSS variables consumed by Tailwind). - Validate every input with a shared zod schema on the client and again on the server or edge function. Never trust client-side checks alone. - Show loading, empty and error states for every async view. Surface errors in plain language with a retry, and log details to the console in development only. - Keep secrets out of the bundle. Only publishable keys (for example a Supabase anon key) belong in client code; service-role keys, API keys and webhooks live in server or edge-function environment variables. ### Data and auth baseline (full-stack entries) - Enable Row Level Security on every table before inserting data. Default-deny, then add owner-scoped policies (`auth.uid() = user_id`) and explicit role checks for admin views. - Store roles in a separate table checked by a security-definer function, never in a user-editable profile field. - Upload files to private storage buckets with size and MIME limits, and serve them through signed URLs. - Rate-limit public endpoints (forms, auth, AI calls) and add a honeypot field or captcha to anonymous forms. - Take payments through a hosted checkout and verify webhooks by signature. Never handle raw card data. ### Accessibility and UX baseline - Target WCAG 2.2 AA: 4.5:1 contrast for normal text and 3:1 for large text, input borders, focus rings and meaningful icons or chart lines. Every palette in this catalog lists its verified pairs; re-check with a contrast tool after any colour change. - Keep body text at 16px or larger with 1.5 line height, nothing below 12px, no light weights under 24px, and uppercase only for short labels. - Give every interactive element a visible focus ring, full keyboard support, semantic landmarks, labelled form fields, and alt text on meaningful images. - Respect `prefers-reduced-motion` for every animation. Give drag-and-drop and carousels keyboard and button alternatives. - Build mobile-first and test at 375px, 768px and 1280px. ### Content guardrails - Use original copy, fictional sample data and placeholder or licensed imagery. Do not reuse another product's name, logo, screenshots or marketing text. - Label demo testimonials and metrics as samples. Collect the minimum personal data the feature needs. ### SaaS screen baseline - Design every screen for its full set of states: first-run empty, loading skeleton, partial data, error with retry, permission-denied, and success feedback. Each entry lists the states its screen needs. - Keep destructive actions (delete, revoke, downgrade, remove member) behind a confirmation that names the object, and prefer undo over a second dialog where the action is reversible. - Enforce authorisation on the server for every action a screen exposes. Hiding a button is not access control; check the role again in the API or RLS policy. - Never show secrets (API keys, tokens) in full after creation. Show them once, then mask them, and offer rotate and revoke. - Keep the app shell (navigation, workspace switcher, account menu) consistent across screens, and preserve filters, sort and scroll position when the user navigates back.
### Goal
Build **Oblaan**, the interstitial a fundraiser organiser sees before being redirected to a payments partner for identity verification and bank linking, plus the return status page. Use invented copy and a mocked partner.
### Stack
Use React 18, TypeScript, Vite, Tailwind CSS, shadcn/ui, Radix, lucide-react, TanStack Query, react-hook-form, zod, Supabase. Partner sessions are created in an Edge Function using a secret key held in function secrets; the partner is referred to only as 'our payments partner' in copy. Use Supabase for Auth, Postgres (row-level security on every table) and Storage where noted; keep only the anon key in the browser and run privileged work in Edge Functions.
### Pages & layout
1. **/withdraw/verify**: the interstitial.
2. **/withdraw/verify/return**: status page reading the verification result.
3. **/withdraw**: stub withdrawal screen for Back.
Regions, in order:
- Header: centred wordmark with a 1px bottom border
- Content column (max 440px) offset right of a back button on desktop: headline over two lines
- Two trust rows: circular tinted icon (lock, check) + bold title + one-line explanation
- Full-width dark rounded button 'Continue to <partner>'
- Help bubble fixed bottom-right
- Mobile: back button sits above the headline; button pinned to bottom with safe-area padding
### Design system
- Colors: `--page: #ffffff` (page), `--text: #2b2b2b` (text), `--muted-text: #5f6368` (muted text), `--primary: #333333` (primary), `--on-primary: #ffffff` (on primary), `--icon-circle: #e6f0ef` (icon circle), `--icon: #1f6f68` (icon), `--brand-green: #02a95c` (brand green), `--border: #dcdcdc` (border), `--focus-ring: #1f6f68` (focus ring).
- Fonts: Figtree 700 22px headline, -0.01em, line-height 1.3 for headings; Figtree 400 16px / 1.5; trust titles 16px 700 for body. Similar to the observed rounded grotesk.
- Spacing, radius and shadows: Airy; 4px base, 64px top margin, 24px between trust rows, 32px before the button; radius 10px on button and back button; no shadows.
- Motion: 150-200 ms ease-out for hover, focus and overlay transitions; overlays fade and scale from 98% to 100%; everything collapses to an instant change under prefers-reduced-motion.
- Mood: Calm, reassuring, minimal - a pause before leaving the product. Imagery: Two 36px circular tinted icon badges only.
### Components & interactions
Build these components: CenteredHeader; BackButton; InterstitialHeadline; TrustPoint (icon badge, title, text); ContinueButton; HelpBubble.
- Continue shows a spinner, creates a partner onboarding session, then does a full-page redirect
- Back returns to the withdrawal screen
- If the session URL fails to create, an inline error appears above the button with Try again
- Returning from the partner lands on a status page (verified, pending, needs more info)
### Data & state
Model: `Organizer{id, user_id, verification_status (none|pending|verified|action_required)}`; `PartnerSession{id, organizer_id, url, expires_at, created_at}`; `Payout{id, organizer_id, amount, status}`.
The Edge Function returns a short-lived URL; the client never builds partner URLs itself. The return page polls status every 3s for up to 30s while pending.
States to implement and demo:
- ready
- creating session (button busy)
- error creating session
- returned: verified
- returned: pending review
- returned: action required with reason
- already verified (interstitial skipped)
### Accessibility
- Headline is the page h1; trust points are a list
- Button text names the destination so users know they are leaving
- Icons are decorative (aria-hidden) because titles carry the meaning
- Visible focus ring on back and continue buttons
- Return page status is announced in a live region
- Body text is 16px with line-height 1.5 (15px only inside dense tables), nothing renders below 12px, weights of 300 or lighter appear only at 24px and above, and uppercase is limited to short labels with at least 0.05em tracking.
Verified contrast: headline on white: #2b2b2b on #ffffff = 14.16:1; muted explanation on white: #5f6368 on #ffffff = 6.05:1; button label on dark: #ffffff on #333333 = 12.63:1; icon on tinted circle: #1f6f68 on #e6f0ef = 5.12:1; focus ring on white: #1f6f68 on #ffffff = 5.95:1; back button border on white: #5f6368 on #ffffff = 6.05:1.
### Security
- Create partner sessions server-side only; keep the partner secret in function secrets
- Validate the return request (state token) before trusting status
- Only the organiser can start verification for their own account (RLS)
- Collect no identity data in this app - the partner does
- Log verification attempts for support
RLS: `organizers` - select/update own row (`user_id = auth.uid()`); `partner_sessions` - select own via organizer join, insert only via service role; `payouts` - select own.
### Performance & SEO
Minimal page, no heavy libraries; render fast. Noindex.
### Guardrails
- Say why the user is leaving and who they are going to, before the click
- Keep reassurance to two short points
- One button only; Back is secondary and iconic
- Never open the partner in a new tab by surprise
- Use the product name Oblaan and fresh, generic copy throughout; all people, companies, amounts and IDs are invented, and no third-party brand, logo or wordmark appears.
- Keep components small and typed (no `any`), and surface every failure visibly instead of swallowing it.
Acceptance criteria:
- [ ] Continue creates a session and redirects (mocked)
- [ ] Error state recoverable
- [ ] Return page shows all three outcomes
- [ ] Works at 390px
- [ ] Contrast pairs pass