Template
Harbor & Pine
A minimalist monospace portfolio for an independent designer: a fixed left sidebar with studio name, page links and contact links, and a main column with a short intro followed by a flowing masonry of project images in full, half and third widths. Case study pages, an about page, a styleguide and a validated contact form round it out.
Monospace designer 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.
Add app screens
Pick up to 6 screens, such as a dashboard, settings or an empty state. Each is built in this design’s own palette and typefaces, with its states and guardrails.
Start from this templateRead the build prompt
Typefaces
Cutive Mono is a single-weight typewriter face, which suits a regular-weight-only, typewritten designer notebook.
- Cutive MonoHeadings: intro 20-24px regular
- Cutive MonoBody: body 16px, nav and meta 13px
Who it is for
- Freelance designers and illustrators
- Independent consultants
- Agencies needing white-label portfolio sites
- Designers wanting a distinctive personal site
Layout
- Fixed left sidebar: two-line studio name top, Work (underlined active) / About / Styleguide, then Email / Instagram / LinkedIn with arrows at bottom
- Main column: monospace intro paragraph
- Flow masonry grid of project images in full-width, half and third-width tiles with tight 4px gaps
- Project case study pages with role, team, timeline metadata and next/previous navigation
- About page
- Styleguide page
- Contact form
- Mobile: header with right slide-in drawer
Palette
Minimal, quiet, typographic, honest, crafted. It feels like a designer's working notebook.
- background
#ffffff - text
#000000 - muted text
#555555 - secondary/muted tint (black 5% = #f2f2f2)
#0000000d - decorative border (black 10%)
#0000001a - input border
#767676 - primary
#000000
Every checked pair, measured again
| Sample | Where | Ratio | Needs |
|---|---|---|---|
| Aa | body text on white | 21.00:1 | 4.5:1 |
| Aa | muted text on white | 7.46:1 | 4.5:1 |
| Aa | muted text on 5% tint | 6.66:1 | 4.5:1 |
| Aa | text on 5% tint | 18.76:1 | 4.5:1 |
| Aa | white hover label on black | 21.00:1 | 4.5:1 |
| input border on white | 4.54:1 | 3:1 | |
| focus ring on white | 21.00:1 | 3:1 | |
| active nav underline on white | 21.00:1 | 3:1 |
As vibld’s tokens
The palette on the 15+ color tokens vibld styles a project with, each text color 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
- Cutive Mono regular (400) 20-24px for intro
- Body
- Cutive Mono 16px regular for body (line-height 1.6); 13px regular for nav and meta
All-monospace at regular weight reads like a typewritten index; no display type
Spacing and imagery
40px sidebar padding, ~180px sidebar, main column from 220px with 40px right margin, 4px image gaps, zero radius
Documentary-style photos of design objects, books, lifestyle and art in varied crops arranged edge-to-edge
Components
- Fixed sidebar nav
- Contact links with arrows
- Intro paragraph
- Flow masonry grid (full/half/third)
- Project tile
- Case study metadata block
- Sequential project navigation
- Slide-in mobile drawer with overlay
- Contact form with validation
- Styleguide page
- Skip link
Interactions
- Scroll-reveal on tiles
- Hover dims/brightens tiles
- Mobile right drawer with dimmer and 50px targets
- Next/previous project navigation
- Form validation with inline errors
- Lazy-loaded images fade in
Data
Project{slug, title, role, team[], timeline, year, cover, width: full|half|third, images[], body}Profile{name, intro, email, instagram, linkedin}ContactMessage{name, email, message}
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 color 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, labeled 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 minimalist portfolio for a fictional independent designer called **Harbor & Pine**. The audience is brand managers and agencies looking for a thoughtful freelancer. Everything is set in a quiet monospace, with a fixed sidebar for navigation and contact and a flowing image grid of projects that leads into detailed case studies.
### Stack
React 18 + TypeScript + Vite, Tailwind CSS, shadcn/ui (Radix Sheet for the mobile drawer, Form), lucide-react, React Router with slug routes, Framer Motion for scroll reveals, Embla for case-study galleries, and react-hook-form + zod. The contact form posts to one serverless function.
### Pages & layout
1. Sidebar (fixed, ~180px): a two-line studio name at the top; Work, About and Styleguide links (active underlined); Email →, Instagram → and LinkedIn → at the bottom.
2. Work (home): an intro paragraph in 20–24px regular (400) monospace, max ~60ch; then a flow grid where each project tile declares its width (full, half or third) and tiles pack left to right with 4px gaps.
3. Case study: title, a metadata block (role, team, timeline, year), intro, image sequence using the same full/half/third system, and previous/next project links.
4. About: portrait, longer bio, services, and selected clients (fictional).
5. Styleguide: shows type sizes, colors, spacing and components.
6. Contact: form with name, email and message.
Mobile: top bar with the name and a menu button; the right-side drawer has a dimmed overlay and 50px tap targets.
### Design system
Tokens: `--background: #ffffff; --foreground: #000000; --muted: rgb(0 0 0 / .05); --border: rgb(0 0 0 / .10) (decorative); --input-border: #767676; --muted-foreground: #555555; --radius: 0`. Font: Cutive Mono 400/500 (no light weights, since no text reaches 32px). Scale: 24 / 20 / 16 / 13px; nav 13px at weight 400; line-height 1.5 for intro and 1.6 for body, max 70ch. Spacing: 40px sidebar padding, 220px main offset, 4px grid gap, 64px section gaps. No shadows, no radius. Motion: 400ms opacity reveals; image fade-in on load; drawer 250ms slide. Light only.
### Components & interactions
- FlowGrid: CSS grid with 6 columns (full = span 6, half = span 3, third = span 2); tiles keep their own aspect ratios; on mobile everything is full width.
- Tile: hover lowers opacity to 0.9 and shows the title in a 13px white-on-black label; focus ring 2px black; a skeleton with fixed ratio while loading.
- Drawer: focus trap, Esc to close, overlay click closes, body scroll locked.
- Contact form: labeled fields, inline errors, loading, success and error messages (not just toasts).
### Data & state
`Project{slug,title,role,team[],timeline,year,cover{src,w,h},width,images[{src,w,h,width}],body}`, `Profile{name,intro,email,instagram,linkedin}`. Static typed data; next/previous computed from array order. Invent project names and clients.
### Accessibility
All text uses weight 400 or heavier so the monospace strokes stay legible at 13px, secondary text is #555555 (7.5:1 on white, 6.7:1 on the 5% tint), and form fields use a #767676 border so their edges reach 3:1. Include a skip link to main content. The sidebar is a `<nav>`; the image grid is a list of links with accessible names from project titles. All images get alt text. Reduced motion disables reveals. Verified contrast: body text on white: #000000 on #ffffff = 21.0:1; muted text on white: #555555 on #ffffff = 7.46:1; muted text on 5% tint: #555555 on #f2f2f2 = 6.66:1; input border on white: #767676 on #ffffff = 4.54:1.
### Security
Validate the contact form with zod on the client and in the function; add a honeypot and rate limiting; keep email-service keys server-side. External social links use `rel="noopener noreferrer"`.
### Performance & SEO
Serve AVIF/WebP with `srcset` matched to each tile's width; lazy-load everything except the first row; reserve aspect ratios. Code-split case-study routes. Person and CreativeWork JSON-LD; per-project meta and OG images. Target CLS under 0.05 and LCP under 2.5s.
### Guardrails
- Use original copy, invented clients and placeholder or licensed images; no real brand logos.
- Don't publish fabricated testimonials.
- Store only contact form fields.
- Keep components small and typed, never use `any`, and handle failed loads visibly.
- Done when: the flow grid packs full/half/third tiles correctly at three breakpoints; the mobile drawer is fully keyboard-operable; case studies link sequentially; the contact form shows inline success and error; the styleguide page lists all tokens.