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.
Add app screens
Pick up to 6 screens, such as a dashboard, settings or an empty state. Each is built in this design’s own palette and typefaces, with its states and guardrails.
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 15+ color tokens vibld styles a project with, each text color 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 color 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, labeled 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 labeled 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