Skip to main content
vibld

Template

Mara Ellis

A deep forest-green portfolio for a product and brand designer. It opens with a split hero (centered greeting and bio on the left, full-height portrait on the right), then lists selected work as oversized text titles that reveal an image following the cursor. It closes with an agency-style footer of address, clients and an email signup.

Dark green 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

Syne and Unbounded stay as the named wide display fallbacks, and Lexend Deca is a calm geometric body close to Satoshi for the boutique agency.

  • SyneHeadings: display 72-96px 500 at -1.8px
  • UnboundedHeadings: the named alternative wide display
  • Lexend DecaBody: body 16-18px at 1.6, 14px labels

Who it is for

  • Product and brand designers seeking premium clients
  • Freelance creatives presenting case studies
  • Small agencies pitching professionally
  • Designers who want a text-led work index

Layout

  1. Small monogram top-left; no conventional nav bar
  2. Split hero: left half dark green with display greeting, two centered bio paragraphs and a small photo; right half a full-bleed portrait
  3. 'Selected Work' list: very large display-type project titles stacked vertically, each with a cursor-following image preview on hover
  4. Agency statement paragraph in large display type with a hairline divider above
  5. Footer grid: address column, 'Selected Clients' two-column list, 'Get in touch' email input

Palette

Rich, calm, premium, personal, editorial. It feels like a boutique agency site: deep color, big type and a friendly voice.

  • background (forest green)#1c3a2e
  • text (cream)#f7f2e9
  • muted text#c9c4b8
  • monogram accent (dusty pink)#d9a5a5
  • divider#2f5244
  • page base (fallback)#ffffff

Every checked pair, measured again

SampleWhereRatioNeeds
Aacream body text on forest11.12:14.5:1
Aamuted text on forest7.13:14.5:1
Aadimmed project titles at 60% opacity5.06:14.5:1
Aadusty pink monogram on forest5.83:14.5:1
email input underline on forest7.13:13:1
focus-visible underline (cream) on forest11.12:13:1
Aaplaceholder text in email input7.13:14.5: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
Clash Display 500, 72-96px, -1.8px tracking, sentence case (Clash Display is not on Google Fonts; a vibld project loads Syne)
Body
Satoshi / Lexend Deca 16-18px for body at 1.6 line-height; 14px labels with slight positive tracking (1.4px) (Satoshi is not on Google Fonts; a vibld project loads Lexend Deca)

A wide geometric display face gives personality; a neutral grotesk keeps bio and footer quiet.

Spacing and imagery

Hero is an exact 50/50 split at full viewport height; content centered in ~380px column; later sections use a 1150px container with 64px gutters and large vertical breaks. Square corners.

Warm, shallow-depth-of-field portrait photography, plus project images that only appear as floating previews tied to the cursor.

Components

  • Monogram mark
  • Split hero with portrait
  • Centered bio block
  • Inline small photo
  • Oversized project title list
  • Cursor-following image preview
  • Statement paragraph
  • Hairline dividers
  • Address block
  • Two-column client list
  • Email capture input
  • Case study page layout

Interactions

  • Hovering a project title shows an image that trails the cursor with spring physics
  • Titles dim siblings on hover to spotlight the active one
  • Scroll-triggered fade-up for sections
  • Email input underline animates on focus with validation message
  • Page transitions into case studies
  • Touch devices show a static thumbnail instead of cursor preview

Data

  • Project{slug, title, cover, year, role, summary, sections[]}
  • Client{name}
  • Profile{name, bio[], portrait, address}
  • Subscriber/Inquiry{email}

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
Create a text-led, deep-green portfolio for a fictional product and brand designer named "Mara Ellis". It targets founders and marketing leads choosing a designer for premium work. The site should feel personal (a warm bio next to a big portrait) and confident (the work index is huge typography with image previews that follow the cursor).

### Stack
React 18 + TypeScript + Vite, Tailwind CSS, shadcn/ui (Radix) for input and toast, and lucide-react. Use Framer Motion for spring-driven cursor previews (`useSpring`, `useMotionValue`) and scroll reveals, React Router for case-study routes, and zod for email validation. If the email capture must persist, post it to a serverless endpoint or a Supabase Edge Function that inserts into a single `leads` table. No other backend is needed.

