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
- Top-right utility links: Mail, Instagram, Vimeo
- Fixed right-side vertical section nav (About, Skills, Work, Education, Writing, Speaking) with underline on active
- Hero: full-bleed dark portrait with stacked condensed uppercase name and a short accolade paragraph
- Pull quote section: a large sentence-case Inter quote with one underlined phrase and a small tracked attribution
- About with grayscale-to-color images
- Skills list
- Work experience timeline rows
- Education rows
- Writing: article list
- Speaking: talks list
- 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
| Sample | Where | Ratio | Needs |
|---|---|---|---|
| Aa | body text on background | 18.97:1 | 4.5:1 |
| Aa | heading gray on background | 13.44:1 | 4.5:1 |
| Aa | accent gray labels on background | 5.51:1 | 4.5:1 |
| Aa | accent gray on secondary surface | 4.84:1 | 4.5:1 |
| Aa | muted text on background | 5.15:1 | 4.5:1 |
| Aa | muted text on secondary surface | 4.53:1 | 4.5:1 |
| Aa | hero name/accolade on 80% black gradient over photo | 12.10:1 | 4.5:1 |
| Aa | hero accolade gray on gradient | 8.57:1 | 4.5:1 |
| focus ring / active underline on background | 18.97:1 | 3: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