Skip to main content
vibld

Template

Pressed Petal

A soft, monochrome-on-sage wedding site built around polaroid-style photos, big serif headlines and a long single scroll: invitation message, venues, photo gallery, hotel details, categorized registry and a conditional RSVP form. It gives couples a personal, scrapbook-like link to send guests.

Scrapbook wedding invitation site · Website · Events and bookings · static site

A mock-up of the homepage, drawn from this design’s layout, palette and typefaces. A build follows the full prompt below.

Start from this templateRead the build prompt

Typefaces

Libre Bodoni is a classic, slightly old-fashioned high-contrast serif that reads like a printed keepsake, and Rosario is a soft humanist sans for the serene scrapbook.

  • Libre BodoniHeadings: headlines 96px 400 in charcoal, 500 italic accents
  • RosarioBody: body 16px charcoal, 12px tracked uppercase labels

Who it is for

  • Couples wanting a personal invitation site
  • Wedding planners
  • Guests on mobile
  • Agencies on tight timelines

Layout

  1. Ghost header: couple's names in serif left, tracked RSVP link right, no background
  2. Hero: tilted polaroid photo with shadow on sage, then huge charcoal serif 'We're Getting Married' and names
  3. Invitation paragraph about ceremony, reception and dress code
  4. Venue list: small caps label, serif venue name, spaced address lines (ceremony gardens, reception ballroom)
  5. Three-column polaroid photo gallery
  6. Hotel details section/page
  7. Categorized registry
  8. 'Will You Celebrate With Us?' RSVP with conditional fields
  9. Footer

Palette

Soft, intimate, nostalgic, playful, serene. It feels like a scrapbook of instant photos laid on a pastel tablecloth.

  • background (sage)#bacfc4
  • text (charcoal)#262626
  • primary (off-white)#ebebeb
  • primary-foreground (charcoal)#262626
  • secondary gray#555555
  • polaroid frame#fafafa

Every checked pair, measured again

SampleWhereRatioNeeds
Aabody and heading text on sage9.23:14.5:1
Aasecondary caption text on sage4.55:14.5:1
Aacharcoal label on off-white primary button12.69:14.5:1
Aahandwritten-style caption on polaroid frame14.50:14.5:1
Aainput text in field14.50:14.5:1
input border on sage page3.02:13:1
input border against field fill4.74:13:1
focus ring on sage9.23: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
Libre Bodoni 400, 96px headlines, charcoal, normal case
Body
Rosario 16px charcoal; 12px tracked uppercase labels

Classic serif plus neutral sans, both in charcoal on a single pastel field, creates a monochrome, paper-like calm.

Spacing and imagery

Single long scroll (6000px+), centered narrow text column (~760px), huge vertical breathing room, 12px radius on form fields.

Candid instant-film couple photos in white polaroid frames, slightly rotated with drop shadows.

Components

  • Ghost navigation
  • Rotated polaroid photo
  • Giant serif headline
  • Invitation text block
  • Venue info blocks
  • Polaroid gallery grid
  • Hotel cards
  • Registry category groups
  • Conditional RSVP form
  • Confirmation state

Interactions

  • Scroll-triggered fade and rise on every block
  • Polaroid slight rotation/hover straighten
  • RSVP fields appear only when attending is yes
  • Form confirmation state
  • Smooth scroll to RSVP

Data

  • Venue{label, name, address, time}
  • Photo{src, caption, rotation}
  • Hotel{name, address, rate, bookingUrl}
  • RegistryItem{category, store, url}
  • RSVP{name, email, attending, guestCount, guestNames[], dietary, note}

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 a template'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 templates)
- 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.
### Goal
Build **Pressed Petal**, a single-scroll wedding invitation site for fictional couple June & Idris. It should feel like a handmade scrapbook: instant-film photos on a soft pastel background, big serif type, and just enough information for guests to plan and reply. Guests mostly open it from a text message on their phones.

### Stack
React 18 + TypeScript + Vite, Tailwind CSS, shadcn/ui (Form, RadioGroup, Input, Textarea, Select), lucide-react, Framer Motion for scroll reveals and polaroid motion, react-hook-form + zod with conditional validation, React Router for optional Hotel and Registry subpages. RSVP posts to a serverless function (or Supabase insert-only table).