### Pages & layout
1. Hero at 100vh, split 50/50. On the left, on a forest background: a monogram top-left, a centered two-line display greeting, two short centered bio paragraphs and a small landscape photo. On the right: a full-bleed portrait. On mobile, the portrait stacks above the text.
2. Selected Work: a small label, then 5-7 project titles set at 72-120px, one per row, left-aligned, each linking to a case study.
3. Statement: a hairline rule and then a 3-4 line paragraph in display type about the practice.
4. Footer grid with three columns: address lines, a "Selected Clients" list in two sub-columns (fictional names) and "Get in touch" with an underlined email input.
5. Case study: title, meta row, cover, alternating image/text sections.

### Design system
- `--bg: #1c3a2e`, `--fg: #f7f2e9`, `--muted: #c9c4b8`, `--rule: #2f5244`, `--mark: #d9a5a5`, `--input-border: #c9c4b8` (email underline and focus-visible outlines use `--fg`).
- Fonts: a wide geometric display (Clash Display from Fontshare, or Syne/Unbounded from Google Fonts as a fallback) at 500, tracking -0.02em. Body is Lexend Deca 400 at 16-18px with 1.6 line-height and a ~65ch measure. Labels are 14px with 0.1em tracking.
- Scale: 14 / 16 / 18 / 28 / 48 / 72 / 112px. Container max 1150px, 64px side padding, 128px between sections.
- Radius 0 and no shadows. Motion: spring (stiffness 150, damping 20) for the cursor preview and 500ms ease-out for fade-ups.
- Dark palette only. It is intentional, so do not invert it.

### Components & interactions
- WorkTitle: default cream. While hovering the list, non-hovered titles drop to 60% opacity (blends to #9fa89e, 5.06:1 on the forest background). Focus-visible gets an underline. The cursor preview is a 320x220 image that springs toward the pointer and hides on leave.
- On touch or coarse pointers, disable the cursor preview and show a small thumbnail beside each title.
- EmailField: states for empty, focus (brighter underline), invalid (message below), submitting (spinner) and success (inline confirmation).

### Data & state
Projects are a typed array `{slug, title, year, role, cover, summary, sections}`. Clients are `string[]`. The only runtime state is pointer position, hovered index and form state. Seed five invented projects and ten made-up client names.

### Accessibility
- Cream on forest is 11.1:1. Keep muted text at #c9c4b8 or lighter.
- The cursor preview is decorative (`aria-hidden`). Each title's link text alone must describe the project.
- Give the email input a visible label, not just a placeholder.
- Honor `prefers-reduced-motion` by showing a static preview with no spring.
- Add a skip link.
- Verified contrast: cream #f7f2e9 on #1c3a2e = 11.12:1; muted #c9c4b8 on #1c3a2e = 7.13:1; dimmed titles #9fa89e on #1c3a2e = 5.06:1; monogram #d9a5a5 on #1c3a2e = 5.83:1.

### Security
- Validate the email on the client and in the function.
- Add a honeypot and rate limit by IP.
- If you use Supabase, enable RLS on `leads` with insert-only access for anon and no select.
- Keep the service key out of the client.
- Store only the email address.

### Performance & SEO
Mark the portrait as the LCP image with `fetchpriority="high"`. Preload preview images for the hovered row only. Self-host the display font with `font-display: swap`.

### Guardrails
- Do write all copy yourself and use placeholder imagery (Unsplash-style stock or generated); no trademarked names, client logos or real people.
- Don't present invented testimonials or awards as real; label sample content as sample.
- Keep components small and fully typed; no `any`. Surface errors visibly instead of failing silently.
- Don't collect or store more personal data than the contact form needs.
- Done when:
  - [ ] Hero split renders 50/50 on desktop and stacks on mobile
  - [ ] Cursor preview follows pointer smoothly and is disabled on touch and reduced-motion
  - [ ] All project titles reachable and operable by keyboard
  - [ ] Email capture validates and shows success/error states
  - [ ] Footer client list uses only fictional names

Open the builderAll templatesThis palette on its own