Template
Paloma Arce
A long, airy masonry gallery for an urban and architectural photographer. A single centered text nav filters between collections, and dozens of pastel-toned photographs float in a staggered four-column grid with generous white space. Clicking any image opens a full-screen lightbox with publication details.
Masonry architecture photography 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.
Start from this templateRead the build prompt
Typefaces
A neutral system-like sans keeps the gallery quiet so the images lead, and Castoro's soft Dutch italic gives the publication titles a serene, bookish touch.
- RobotoHeadings: brand name 24px regular in nav
- RobotoBody: body 16-18px, captions 14px
- CastoroAccent: italic publication titles in the lightbox, 20px+
Who it is for
- Architectural and urban photographers
- Photographers moving from offline networking to online leads
- Agencies organizing multi-client galleries
- Artists with large, consistent bodies of work
Layout
- Centered one-line nav: collection links (Urban, Architecture) left of the larger brand name, Info and Email me to the right; the active item is dark and the rest light gray
- Four-column masonry grid of portrait and landscape images with wide gutters (~75px) and varied vertical offsets
- Credit caption per image (photographer, source)
- Full-screen lightbox with publication metadata and keyboard navigation
- Client marquee banner
- Info page with bio and contact
Palette
Serene, pastel, spacious, curated, dreamy. It reads like a white-walled gallery hung with soft, sunny architecture prints.
- background
#ffffff - text / active nav
#09090b - inactive nav
#71717a - accent surface
#f4f4f5 - border
#e4e4e7 - photo tone (pastel sky)
#a9cfe0
Every checked pair, measured again
| Sample | Where | Ratio | Needs |
|---|---|---|---|
| Aa | active nav and body text on white | 19.90:1 | 4.5:1 |
| Aa | inactive nav on white | 4.83:1 | 4.5:1 |
| Aa | image credit captions on white | 4.83:1 | 4.5:1 |
| Aa | lightbox metadata text on white | 19.90:1 | 4.5:1 |
| focus ring on white | 19.90:1 | 3:1 | |
| Aa | dusk theme body text | 15.31:1 | 4.5:1 |
| Aa | dusk theme inactive nav | 7.37:1 | 4.5:1 |
| dusk theme focus ring | 15.31: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
- System sans (Helvetica-like), 24px regular for the brand name in nav (the system face is not on Google Fonts; a vibld project loads Roboto)
- Body
- System sans 16-18px at 1.5 line-height; captions 14px (the system face is not on Google Fonts; a vibld project loads Roboto)
The type is deliberately neutral and small so the images carry the page; an optional Castoro serif can be used for publication titles.
Spacing and imagery
Four equal columns within ~1100px, very wide gutters, images at natural aspect ratio with staggered tops; long page (~6000px); no radius.
Minimalist architectural and landscape photographs with pale blue skies and pastel facades, shown uncropped at natural ratios.
Components
- Centered text nav with collection filters
- Brand wordmark in nav center
- Masonry image grid
- Image credit caption
- Full-screen lightbox
- Publication metadata panel
- Client marquee
- Info/about page
- Email link
- Theme switch (dual colors)
Interactions
- Filter collections via nav links with an animated grid reflow
- Images fade/slide in as they load
- Hover dims other images or slightly lifts the hovered one
- Lightbox with arrow keys, Esc and swipe
- Marquee scrolls continuously and pauses on hover
- Nav gains a solid white background over images on scroll
Data
Photo{id, src, width, height, alt, collection, credit, publication?, year?}Collection{slug, title}Client{name}
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 an image-first masonry portfolio for a fictional architecture photographer, "Paloma Arce". It is for creative directors and editors browsing a large body of consistent work. There is no hero. The page opens straight into a calm, gappy masonry grid, and a centered nav filters it by collection. Any image expands into a lightbox that shows where it was published.
### Stack
React 18 + TypeScript + Vite, Tailwind CSS, shadcn/ui (Radix Dialog) and lucide-react. Use React Spring for grid reflow and lightbox transitions, plus a small masonry helper that places each image in the shortest column so tab order is preserved. Use React Router with `?c=` for the collection filter. Static only; "Email me" is a `mailto:`.
### Pages & layout
1. Sticky nav, centered on one line: collection links, the brand name at 24px, then Info and Email me. The active item is near-black and the others gray. On scroll, the bar turns solid white with a hairline so nav text never sits on a photo.
2. Grid: 4 columns at 1200px and up, 3 at 900px, 2 at 600px and 1 below that. Column gap is 72px on desktop and 24px on mobile. Images keep their natural ratio. Give columns different top offsets (0 / 24 / 48 / 0px) for a drifting rhythm.
3. Lightbox: the image is contained on white. A side or bottom panel shows the title, publication, year and credit, plus prev/next, a counter and close.
4. A client marquee strip near the bottom, with fictional names.
5. Info page: a short bio, services, email and social links.
### Design system
- `--background: #ffffff`, `--foreground: #09090b`, `--nav-inactive: #71717a`, `--muted: #f4f4f5`, `--border: #e4e4e7`. An alternate "dusk" theme uses #0f1115 background, #e7e7ea text and #a1a1aa inactive nav.
- Fonts: Roboto for UI and Castoro italic for publication titles in the lightbox, both from Google Fonts. Scale: 12 / 14 / 16 / 18 / 24px; 12px only for credits. Publication titles in Castoro italic are set at 20px or larger.
- Spacing: 8px base. Radius 0 and no shadows.
- Motion: spring (tension 170, friction 26) for reflow, 400ms opacity fade on image load and 40s linear marquee.
### Components & interactions
- NavFilter: link buttons with `aria-current`. The hover color shifts toward the foreground.
- MasonryItem: shows a blurred low-res placeholder, then fades to full. Hover and focus lift it 2px or dim its siblings. Enter opens the lightbox.
- Lightbox: arrow keys, swipe and Esc; focus returns on close. If an image fails, show a neutral tile with its title.
- Marquee: duplicated track that pauses on hover or focus and is static under reduced motion.
- Empty collection: "No photographs in this collection yet."
### Data & state
`Photo{id, src, w, h, alt, collection, credit, publication?, year?}` and `Collection{slug, title}` live in typed JSON. The filter lives in the URL and the lightbox index lives in local state. Seed 40-60 placeholder images across two collections. Credits are fictional or say "Sample image".
### Accessibility
- Inactive nav items use #71717a (4.83:1 on white), and the active item adds `aria-current` plus an underline so color is not the only cue.
- Masonry DOM order must follow visual reading order: fill row-wise, or at least keep focus order predictable.
- Every photo needs descriptive alt text, and the lightbox is a labelled dialog.
- The marquee has a pause control and reduced-motion support.
- Verified contrast: body #09090b on #ffffff = 19.9:1; inactive nav #71717a on #ffffff = 4.83:1; dusk body #e7e7ea on #0f1115 = 15.31:1; dusk inactive #a1a1aa on #0f1115 = 7.37:1.
### Security
- No user input apart from `mailto:`.
- External links use `rel="noopener noreferrer"`.
- No keys in client-side code. Validate the JSON shape with zod at build time.
### Performance & SEO
With 60+ images, lazy-load everything past the first row, use `srcset`/AVIF, set explicit width and height, and decode asynchronously. Consider virtualizing if the grid grows past 150 items. Add per-collection titles, OG images and an ImageGallery JSON-LD.
### 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:
- [ ] Grid reflows smoothly across 1-4 columns with no overlap
- [ ] Collection filter is reflected in the URL
- [ ] Lightbox shows metadata and supports keyboard/swipe
- [ ] Nav colors meet 4.5:1
- [ ] First contentful image loads under 2.5s on 4G