Template
Odile Varenne
A warm, gallery-like portfolio for a visual artist. A fixed left sidebar holds the artist's name, pill-shaped navigation, a 'Say hello!' button and social icons, while a two-column grid of large rounded artwork images scrolls on the right. Detail pages present each piece, and a physics cursor plus blur-to-focus loading add polish.
Linen-toned painter portfolio with sidebar · 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
Afacad is a soft, refined modern sans with a gentle calligraphic touch, and Kumbh Sans stands in for Satoshi, keeping the linen-walled salon quiet.
- AfacadHeadings: name 60px 500 at -1.5px
- Kumbh SansBody: body 16px, 500 for pills and buttons
Who it is for
- Painters and visual artists
- Photographers presenting gallery-style work
- Design agencies showing client pieces
- Artists seeking premium commissions
Layout
- Fixed left sidebar: large name, role subtitle, stacked pill nav (Work, About), bottom 'Say hello!' pill and circular social icon buttons, copyright
- Right content: two-column grid of large 4:3 artwork images with generous rounded corners
- Artwork detail page: large image, title, year, medium, description, next/prev
- About page with statement and exhibition history
- Mobile: sidebar collapses into a top bar with a drawer
Palette
Warm, gentle, refined, tactile, gallery-quiet. It feels like a linen-walled salon hung with classic paintings.
- background (warm linen)
#f6f1ea - text
#292623 - pill / secondary
#eae2d7 - card
#f0e9e0 - accent
#e6d7cb - muted
#e2dacf - border
#e5e1dc - muted text
#6b645c
Every checked pair, measured again
| Sample | Where | Ratio | Needs |
|---|---|---|---|
| Aa | body text on linen | 13.39:1 | 4.5:1 |
| Aa | muted role text on linen | 5.19:1 | 4.5:1 |
| Aa | muted text on card | 4.84:1 | 4.5:1 |
| Aa | pill text on secondary fill | 11.72:1 | 4.5:1 |
| Aa | active pill: linen text on dark fill | 13.39:1 | 4.5:1 |
| Aa | text on card surface | 12.49:1 | 4.5:1 |
| focus ring on linen | 13.39:1 | 3:1 | |
| social icon on secondary fill | 11.72: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 500, 60px, -1.5px tracking for the name (Clash Grotesk is not on Google Fonts; a vibld project loads Afacad)
- Body
- Satoshi 16px at 1.6 line-height (14px only for the copyright), 500 for pills and buttons (Satoshi is not on Google Fonts; a vibld project loads Kumbh Sans)
A soft modern grotesk pairing; warm neutrals keep the tone gentle and gallery-like.
Spacing and imagery
Sidebar ~300px wide with 32px padding; grid gap 24px; images radius ~24px; pills fully rounded (9999px).
Classical-style paintings and gallery interiors (florals, landscapes, portraits) in large rounded frames, loaded with blur-to-focus.
Components
- Fixed sidebar
- Pill navigation buttons
- Say hello pill CTA
- Circular social icon buttons
- Two-column rounded artwork grid
- Blur-to-focus image loader
- Physics-based custom cursor
- Artwork detail page
- About page
- Mobile drawer (Vaul)
- Toasts
Interactions
- Custom cursor dot follows the pointer with spring damping and grows over links/images
- Images load blurred and sharpen when in view
- Staggered entrance animations for grid items
- Pills darken on hover; the active pill is filled dark with linen text
- Say hello opens email/contact drawer and toast on copy
- Artwork hover slightly scales the image
Data
Artwork{slug, title, year, medium, dimensions, image, description}Artist{name, role, statement, email, socials[], since}Exhibition{title, venue, year}
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 warm, gallery-style portfolio for a fictional painter, "Odile Varenne". It serves collectors and galleries who want to browse paintings calmly. A fixed sidebar carries the identity and navigation, and the main area is a two-column wall of large, softly rounded artworks. Each piece has its own page. Small touches like a springy cursor and blur-to-focus loading make it feel crafted.
### Stack
React 18 + TypeScript + Vite, Tailwind CSS, shadcn/ui (Radix Button, Tooltip), Vaul for the mobile drawer, Sonner for toasts and lucide-react. Use Framer Motion for springs and staggered entrances and React Router for `/`, `/work/:slug` and `/about`. Static only; contact is `mailto:` with a copy-to-clipboard fallback.
### Pages & layout
1. Sidebar, fixed on desktop and 300px wide: the name at 60px, a role line in muted text (#6b645c), then vertical pill links. Pinned to the bottom are a "Say hello!" pill, round LinkedIn/Instagram icon buttons and a small copyright range.
2. Main grid: 2 columns with a 24px gap and 48px top padding. Images are 4:3 with a 24px radius.
3. Artwork page: a large image (contain), title, year, medium, dimensions, a short description and prev/next links.
4. About: statement paragraphs and an exhibition list.
5. Under 900px the sidebar becomes a top bar with a Vaul drawer and the grid becomes 1 column.
### Design system
- `--background: #f6f1ea`, `--foreground: #292623`, `--secondary: #eae2d7`, `--card: #f0e9e0`, `--accent: #e6d7cb`, `--muted: #e2dacf`, `--border: #e5e1dc` (decorative), `--muted-foreground: #6b645c`, `--radius: 1rem` (images 1.5rem, pills 9999px).
- Fonts: Clash Grotesk 500 for display and Satoshi 400/500 for UI, both from Fontshare. Fallbacks are Afacad and Kumbh Sans from Google Fonts. Scale: 12 / 14 / 16 / 24 / 60px.
- Spacing: 8px base; sidebar padding 32px.
- Motion: cursor spring (stiffness 300, damping 28), image blur from 20px to 0 over 700ms, grid stagger 60ms. Light only.
### Components & interactions
- PillNav: states for default (border), hover (`--secondary` fill), active (filled `--foreground` with linen text, so the state is clear at 13:1) and focus-visible (2px ring).
- SayHello: opens a small popover with the email address and a copy button, and shows a toast on copy.
- ArtworkImage: blurred low-res first, sharp when intersecting, and a soft placeholder tile on error. Hover scales it to 1.02.
- CustomCursor: an 8px dot that grows to 40px over interactive elements. Disable it on touch and under reduced motion, and always keep the native cursor available.
### Data & state
Typed data: `Artwork{slug, title, year, medium, dimensions, image, description}`, `Artist{name, role, statement, email, socials}` and `Exhibition{title, venue, year}`. Seed 8-12 public-domain-style placeholder paintings with invented titles.
### Accessibility
- #292623 on #f6f1ea is 13.39:1. Muted role text uses #6b645c (5.19:1 on the background, 4.84:1 on cards).
- Icon buttons need `aria-label`s. The sidebar is a `<nav>`.
- The custom cursor is decorative and must never hide focus or replace the system cursor for accessibility tools.
- Artwork alt text describes subject and medium.
- Verified contrast: body #292623 on #f6f1ea = 13.39:1; muted #6b645c on #f6f1ea = 5.19:1; pill #292623 on #eae2d7 = 11.72:1; active pill #f6f1ea on #292623 = 13.39:1.
### Security
- No form submission. Clipboard API with graceful fallback.
- External links use `rel="noopener noreferrer"`. No secrets in client-side code.
### Performance & SEO
Use progressive images (tiny LQIP plus `srcset`), lazy-load past the first row, and self-host fonts with `font-display: swap`. Add VisualArtwork JSON-LD and OG images per artwork.
### 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:
- [ ] Sidebar stays fixed on desktop and becomes a drawer on mobile
- [ ] Images progress from blur to sharp without layout shift
- [ ] Custom cursor is disabled on touch and reduced-motion
- [ ] Say hello copies email with a toast
- [ ] Artwork pages link prev/next