Skip to main content
vibld

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

  1. 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
  2. Four-column masonry grid of portrait and landscape images with wide gutters (~75px) and varied vertical offsets
  3. Credit caption per image (photographer, source)
  4. Full-screen lightbox with publication metadata and keyboard navigation
  5. Client marquee banner
  6. 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

SampleWhereRatioNeeds
Aaactive nav and body text on white19.90:14.5:1
Aainactive nav on white4.83:14.5:1
Aaimage credit captions on white4.83:14.5:1
Aalightbox metadata text on white19.90:14.5:1
focus ring on white19.90:13:1
Aadusk theme body text15.31:14.5:1
Aadusk theme inactive nav7.37:14.5:1
dusk theme focus ring15.31: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
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

Open the builderAll templatesThis palette on its own