Skip to main content
vibld

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

  1. Fixed left sidebar: large name, role subtitle, stacked pill nav (Work, About), bottom 'Say hello!' pill and circular social icon buttons, copyright
  2. Right content: two-column grid of large 4:3 artwork images with generous rounded corners
  3. Artwork detail page: large image, title, year, medium, description, next/prev
  4. About page with statement and exhibition history
  5. 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

SampleWhereRatioNeeds
Aabody text on linen13.39:14.5:1
Aamuted role text on linen5.19:14.5:1
Aamuted text on card4.84:14.5:1
Aapill text on secondary fill11.72:14.5:1
Aaactive pill: linen text on dark fill13.39:14.5:1
Aatext on card surface12.49:14.5:1
focus ring on linen13.39:13:1
social icon on secondary fill11.72: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
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

Open the builderAll templatesThis palette on its own