Template
Kasimir Lund
A visual-first portfolio for a graphic designer or illustrator presented as a masonry grid of rounded image cards with titles and hashtag-style tags. Category pills filter the work, a floating bottom pill nav switches between Work, About and Contact, and a dark-mode toggle flips the monochrome UI.
Masonry illustrator 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
Hind is a plain, quiet sans that keeps the UI small and neutral so the artwork dominates, and Crimson Pro is a sturdy book serif for the storytelling pages.
- HindHeadings: studio name 18-20px medium
- HindBody: body 16px, tags 14px
- Crimson ProAccent: editorial headings on about and project pages
vibld has built this product: see its example, generated from one sentence. An illustrator's portfolio with a gallery and a short bio.
Who it is for
- Designers and illustrators
- Digital artists
- Creative studios presenting client work
- Freelancers building a personal brand
Layout
- Top bar: studio name left, centered category pills (everything active in black, illustration, digital art, abstract, editorial), moon icon theme toggle right
- Masonry grid (3 columns desktop, 2 on mobile) of large rounded image cards with title and #tags under each
- Floating translucent bottom-center pill nav: Work (active white pill), About, Contact
- Project detail pages with multi-image layouts
- About page
- Contact page
Palette
Clean, colorful, contemporary, gallery-like, calm. A neutral frame for vivid work.
- background
#ffffff - text
#0d0d0d - active pill
#0d0d0d - secondary
#f5f5f5 - muted
#f0f0f0 - decorative border
#e6e6e6 - input border (light)
#8f8f8f - tag gray
#6b6b6b - dark background
#0d0d0d - dark secondary
#1f1f1f - dark tag gray
#a6a6a6 - dark input border
#737373
Every checked pair, measured again
| Sample | Where | Ratio | Needs |
|---|---|---|---|
| Aa | light: body text | 19.44:1 | 4.5:1 |
| Aa | light: text on secondary | 17.83:1 | 4.5:1 |
| Aa | light: tags on white | 5.33:1 | 4.5:1 |
| Aa | light: tags on secondary | 4.89:1 | 4.5:1 |
| Aa | light: white on active black pill | 19.44:1 | 4.5:1 |
| light: input border | 3.23:1 | 3:1 | |
| Aa | light: nav labels on 85% white pill over black-worst-case artwork | 13.77:1 | 4.5:1 |
| Aa | dark: body text | 17.83:1 | 4.5:1 |
| Aa | dark: tags on secondary | 6.77:1 | 4.5:1 |
| dark: input border | 4.10:1 | 3:1 | |
| Aa | dark: nav labels on 85% pill over white-worst-case artwork | 9.36:1 | 4.5:1 |
| focus ring on white | 19.44:1 | 3:1 | |
| Aa | light: text on muted surface | 17.05: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
- Hind medium 18-20px for studio name; Crimson Pro available for editorial headings on inner pages
- Body
- Hind 16px (14px for tags), line-height 1.6; tags in #6b6b6b
UI stays quiet and small so the artwork dominates; serif reserved for about/project storytelling
Spacing and imagery
24px gutters, 16px column gaps, ~24px card radius, pill buttons, titles 16px below images
Vivid 3D renders, illustrations, collage, typography posters, product and stationery mockups in varied aspect ratios
Components
- Top bar with category pills
- Theme toggle
- Masonry grid
- Rounded image card with title and tags
- Floating bottom pill nav
- Project detail page
- Image carousel
- About section
- Contact form
- Toasts
- Mobile drawer
Interactions
- Category pill filters grid with fade
- Staggered fade-in as cards enter viewport
- Dark mode toggle
- Card hover lifts/zooms image
- Floating nav active pill slides
- Lazy image loading
- Toast on form submit
Data
Project{slug, title, tags[], categories[], cover, images[], description, client?, year}Category{slug, label}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 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 portfolio for a fictional independent illustrator and designer called **Kasimir Lund**. The audience is art directors and brands scanning for a visual match. The home page is a masonry wall of rounded project cards that can be filtered by category; a floating pill nav handles Work, About and Contact, and the whole UI can switch to dark mode.
### Stack
React 18 + TypeScript + Vite, Tailwind CSS with HSL CSS variables, shadcn/ui (Radix Toggle Group, Dialog, Form), lucide-react, React Router, Framer Motion for filter transitions and nav pill `layoutId`, Embla for project galleries, Sonner for toasts, Vaul for mobile sheets, and react-hook-form + zod. The contact form posts to one serverless function (a Supabase edge function or similar).
### Pages & layout
1. Top bar: studio name left; centered category pills (Everything, Illustration, Digital art, Abstract, Editorial) with the active one filled black; a moon/sun icon toggle right.
2. Masonry grid: 3 columns on desktop, 2 on tablet and mobile, 16px gaps; each card is a rounded image with its natural aspect ratio, then a title and gray hashtag tags.
3. Floating bottom nav: a translucent blurred pill (background at 85% opacity so labels stay above 4.5:1 over any artwork) centered at the bottom with Work, About and Contact; the active item is a white inner pill that slides.
4. Project page: title in an elegant serif, client, year, tags, intro, then a sequence of full-width and paired images, plus a carousel for process shots; previous and next project links.
5. About: portrait, serif pull quote, bio, services, tools.
6. Contact: short form and email.
### Design system
Light: `--background: 0 0% 100%; --foreground: 0 0% 5%; --secondary: 0 0% 96%; --muted: 0 0% 94%; --border: 0 0% 90% (decorative); --input-border: 0 0% 56% (#8f8f8f); --muted-foreground: 0 0% 42% (#6b6b6b)`. Dark: `--background: 0 0% 5%; --foreground: 0 0% 96%; --secondary: 0 0% 12%; --border: 0 0% 18% (decorative); --input-border: 0 0% 45% (#737373); --muted-foreground: 0 0% 65% (#a6a6a6)`. Fonts: Hind 400/500 for UI and Crimson Pro 500 for editorial headings. Scale: clamp(32px, 5vw, 56px) serif titles; 18 / 16 / 14 / 13px (16px body at line-height 1.6, max 70ch; 13–14px only for tags and meta at weight 400+). Radius: 24px cards, 9999px pills. Shadow only on the floating nav: `0 8px 30px rgb(0 0 0 / .12)`. Motion: 400ms staggered fade-up (60ms step); 250ms filter crossfade; spring for the nav pill.
### Components & interactions
- Filter pills: toggle group with `aria-pressed`; updates the URL (`?c=illustration`); an empty state with a reset button.
- Card: hover scales the image to 1.03 inside a clipped frame; focus ring; skeleton with a fixed aspect ratio; broken-image fallback.
- Theme toggle: respects the system theme first; persists; avoids a flash by setting the class in `index.html`.
- Floating nav: stays above the grid, adapts to theme, and keeps a safe-area inset on iOS.
- Contact form: validation, loading, success and error toasts.
### Data & state
`Project{slug,title,tags[],categories[],cover{src,w,h},images[],description,client?,year}`, `Category{slug,label}`. Static typed data; the filter lives in the URL. Seed 16 projects with invented titles and clients.
### Accessibility
Tag gray is #6b6b6b (light) and #a6a6a6 (dark); inputs use #8f8f8f and #737373 borders; the floating nav is 85% opaque in both themes. The floating nav must not cover focused elements; add bottom padding equal to its height. Masonry order in the DOM should follow visual reading order (use column-major or a JS masonry that preserves order). Alt text for every artwork. Reduced motion removes staggered reveals and zooms. Verified contrast: light: tags on white: #6b6b6b on #ffffff = 5.33:1; light: nav labels on 85% white pill over black-worst-case artwork: #0d0d0d on #d9d9d9 = 13.77:1; dark: nav labels on 85% pill over white-worst-case artwork: #f5f5f5 on #414141 = 9.36:1.
### Security
Validate the contact form with zod on the client and in the edge function, add a honeypot and rate limit, and keep keys server-side. If project descriptions are Markdown, sanitize them with DOMPurify. External links use `rel="noopener noreferrer"`.
### Performance & SEO
With 30+ images, serve responsive AVIF/WebP with width descriptors, lazy-load everything below the first row, and reserve aspect ratios to prevent layout shift. Code-split project pages. Per-project meta and OG images; CreativeWork JSON-LD. Target CLS under 0.05.
### Guardrails
- Use placeholder or generated artwork and invented client names; don't imply work for real publications.
- No fabricated testimonials.
- Store only contact form fields.
- Keep components small and typed, never use `any`, and surface load errors visibly.
- Done when: filters deep-link and animate; both themes pass AA for text; the floating nav never hides focused content; project pages resolve by slug; the grid has no layout shift while images load.