Template
Bram Oduya
A clean agency-style portfolio for an independent designer. An auto-rotating full-bleed hero carousel shows featured projects with overlaid descriptions and a slide counter, followed by a positioning statement, an alternating 'Selected Work' grid with tag pills and a contact footer. It gives freelancers and small teams a polished, studio-grade presence.
Carousel-led freelance 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
Bricolage Grotesque is a characterful grotesk like Clash Grotesk, and Lexend Deca is a clean geometric body close to General Sans.
- Bricolage GrotesqueHeadings: hero 60px+ at 500, fluid footer wordmark
- Lexend DecaBody: body 16px at 1.6, tags 12-14px
Who it is for
- Freelancers and consultants building credibility
- Small agencies pitching new business
- Designers with illustration, editorial and 3D work
- Teams delivering client portfolio sites cheaply
Layout
- White top bar: bold wordmark left; Work (active, gray), About, Contact right
- Full-bleed hero carousel with dark overlay: small project name, large multi-line description, '01/06' counter bottom-right
- Positioning statement in large display type
- Selected Work: alternating large and small project cards, each with image, bold title, one-line description and outlined tag pills
- Footer: Contact, Social, Work columns and a giant wordmark
- Project detail page with next project navigation
- Mobile menu
Palette
Crisp, confident, contemporary, editorial, energetic. It looks like a studio site with punchy imagery and restrained UI.
- background
#ffffff - text
#0a0a0a - accent (acid yellow)
#eeff00 - secondary surface
#f7f7f7 - border
#e0e0e0 - muted text
#5c5c5c - input border
#5c5c5c
Every checked pair, measured again
| Sample | Where | Ratio | Needs |
|---|---|---|---|
| Aa | body text on white | 19.80:1 | 4.5:1 |
| Aa | muted text and tag labels on white | 6.69:1 | 4.5:1 |
| Aa | muted text on secondary surface | 6.24:1 | 4.5:1 |
| Aa | white hero text on 60% black overlay (worst case) | 5.74:1 | 4.5:1 |
| Aa | dark text on acid-yellow highlight | 17.86:1 | 4.5:1 |
| input border on white | 6.69:1 | 3:1 | |
| focus ring (black) on white | 19.80: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
- Clash Grotesk / Clash Display 500, 60px+ on hero, fluid clamp sizes (Clash Grotesk is not on Google Fonts; a vibld project loads Bricolage Grotesque)
- Body
- General Sans 16px at 1.6 line-height; tags 12-14px in #5c5c5c (General Sans is not on Google Fonts; a vibld project loads Lexend Deca)
A characterful grotesk display with a clean geometric sans body; acid-yellow accent used sparingly.
Spacing and imagery
64px side margins, 1150px content width for cards, generous 120px sections, pill-shaped tags, images square-cornered.
Warm, photographic project shots (tablets, printed matter, abstract art, 3D renders) cropped wide; hero darkened with an overlay for legibility.
Components
- Wordmark header with active state
- Auto-rotating hero carousel
- Slide counter
- Overlay description text
- Positioning statement
- Alternating project grid
- Project card with tag pills
- Contact form
- Footer columns + giant wordmark
- Next-project navigation
- Mobile menu drawer
- SEO meta config
Interactions
- Hero auto-advances every 6s with crossfade; pauses on hover/focus
- Scroll-triggered fade-up on cards and headings
- Card image zooms slightly on hover; title underlines
- Mobile menu slides in
- Contact form validation with inline errors and toast
- Next project link at the end of each case study
Data
Project{slug, title, summary, tags[], cover, featured, body[], gallery[]}SiteConfig{name, statement, email, socials[], meta}Inquiry{name, email, 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 crisp studio-style portfolio for a fictional independent designer, "Bram Oduya". It is aimed at marketing leads and founders choosing a designer for brand, editorial and illustration work. The home page opens with a rotating, full-bleed showcase of featured projects, states a one-line mission, lists selected work in an alternating grid and ends with contact details. Each project has a case study page that links onward to the next.
### Stack
React 18 + TypeScript + Vite, Tailwind CSS, shadcn/ui (Radix Sheet, Form, Toast) and lucide-react. Use Embla Carousel with autoplay and fade for the hero, Framer Motion for in-view reveals, React Router for `/`, `/work/:slug`, `/about` and `/contact`, and react-hook-form + zod. One serverless function relays the contact form.
### Pages & layout
1. Header, 60px, white: wordmark on the left and three links on the right. The active link is gray.
2. Hero carousel at 90vh: an image with a 60% black overlay (effective #666666 or darker behind text, even on a white slide). At bottom-left, the small project name and a 60px description over up to three lines. The counter "01/06" sits at bottom-right.
3. Statement: a two-line mission at 48px, centered in a 900px column.
4. Selected Work: rows alternate between one full-width card and a pair of half cards. Each card has a 16:9 image, bold title, one-line summary and outlined tag pills.
5. Footer: three columns (Contact, Social, Work) and an oversized wordmark along the bottom edge.
6. Case study: title, tags, hero image, body sections, gallery and a "Next project →" banner.
### Design system
- `--background: #ffffff`, `--foreground: #0a0a0a`, `--accent: #eeff00` (highlight fills only, never text on white), `--secondary: #f7f7f7`, `--border: #e0e0e0`, `--muted-foreground: #5c5c5c`, `--input-border: #5c5c5c` (the #e0e0e0 border is for decorative dividers and tag outlines only).
- Fonts: Clash Grotesk from Fontshare, or Bricolage Grotesque from Google Fonts, at 500 for display; General Sans or Lexend Deca at 400/500 for body. Use a clamp scale: 14 / 16 / 20 / 32 / clamp(40px, 5vw, 64px) / clamp(64px, 12vw, 180px) for the footer wordmark.
- Spacing: 8px base, 64px gutters, 120px sections. Tags are 9999px pills; images have 0 radius.
- Motion: 6s autoplay, 800ms crossfade and 500ms fade-up with a 80ms stagger.
### Components & interactions
- HeroCarousel: dots or counter plus prev/next buttons. It pauses on hover, focus and hidden tab, and stays static under reduced motion.
- ProjectCard: hover or focus zooms the image to 1.03 and underlines the title. Show a skeleton while loading. Tags are non-interactive chips.
- Accent use: the acid yellow appears as a text-selection color and a hover highlight behind the title.
- ContactForm: states for invalid, submitting, success toast and error toast.
- Header: a Sheet menu on mobile.
### Data & state
`Project{slug, title, summary, tags, cover, featured, body, gallery}` plus a `SiteConfig` for SEO defaults. Featured projects feed the carousel. Seed six fictional projects covering illustration, editorial, abstract, 3D, portrait and animal studies.
### Accessibility
- Overlay text is white on the 60% black overlay, which stays at 5.74:1 or better even on the brightest slide.
- The carousel is a labelled region with a visible pause (WCAG 2.2.2) and announces "Slide 2 of 6".
- Yellow #eeff00 is used only as a background behind dark text (17.86:1).
- Focus rings are 2px black with a 2px offset. Tags are text.
- Verified contrast: body #0a0a0a on #ffffff = 19.8:1; muted #5c5c5c on #ffffff = 6.69:1; hero overlay #ffffff on #666666 = 5.74:1; text on yellow #0a0a0a on #eeff00 = 17.86:1.
### Security
- zod on the client and in the function, with a honeypot and rate limit.
- No secrets client-side. Social links use `rel="noopener noreferrer"`.
### Performance & SEO
Load the first slide eagerly and lazy-load the rest. Use `srcset`. Keep per-route meta in a typed config with OG images from covers. Use one H1 per page (the hero needs a visually hidden H1).
### 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 rotates every 6s, pauses on interaction, and has a counter
- [ ] Selected Work alternates full/half card rows
- [ ] Case studies end with a working next-project link
- [ ] Contact form handles all states
- [ ] Overlay text passes contrast on every slide