Skip to main content
vibld

Template

Odette Crane

A refined portfolio for a brand designer and strategist that pairs an elegant serif headline with a warm portrait, then turns vertical scrolling into a horizontal showreel of project mockups. It adds case-study pages, a services section, an interactive investment estimator to pre-qualify leads, and a validated inquiry form.

Brand designer portfolio · Website · Portfolio · 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 Caslon Condensed is a condensed editorial serif with italics, like a design journal, and Ysabeau Office is a graceful humanist body.

  • Libre Caslon CondensedHeadings: hero 96px at -2.4px with italic accent word, section heads 48px
  • Ysabeau OfficeBody: body 16-20px, 13px uppercase eyebrows 500

Who it is for

  • Freelance brand designers
  • Creative agencies presenting case studies
  • Architects and consultants selling services
  • Photographers with image-heavy work

Layout

  1. Header: serif name left, Work / About / Services / Contact right; becomes translucent on scroll
  2. Split hero: tracked uppercase eyebrow, large serif headline with one italic word, supporting sentence left; tall warm portrait right
  3. Pinned horizontal-scroll 'Selected work' gallery with vertical label, scattered mockup images at different sizes, progress bar
  4. Projects list/grid linking to case studies
  5. 'What I do' services (strategy, identity, art direction)
  6. Investment estimator: project type, scope, timeline, add-ons → live price range
  7. Contact CTA 'Let's create something meaningful' with validated form
  8. Footer

Palette

Elegant, restrained, warm, premium, intentional. It feels like a design journal.

  • background#fbfaf9
  • text#1a1a1a
  • secondary#f6f5f4
  • accent surface#ecebe9
  • muted surface#f1f0ee
  • decorative border#e3e1dd
  • input border#958d7e
  • eyebrow / muted text#6a6a6a

Every checked pair, measured again

SampleWhereRatioNeeds
Aabody text on background16.69:14.5:1
Aatext on secondary15.98:14.5:1
Aatext on accent surface14.61:14.5:1
Aamuted eyebrow on background5.19:14.5:1
Aamuted text on accent surface4.54:14.5:1
Aamuted text on muted surface4.75:14.5:1
Aawhite on dark primary button17.40:14.5:1
input / select border on background3.15:13:1
slider track on background3.15:13:1
slider range / thumb on background16.69:13:1
focus ring on background16.69: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 Caslon Condensed regular, 96px hero with -2.4px tracking and italic accent word; 48px section headings
Body
Ysabeau Office 16-20px, line-height 1.6; eyebrows 13px uppercase weight 500 with wide tracking

Condensed editorial serif against clean Ysabeau Office; italics add voice

Spacing and imagery

~1120px container with 80px side padding, 55/45 hero split, zero radius, large section gaps, pinned full-viewport gallery

Warm natural-light portrait; brand identity mockups (stationery, embossed monograms, screens, type specimens) with soft shadows

Components

  • Serif wordmark header
  • Split hero with italic accent
  • Portrait image
  • Pinned horizontal scroll gallery
  • Skip gallery link
  • Progress indicator
  • Project case study page
  • Services list
  • Investment estimator (selects, sliders, checkboxes)
  • Animated price range output
  • Contact form with zod
  • Toasts

Interactions

  • Vertical scroll translates gallery horizontally
  • Gallery images link to project detail
  • Estimator updates price range in real time with animated numbers
  • Form validation with toast feedback
  • Header blur on scroll
  • Hover lift on gallery items

Data

  • Project{slug, name, client, year, services[], hero, images[], challenge, approach, outcome}
  • Service{title, description, deliverables[]}
  • EstimatorInput{projectType, scope, timeline, addOns[]}
  • PriceRule{projectType, base, scopeMultiplier, rushFee, addOnPrices}
  • Inquiry{name, email, projectType, budget, timeline, message}

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 a portfolio for a fictional brand designer and strategist called **Odette Crane**. The audience is founders and marketing leads of premium small brands who need identity work and want to know if they can afford it. The site shows taste first (serif hero, portrait, a horizontal showreel), proves depth through case studies, explains services, and pre-qualifies leads with a price estimator before the inquiry form.

### Stack
React 18 + TypeScript + Vite, Tailwind CSS, shadcn/ui (Radix Select, Slider, Checkbox, Form, Toast), lucide-react, React Router, Framer Motion (`useScroll` + `useTransform` for the pinned horizontal gallery and animated numbers), and react-hook-form + zod. The inquiry posts to one serverless function.

