Skip to main content
vibld

Template

Idris Vale

A restrained, Swiss-style split-screen site for a fine-art photographer. The left half holds a large Helvetica name, discipline, studio address and email, and the right half is a scrolling grid of square photographs. Small circular icons switch grid density, and an artist-statement panel can be opened and closed.

Swiss split-screen fine-art photo site · 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

Gothic A1's Latin is a clean, Helvetica-like grotesk, so the contact-sheet page keeps its classic Swiss single-family look.

  • Gothic A1Headings: name ~100px 500 at -4px, bold top name 22px
  • Gothic A1Body: address and statement ~20px regular, captions 14px

Who it is for

  • Fine art and editorial photographers
  • Artists pairing images with an artist statement
  • Photographers curating a small best-work selection
  • Gallery-represented creatives who need a contact card site

Layout

  1. Top bar: bold name left; three circular grid-density toggles (single, 2x2, dense grid) right
  2. Split viewport divided by a thin vertical rule
  3. Left pane (fixed): huge tight-tracked name, 'Visual Artist & Photographer', studio address, email, links
  4. Right pane (scrolling): two-column grid of square images with wide gutters
  5. Statement/about panel that opens over the grid with a Close control
  6. Single-image view when the largest density is selected

Palette

Quiet, precise, Swiss, contemplative, gallery-grade. It reads like an artist's contact sheet printed on white card.

  • background#ffffff
  • text#000000
  • primary#171717
  • divider#e6e6e6
  • muted surface#f5f5f5
  • photo accent (teal)#0e6a80
  • control border / captions#737373

Every checked pair, measured again

SampleWhereRatioNeeds
Aatext on white21.00:14.5:1
selected toggle ring / primary on white17.93:13:1
unselected toggle outline on white4.74:13:1
Aacaptions and error-tile text on white4.74:14.5:1
Aastatement sheet text on white21.00:14.5:1
focus ring on white21.00:13:1
Aaimage placeholder tile text on muted16.44:14.5: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
Helvetica Neue 500, ~100px, very tight -4px tracking (Helvetica Neue is not on Google Fonts; a vibld project loads Gothic A1)
Body
Helvetica Neue ~20px regular for address and statement; 22px bold for the top name (Helvetica Neue is not on Google Fonts; a vibld project loads Gothic A1)

Classic Swiss single-family typography; scale and tracking create hierarchy with no decoration.

Spacing and imagery

Exact 50/50 split, generous 48px padding, square thumbnails ~250px with ~50px gutters, fully rounded icon buttons (9999px), no other radius.

Mostly black-and-white fine-art photography (landscapes, reeds, lone figures) with occasional color, cropped square.

Components

  • Name wordmark
  • Grid-density toggle buttons (circular icons)
  • Split-screen shell with vertical rule
  • Large name display
  • Address and email block
  • Square image grid
  • Artist statement panel with Close
  • Single-image viewer
  • Mobile stacked layout

Interactions

  • Density toggles switch between 1-up, 2-up and dense grids with smooth transitions
  • Right pane scrolls independently of the fixed left pane
  • Clicking an image enlarges it into single view
  • Statement panel slides open and closes via button or Esc
  • Images fade in lazily
  • Keyboard arrows move between images in single view

Data

  • Photo{id, src, alt, series, year}
  • Artist{name, discipline, address, email, statement, links[]}

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 Swiss-minimal split-screen site for a fictional fine-art photographer, "Idris Vale". It serves curators, editors and collectors who want an artist's contact details and a tight selection of images at a glance. The left half is a typographic calling card and the right half is a photo grid whose density the visitor can change. An artist statement opens in a panel.

### Stack
React 18 + TypeScript + Vite, Tailwind CSS, shadcn/ui (Radix Sheet or Dialog for the statement, ToggleGroup for density) and lucide-react. Use Framer Motion `layout` animations for density changes and Embla Carousel for the single-image view with swipe. Static only.

### Pages & layout
1. Top bar: the name in 22px bold on the left and three 32px circular toggle buttons on the right: one large dot (single), four dots (2x2) and a dot grid (dense).
2. Shell at 100dvh on desktop with a 1px vertical rule at 50%.
3. Left pane, not scrolling: the name at clamp(56px, 8vw, 104px) with weight 500 and -0.04em tracking over two lines; the discipline line at 28px; then the studio address, email and 2-3 links at 20-24px, spaced apart.
4. Right pane, scrolling: square thumbnails in a 2-column grid with 48px gaps by default. Dense uses 4 columns and 16px gaps. Single shows one image per row at full pane width, with captions.
5. Statement panel: a sheet covering the right pane with the artist bio in 20px text and a Close button.
6. Mobile: the left pane becomes a header block, the grid follows and the toggles stay in the top bar.

### Design system
- `--background: #ffffff`, `--foreground: #000000`, `--primary: #171717`, `--border: #e6e6e6`, `--muted: #f5f5f5`, `--control-border: #737373` (unselected toggle outlines), `--muted-foreground: #737373`, `--radius: 0` (icon buttons are fully round). The #e6e6e6 rule is decorative.
- Font: Helvetica Neue with an Gothic A1 fallback (Google Fonts), weights 400/500/700. Scale: 14 / 20 / 28 / 56 / 104px; 14px only for captions, prose at 20px with 1.5 line-height and a ~65ch measure.
- Spacing: 8px base; 48px pane padding. No shadows.
- Motion: 350ms ease-in-out for layout transitions and 250ms for the sheet slide. Light only.

### Components & interactions
- DensityToggle: a Radix ToggleGroup (single-select) with `aria-label` on each option. Selected is a filled black ring; hover darkens the outline; the focus ring is visible.
- PhotoGrid: animates between densities. Images show a gray placeholder until loaded and a neutral tile with the title on error.
- SingleView: arrows, swipe, a counter and Esc to return to the grid.
- StatementSheet: states for open and closed; it traps focus and has a Close button.

### Data & state
`Photo{id, src, alt, series, year}` and `Artist{name, discipline, address, email, statement, links}` as typed data. Density is stored in the URL (`?view=`) so it can be shared. Seed about 30 placeholder images, mostly monochrome with a few color frames. The address is fictional.

### Accessibility
- The independently scrolling pane needs `tabindex="0"`, a label and a visible focus state.
- Icon toggles need text labels such as "Single image view". Don't rely on the icon shape alone; unselected outlines use #737373 so the control boundary reaches 3:1.
- Name and address are real text. The email is a `mailto:` link.
- Respect reduced motion by switching densities without animation.
- Verified contrast: text #000000 on #ffffff = 21.0:1; selected toggle #171717 on #ffffff = 17.93:1; toggle outline #737373 on #ffffff = 4.74:1; captions #737373 on #ffffff = 4.74:1.

### Security
- No forms. `mailto:` only.
- External links use `rel="noopener noreferrer"`.
- Don't publish a real home address; use a studio or PO-style placeholder.

### Performance & SEO
Serve square-cropped `srcset` thumbnails and fetch full sizes only in single view. Lazy-load below the fold. Add Person JSON-LD, OG tags and a descriptive title and meta description.

### 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:
  - [ ] Three density modes animate between each other and persist in URL
  - [ ] Left pane stays fixed while right pane scrolls on desktop
  - [ ] Toggles are keyboard operable with clear labels
  - [ ] Statement sheet opens/closes with focus management
  - [ ] Mobile layout stacks without horizontal scroll

Open the builderAll templatesThis palette on its own