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
- Top bar: bold name left; three circular grid-density toggles (single, 2x2, dense grid) right
- Split viewport divided by a thin vertical rule
- Left pane (fixed): huge tight-tracked name, 'Visual Artist & Photographer', studio address, email, links
- Right pane (scrolling): two-column grid of square images with wide gutters
- Statement/about panel that opens over the grid with a Close control
- 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
| Sample | Where | Ratio | Needs |
|---|---|---|---|
| Aa | text on white | 21.00:1 | 4.5:1 |
| selected toggle ring / primary on white | 17.93:1 | 3:1 | |
| unselected toggle outline on white | 4.74:1 | 3:1 | |
| Aa | captions and error-tile text on white | 4.74:1 | 4.5:1 |
| Aa | statement sheet text on white | 21.00:1 | 4.5:1 |
| focus ring on white | 21.00:1 | 3:1 | |
| Aa | image placeholder tile text on muted | 16.44:1 | 4.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