### Pages & layout
1. Header: serif name left; Work, About, Services and Contact right; translucent with blur after scroll.
2. Hero: a tracked uppercase eyebrow, a large serif headline with one italic word, and a one-sentence positioning line on the left; a tall warm portrait on the right.
3. Selected work: a pinned section (about 300vh tall) where vertical scroll moves a strip of 12–24 mockup images horizontally; images vary in size and vertical offset; a rotated "Selected work" label; a thin progress bar; a "Skip gallery" link before it.
4. Projects: four featured case studies with client, year and services.
5. Services: three offerings with deliverables.
6. Estimator: project type (select), scope (slider), timeline (standard or rush), add-ons (checkboxes); outputs an animated price range and a "Send this estimate" button that pre-fills the form.
7. Contact: large serif line and a form (name, email, project type, budget, timeline, message).
8. Case study page: hero, metadata, challenge, approach, outcome, gallery, next project.

### Design system
Tokens: `--background: #fbfaf9; --foreground: #1a1a1a; --secondary: #f6f5f4; --accent: #ecebe9; --muted: #f1f0ee; --muted-foreground: #6a6a6a; --border: #e3e1dd (decorative); --input-border: #958d7e; --radius: 0`. Fonts: Libre Caslon Condensed 400 (regular and italic) and Ysabeau Office 400/500. Scale: clamp(52px, 7.5vw, 96px) H1 with -2.5% tracking; 48 / 32 / 20 / 16 / 13px (16–20px body at line-height 1.6, max 70ch); eyebrow 13px uppercase, weight 500, with 0.15em tracking, short labels only. Spacing: 80px side padding, 160px section gaps. Shadows: soft `0 20px 50px -20px rgb(0 0 0 / .25)` on gallery images. Motion: numbers tween over 400ms; gallery is scroll-linked; 300ms hovers. Light only.

### Components & interactions
- Horizontal gallery: each image links to its case study; keyboard users can skip it or tab through links, and focusing a link scrolls it into view.
- Estimator: pure function `estimate(input, rules)` with unit tests; shows a range, never a single binding price; reset button; the disclaimer states it is indicative.
- Form: inline zod errors, a disabled submit while sending, success toast, error toast with retry; estimator values arrive pre-filled but editable.
- Mobile: the gallery becomes a normal swipe carousel (no pinning).

### Data & state
`Project{slug,name,client,year,services[],hero,images[],challenge,approach,outcome}`, `Service{title,text,deliverables[]}`, `EstimatorInput{type,scope,timeline,addOns[]}`, `PriceRules` config, `Inquiry{…}`. Estimator state is local, passed to the form through context or the URL.

### Accessibility
#6a6a6a eyebrow and muted text is 5.2:1 on #fbfaf9 and stays above 4.5:1 on the #ecebe9 accent surface; inputs, selects and the slider track use #958d7e so their edges reach 3:1. Scroll-jacked galleries are hard for many users, so provide the skip link, disable pinning under `prefers-reduced-motion`, and keep a standard layout below 768px. Slider needs a visible value and `aria-valuetext` ("Scope: medium, about 6 deliverables"). The price range output is an `aria-live="polite"` region. All form fields are labelled. Verified contrast: body text on background: #1a1a1a on #fbfaf9 = 16.69:1; muted eyebrow on background: #6a6a6a on #fbfaf9 = 5.19:1; muted text on accent surface: #6a6a6a on #ecebe9 = 4.54:1; white on dark primary button: #ffffff on #1a1a1a = 17.4:1; input / select border on background: #958d7e on #fbfaf9 = 3.15:1.

### Security
Validate the inquiry with zod on the client and in the function, recompute any estimate server-side if it is stored, add a honeypot and rate limiting, and keep email keys server-side. External links use `rel="noopener noreferrer"`.

### Performance & SEO
Gallery images should be compressed WebP/AVIF at the displayed size and lazy-loaded; preload only the portrait. Code-split case studies. Person, Service and CreativeWork JSON-LD; per-project OG images. Target smooth 60fps scroll by animating transform only.

### Guardrails
- Use original copy, invented clients and placeholder mockups; no real brand logos.
- Present estimator outputs as indicative, never as quotes.
- Store only inquiry fields.
- Keep components small and typed, never use `any`, and show errors visibly.
- Done when: the gallery can be skipped and degrades on mobile and under reduced motion; the estimator is unit-tested and announces changes; the estimate pre-fills the form; case studies resolve by slug; Lighthouse accessibility is 95 or higher.

Open the builderAll templatesThis palette on its own