Skip to main content
vibld

Template

Pembrow

The first onboarding step of a personal note-taking app. It greets the user by first name and asks which part of life they most want to organise, then tailors starter templates to that choice. It targets individuals, so it is warm and unhurried rather than business-like.

Personalised welcome question with icon choice cards · App screen: discovery questions · 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, 36px/1.2, -0.01em (similar to the observed humanist geometric sans)
  • FigtreeBody: Figtree 400 17px/1.6

Patterns

  • full-bleed pastel gradient canvas
  • personalised greeting headline
  • stacked icon choice cards with subtitle
  • selected card lifts to white with check badge
  • wide pill Next button
  • step dots pagination

States it is designed for

  • default choice pre-selected
  • changed choice
  • name missing (greeting falls back to 'Hi there')
  • saving (button label to 'Saving…')
  • save failed (inline note under button, retry)
  • last step (button becomes 'Start writing')
  • reduced motion (no slide, instant swap)

Who it is for

  • students
  • knowledge workers
  • personal journalers

Layout

  1. full-viewport vertical gradient from pale aqua to light sky blue
  2. centred column (~360px): large greeting, welcome line, two-line question
  3. three stacked choice cards (icon left, title and example subtitle)
  4. generous gap, then a wide Next button
  5. step dots at the bottom (current dot wider)
  6. on mobile the column fills the width with 20px gutters and Next sticks above the dots

Palette

Soft, friendly, personal; like opening a fresh notebook on a clear morning.

  • gradient top#e0f9ff
  • gradient bottom#b9eaff
  • unselected card#d3f3ff
  • selected card#ffffff
  • heading text#1d2733
  • body / subtitle text#35505f
  • check badge / focus#0a6fd6
  • next button#a8dcf5
  • step dot inactive#7fa7ba
  • step dot active#35505f

Every checked pair, measured again

SampleWhereRatioNeeds
Aaheading on gradient top13.78:14.5:1
Aasubtitle on unselected card7.32:14.5:1
Aasubtitle on gradient bottom6.61:14.5:1
Aabutton label on button10.23:14.5:1
check badge / focus ring on white card4.93:13:1
active step dot on gradient6.61:13: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, 36px/1.2, -0.01em (similar to the observed humanist geometric sans)
Body
Figtree 400 17px/1.6

Card titles 18px 600; subtitles 14px 400; button 17px 600.

Spacing and imagery

Spacious: 16px between the question lines, 40px before the cards, 12px between cards, 56px before Next. Cards 64px tall, 14px radius, 16px padding; selected card gets 0 6px 20px rgba(29,39,51,0.10). Button 14px radius, 48px tall.

Simple solid pictogram icons (person, person at desk, person at board) in dark slate; a small accent check badge overlays the selected icon. No photos.

Components

  • GradientCanvas
  • Greeting (uses first name)
  • ChoiceCard (icon, title, subtitle, check badge)
  • NextButton
  • StepDots

Interactions

  • click or Space selects a card; the card fades to white and lifts 2px
  • arrow keys move between cards
  • Next advances with a horizontal slide (200ms)
  • dots are not clickable until a step is completed, then they jump back
  • a default is pre-selected so Next is always usable

Data

  • Profile{user_id, first_name, focus (personal|work|education), onboarding_step int}
  • StarterTemplate{id, focus, title, body_md}
  • Note{id, user_id, title, body_md, created_at}

Guardrails

Experience

  • Keep the greeting short and personal; one question per step.
  • Give every choice a concrete example subtitle so the category is self-explanatory.
  • Pre-select the most common choice so the user can simply continue.
  • Show total step count with dots and an sr-only 'Step 1 of 7'.
  • After the last step, create two starter notes from the chosen focus so the app is not empty.

Accessibility

  • Choice cards are a radio group with a visible legend (the question).
  • The check badge is decorative; selection is announced through aria-checked.
  • Next button text is dark on the pale blue; never white.
  • Dots use aria-current='step' and are hidden from tab order until navigable.
  • Honour prefers-reduced-motion for card lift and slide.

Security

  • RLS: profile and notes readable and writable only by the owner.
  • Escape the first name before rendering; limit to 40 characters.
  • Starter templates are read-only public rows; seeding user notes happens in a server function.

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 **Pembrow**, the first-run welcome flow of a personal notes app. Step one greets the user by first name and asks which part of life they want to improve (personal, work, education); later steps are placeholders. Completing the flow seeds starter notes matching the choice.

### Stack
React 18 + TypeScript + Vite, Tailwind CSS, Radix RadioGroup and lucide-react icons, Motion for step transitions, TanStack Query. Supabase Auth, Postgres for profiles, templates and notes.

