Skip to main content
vibld

Template

Cass Moreno

A cinematic, near-black one-page portfolio for a documentary photographer and creative director. A giant Bebas Neue name overlays a moody portrait, followed by oversized quote-style accolades and sections for about, skills, work history, education, writing and speaking, with a fixed right-side section nav. It turns a varied career into one strong narrative.

Cinematic documentary photographer one-pager · 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

League Gothic is a tall, classic condensed poster face like a documentary title card, and IBM Plex Sans is a neutral, slightly engineered body.

  • League GothicHeadings: name and short headings 128-192px uppercase at 0.05em
  • IBM Plex SansBody: body 16px at 1.6, 12px tracked uppercase labels

Who it is for

  • Photographers and videographers with a cinematic style
  • Creatives who also write and speak
  • Consultants building credibility with clients
  • Professionals combining varied experience into one story

Layout

  1. Top-right utility links: Mail, Instagram, Vimeo
  2. Fixed right-side vertical section nav (About, Skills, Work, Education, Writing, Speaking) with underline on active
  3. Hero: full-bleed dark portrait with stacked condensed uppercase name and a short accolade paragraph
  4. Pull quote section: a large sentence-case Inter quote with one underlined phrase and a small tracked attribution
  5. About with grayscale-to-color images
  6. Skills list
  7. Work experience timeline rows
  8. Education rows
  9. Writing: article list
  10. Speaking: talks list
  11. Get in touch with a playful note and contact links

Palette

Cinematic, dramatic, dark, bold, grainy. It feels like the opening titles of a documentary.

  • background#0a0a0a
  • text#fafafa
  • heading gray#d1d5db
  • secondary surface#1a1a1a
  • accent gray#878787
  • muted#828282
  • border#333333

Every checked pair, measured again

SampleWhereRatioNeeds
Aabody text on background18.97:14.5:1
Aaheading gray on background13.44:14.5:1
Aaaccent gray labels on background5.51:14.5:1
Aaaccent gray on secondary surface4.84:14.5:1
Aamuted text on background5.15:14.5:1
Aamuted text on secondary surface4.53:14.5:1
Aahero name/accolade on 80% black gradient over photo12.10:14.5:1
Aahero accolade gray on gradient8.57:14.5:1
focus ring / active underline on background18.97: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
League Gothic, 128-192px, uppercase with 0.05em tracking, name and short headings only
Body
IBM Plex Sans 16px at 1.6 line-height (14px only for utility links); 12px tracked uppercase labels

Condensed poster display against a neutral sans; scale contrast is extreme to feel like a film title card.

Spacing and imagery

64px left margin, full-height sections, long page (~13k px), right-aligned nav column, 0 radius, thick underline accents.

High-contrast black-and-white portraits with subtle animated film grain; images shift grayscale-to-color on hover.

Components

  • Utility social links
  • Fixed vertical section nav with active underline
  • Full-bleed hero portrait
  • Stacked condensed name
  • Oversized pull quote with underline
  • Grayscale-to-color images
  • Skills list
  • Experience rows
  • Education rows
  • Writing list
  • Speaking list
  • Contact section
  • Film-grain overlay
  • Custom scrollbar

Interactions

  • Active section in the side nav updates on scroll (scroll spy)
  • Smooth scroll to sections
  • Scroll-triggered fade/slide-in of headings
  • Images go grayscale to color on hover
  • Animated film-grain noise overlay
  • Link underline animations

Data

  • Role{title, organization, start, end, summary}
  • Education{program, school, years}
  • Article{title, outlet, date, url}
  • Talk{title, event, date}
  • Skill{name}
  • Accolade{quote, source}

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 cinematic, near-black one-page portfolio for a fictional documentary photographer and creative director, "Cass Moreno". It serves editors, conference organizers and brand clients who want to understand a whole career, including photography, leadership, writing and speaking, in one scroll. It should feel like a film title sequence: towering condensed type, grainy monochrome portraits and a quiet side nav.

### Stack
React 18 + TypeScript + Vite, Tailwind CSS, shadcn/ui (Radix) and lucide-react. Use an IntersectionObserver hook for scroll spy, and CSS or Framer Motion for reveals. Static only.