### Pages & layout
1. **Home (long scroll)** – ghost header: names in serif at left, tracked "RSVP" link at right, no background. Hero: one polaroid photo rotated ~-2° with a soft shadow, then a very large charcoal serif headline and the names on the next line. Invitation paragraph (ceremony time, reception, dress code). Venue list: tiny caps label (Ceremony / Reception), serif venue name, address in tracked small caps. Gallery: three columns of polaroids with handwritten-style captions and alternating rotations. Hotels teaser. Registry grouped by category. "Will you celebrate with us?" RSVP. Footer with date and a thank-you line.
2. **Hotel details** – cards with rate, distance and booking link.
3. **Registry** – categories (Home, Experiences, Honeymoon fund) with store links.

### Design system
- Tokens: `--background: #bacfc4` (sage), `--foreground: #262626`, `--primary: #ebebeb`, `--primary-foreground: #262626`, `--secondary: #555555`, `--border: #adadad` (decorative), `--input-border: #707070`, `--input: #fafafa`, `--radius: 0.75rem`, `--polaroid: #fafafa`.
- Fonts: Libre Bodoni (400, 500 italic) and Rosario. Scale: 12 (labels, uppercase +0.25em) / 14 / 16 / 20 / 32 / 56 / clamp(56px, 8vw, 96px).
- Spacing: 8px base; sections separated by 160–200px; text column 760px.
- Shadows: polaroids `0 18px 40px rgb(0 0 0 / .15)`.
- Motion: reveal 800ms ease-out with 20px rise; polaroids straighten to 0° on hover in 300ms; smooth scroll for the RSVP link.

### Components & interactions
Ghost nav (focus-visible underline), polaroid (rotation prop, caption, hover), venue block, gallery grid (lightbox optional), hotel card, registry group, RSVP form: attending yes/no radio; if yes, guest count select reveals that many name fields plus dietary notes; if no, only a message field. States: pristine, invalid (inline messages), submitting, success (thank-you card replaces form), error with retry.

### Data & state
`Couple{names,date,city}`, `Venue{label,name,address,time}`, `Photo{src,alt,caption,rotation}`, `Hotel{name,address,rate,url}`, `RegistryItem{category,store,url}`, `Rsvp{name,email,attending,guests:[{name,dietary}],message}`. All content in a typed config; form state in react-hook-form. Use placeholder couple photos of models.

### Accessibility
White on sage `#bacfc4` would be only about 1.6:1, so all text, including headings, is charcoal `#262626` on sage (9.2:1); white is reserved for the polaroid frames. The secondary gray is darkened to `#555555` so captions pass on sage. Form fields are `#fafafa` with a `#707070` border (3:1+ on both the field and the sage page). Faded "reveal" text must end fully opaque. Form fields need visible borders (3:1) and labels. Conditional fields are announced (focus moves to the first new field). Reduced motion removes rotations and reveals.
Verified contrast: body and heading text on sage #262626 on #bacfc4 = 9.23:1; secondary caption text on sage #555555 on #bacfc4 = 4.55:1; charcoal label on off-white primary button #262626 on #ebebeb = 12.69:1; handwritten-style caption on polaroid frame #262626 on #fafafa = 14.5:1; input text in field #262626 on #fafafa = 14.5:1.

### Security
Proportionate: zod schema shared by client and function (conditional rules enforced server-side too), honeypot and rate limit, optional invite code, no secrets in the client, anon insert-only RLS if using Supabase, and `rel="noopener noreferrer"` on registry links. Don't expose the guest list publicly.

### Performance & SEO
Only a handful of images: serve them as responsive WebP, preload the hero polaroid, lazy-load the gallery. `noindex` by default; OG image and description for message previews. Lighthouse 95+.

### Guardrails
- Fictional couple, venues and placeholder photos; no real venue names or logos.
- No fabricated guest messages.
- Collect only what planning needs and allow the couple to purge responses.
- Small typed components, no `any`, visible errors.
- Done when: the long scroll renders all sections with reveals that end fully visible; the conditional RSVP works and validates on both sides; text contrast passes AA; the page is smooth on a mid-range phone.

Open the builderAll templatesThis palette on its own