### Pages & layout
1. **/welcome/:step** (7 steps): gradient canvas, greeting, question, choices, Next, dots.
2. **/notes**: minimal list showing the seeded starter notes after completion.
3. Mobile: full-width column, sticky Next above the dots.

### Design system
- Colors: `--bg-top: #e0f9ff` (gradient top), `--bg-bottom: #b9eaff` (gradient bottom), `--card: #d3f3ff` (unselected card), `--card-selected: #ffffff` (selected card), `--fg: #1d2733` (heading text), `--muted: #35505f` (body / subtitle text), `--accent: #0a6fd6` (check badge / focus), `--button: #a8dcf5` (next button), `--dot: #7fa7ba` (step dot inactive), `--dot-active: #35505f` (step dot active).
- Fonts: Figtree 700, 36px/1.2, -0.01em (similar to the observed humanist geometric sans) for headings; Figtree 400 17px/1.6 for body. Card titles 18px 600; subtitles 14px 400; button 17px 600.
- Spacing: Spacious: 16px between the question lines, 40px before the cards, 12px between cards, 56px before Next. Cards 64px tall, 14px radius, 16px padding; selected card gets 0 6px 20px rgba(29,39,51,0.10). Button 14px radius, 48px tall.
- Radius: 14px cards and button; dots 3px tall pills (active 16px wide, inactive 6px).
- Shadows: selected card only.
- Motion: 200ms slide between steps; 150ms card lift; none under reduced motion.
- Gradient: linear 180deg from bg-top to bg-bottom, fixed to the viewport.

### Components & interactions
GradientCanvas, Greeting, ChoiceCard, NextButton, StepDots, StarterNotesList.

Interactions: click or Space selects a card; the card fades to white and lifts 2px; arrow keys move between cards; Next advances with a horizontal slide (200ms); dots are not clickable until a step is completed, then they jump back; a default is pre-selected so Next is always usable.

States to build: default choice pre-selected; changed choice; name missing (greeting falls back to 'Hi there'); saving (button label to 'Saving…'); save failed (inline note under button, retry); last step (button becomes 'Start writing'); reduced motion (no slide, instant swap).

### Data & state
Profile holds `focus` and `onboarding_step`; update on every Next so the flow resumes. On finish, a server function copies two `starter_templates` for the chosen focus into `notes`. Seed a user named 'Rowan' for the demo.

Model: `Profile{user_id, first_name, focus (personal|work|education), onboarding_step int}`; `StarterTemplate{id, focus, title, body_md}`; `Note{id, user_id, title, body_md, created_at}`.

### Accessibility
Choice cards are a radio group with a visible legend (the question). The check badge is decorative; selection is announced through aria-checked. Next button text is dark on the pale blue; never white. Dots use aria-current='step' and are hidden from tab order until navigable. Honour prefers-reduced-motion for card lift and slide.
Verified contrast: heading on gradient top: #1d2733 on #e0f9ff = 13.78:1; subtitle on unselected card: #35505f on #d3f3ff = 7.32:1; subtitle on gradient bottom: #35505f on #b9eaff = 6.61:1; button label on button: #1d2733 on #a8dcf5 = 10.23:1; check badge / focus ring on white card: #0a6fd6 on #ffffff = 4.93:1; active step dot on gradient: #35505f on #b9eaff = 6.61:1.

### Security
RLS: profile and notes readable and writable only by the owner. Escape the first name before rendering; limit to 40 characters. Starter templates are read-only public rows; seeding user notes happens in a server function. RLS per table: `profiles` select/update where `user_id = auth.uid()`; `notes` full CRUD for owner only; `starter_templates` select for authenticated, no client writes.

### Performance & SEO
Inline the gradient CSS; icons tree-shaken from lucide-react. Prefetch /notes on the last step. Welcome routes are noindex.

### Guardrails
- Keep the greeting short and personal; one question per step.
- Give every choice a concrete example subtitle so the category is self-explanatory.
- Pre-select the most common choice so the user can simply continue.
- Show total step count with dots and an sr-only 'Step 1 of 7'.
- After the last step, create two starter notes from the chosen focus so the app is not empty.
- Write all copy fresh; use invented people, companies and numbers only. No real brands, logos, wordmarks or third-party product names anywhere in the UI or seed data.
- Do not trace or copy any existing product's layout assets, icons or illustrations; draw generic ones.
- Acceptance criteria:
  - [ ] Greeting shows the user's first name or a fallback
  - [ ] A choice is pre-selected and can be changed with keyboard
  - [ ] Refresh resumes on the saved step
  - [ ] Finishing creates two notes for the chosen focus
  - [ ] All text meets the verified contrast pairs

Open the builderAll templatesThis palette on its own