### Pages & layout
1. Utility links top-right (Mail, Instagram, Vimeo) at 14px.
2. Fixed side nav, bottom-right, right-aligned: About, Skills, Work, Education, Writing, Speaking. The active item gets a 1px underline.
3. Hero: a full-viewport black-and-white portrait with a dark gradient on the left. A three-line uppercase name at clamp(72px, 15vw, 192px) with 0.05em tracking and a two-sentence accolade (fictional) below.
4. Quote: a large pull quote in IBM Plex Sans 600 at 48-72px, sentence case (Bebas is reserved for the name and short section headings), with one phrase underlined by a thick 8px bar, and a small tracked attribution.
5. About: a paragraph and two images that are grayscale by default.
6. Skills: a wrapped list or two-column grid.
7. Work: rows with role, organization and years plus a one-line summary.
8. Education, then Writing (article title, outlet, date) and Speaking (talk, event, date).
9. Contact: a big heading, a wry one-liner and email/social links.

### Design system
- `--background: #0a0a0a`, `--foreground: #fafafa`, `--heading-muted: #d1d5db`, `--secondary: #1a1a1a`, `--accent: #878787`, `--muted: #828282`, `--border: #333`, radius 0.
- Fonts: League Gothic for display only (192 / 128 / 64px, never below 48px, with Impact and sans-serif fallbacks) and IBM Plex Sans 400/500 for body at 16px. Labels are 12px uppercase with 0.12em tracking.
- Spacing: 8px base, 64px page margin, full-height sections. Film grain is an SVG turbulence overlay at 4-6% opacity, animated in steps.
- Motion: 700ms cubic-bezier(0.16,1,0.3,1) reveals, 500ms grayscale transitions. Dark only. Style the scrollbar thin and dark.

### Components & interactions
- SideNav: states for default gray, hover white and active underlined. Click scrolls smoothly. On mobile it becomes a top sheet menu.
- RevealHeading: fades and slides up once. Under reduced motion it is shown immediately.
- MonoImage: grayscale; hover or focus shows color. Show a skeleton while loading.
- Lists (work, writing, speaking): hover draws an underline. External article links show ↗.
- Empty section: hide the section and its nav item automatically if its data array is empty.

### Data & state
Typed config arrays: `Role`, `Education`, `Article{title, outlet, date, url}`, `Talk{title, event, date}`, `Skill` and `Accolade`. The only state is the active section. All names, awards and publications must be invented and marked as sample. Never imply real awards.

### Accessibility
- #878787 on #0a0a0a is 5.51:1. The muted gray is lifted from #666 to #828282 (5.15:1) so it works for small text.
- Condensed display text must stay real text (H1, H2). The side nav is a `<nav aria-label="Sections">` with `aria-current`.
- Pause or disable the grain animation under reduced motion. Hero text sits on a left-side black gradient of at least 80% opacity (effective #333333 or darker behind the text).
- Add a skip link. The underline accent is not the only cue for active.
- Verified contrast: body #fafafa on #0a0a0a = 18.97:1; accent gray #878787 on #0a0a0a = 5.51:1; muted #828282 on #0a0a0a = 5.15:1; hero text #fafafa on #333333 = 12.1:1.

### Security
- No forms. `mailto:` link only.
- External links (articles, Vimeo) use `rel="noopener noreferrer"`. Validate URLs in config (https only).
- No secrets in client-side code.

### Performance & SEO
The page is long (about 9 sections), so lazy-load all images after the hero, preload League Gothic and the hero portrait, and keep the grain as CSS/SVG rather than video. Add Person JSON-LD, section IDs for deep links and OG tags.

### 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:
  - [ ] Side nav highlights the section in view and scrolls smoothly
  - [ ] Hero text keeps 4.5:1 contrast over the photo
  - [ ] Grain and reveals stop under reduced-motion
  - [ ] Sections with empty data are hidden with their nav items
  - [ ] All accolades and outlets are fictional

Open the builderAll templatesThis palette on its own