Template
KRV Works
A brutalist, split-screen portfolio for a freelance designer. A giant monospace name fills the left half while a scrolling column of heavily bordered project cards runs on the right, followed by service categories and a contact prompt. It helps a designer stand out in pitches with a loud, graphic identity.
Brutalist split-screen design 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
Space Mono's quirky bold is rawer than a code mono, right for the Swiss-meets-zine typewriter poster, and Work Sans keeps paragraphs readable.
- Space MonoHeadings: display up to 160px 700 uppercase, labels and buttons 14px bold
- Work SansBody: paragraphs 16px at 1.6
Who it is for
- Freelance designers pitching competitively
- Creative directors building a personal brand
- Designers with brand, digital, print and motion work
- People who want an anti-corporate, high-contrast look
Layout
- Top bar: monospace initials logo left, three boxed nav buttons (Work / Info / Mail) right, thick 4px rule below
- Split viewport: left pane pinned with a huge stacked monospace name, red bar and 'Designer / Est.' tagline plus a teal color block
- Right pane scrolls independently: project cards with 4px black frame, grayscale image, bold title, subtitle and year
- Services grid: Brand, Digital, Print, Motion, each with a one-line descriptor
- Contact prompt: 'Let's work together' with a form or mail link
- Project detail pages with full/half-width image rows and circular next/previous navigation
Palette
Loud, raw, graphic, confident, playful. It feels like a Swiss-meets-zine poster with blocks of primary color and heavy rules.
- background (off-white paper)
#f9f7ec - ink / borders
#1a1a1a - signal red
#d62828 - teal block
#2e9a9a - muted text
#6b6b6b - button text on ink
#f9f7ec
Every checked pair, measured again
| Sample | Where | Ratio | Needs |
|---|---|---|---|
| Aa | body text (ink) on paper | 16.20:1 | 4.5:1 |
| Aa | muted subtitle/year text on paper | 4.96:1 | 4.5:1 |
| Aa | paper text on ink nav button (hover/focus) | 16.20:1 | 4.5:1 |
| 4px ink card and input borders on paper | 16.20:1 | 3:1 | |
| teal focus ring on paper | 3.15:1 | 3:1 | |
| teal focus ring against ink borders | 5.14:1 | 3:1 | |
| Aa | signal red if used for large labels on paper | 4.66:1 | 4.5: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
- System monospace (SFMono/Menlo) 700, up to 160px, uppercase with 0.05em tracking, tight leading (the system face is not on Google Fonts; a vibld project loads Space Mono)
- Body
- Work Sans 16px for longer copy; monospace 14px bold for labels and buttons
Monospace dominates for a raw, typewriter-poster feel; Work Sans is reserved for readability in paragraphs.
Spacing and imagery
Hard 50/50 split with a 4px vertical divider; cards separated by ~32px; all radii 0; 4px borders everywhere.
Project photos shown in grayscale inside thick black frames, turning to color on hover; flat color blocks (red, teal) as decorative shapes.
Components
- Boxed monospace nav buttons
- Monospace initials logo
- Pinned left hero with giant stacked name
- Decorative red bar and teal square
- Independently scrolling project column
- Framed project card with title, subtitle, year
- Grayscale-to-color image treatment
- Services grid (4 disciplines)
- Contact prompt with form
- Testimonial block
- Project detail gallery
- Circular project navigation
Interactions
- Hover on a card restores full color and nudges the frame offset (hard shadow)
- Boxed nav buttons invert to ink background on hover/focus
- Intersection-triggered fade/slide-in for cards
- Framer Motion page transitions between routes
- Keyboard arrow navigation between projects on detail pages
- Contact form inline validation with success message
Data
Project{slug, title, subtitle, year, cover, gallery[], discipline}Service{name, tagline}Testimonial{quote, author, role} (sample only)Inquiry{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 brutalist designer portfolio for a fictional studio of one called "KRV Works". It is for freelance designers who need to be memorable in competitive pitches. The home screen is a split layout: a huge monospace name is pinned on the left and a scrolling feed of framed projects runs on the right.
### Stack
React 18 + TypeScript + Vite, Tailwind CSS, shadcn/ui (Radix) primitives for dialog, toast and form, and lucide-react. Use React Router for `/` and `/work/:slug`, Framer Motion for route transitions and in-view reveals, and react-hook-form + zod for the contact form. No database is needed; post the form to a serverless function.
### Pages & layout
1. Header: monospace initials with an asterisk on the left. On the right are three square-cornered bordered buttons: Work, Info, Mail. A 4px rule sits below.
2. Split hero (desktop): the left 50% is sticky and holds the name in three stacked words at clamp(64px, 12vw, 160px), a red bar, a small "Designer / Est. 20XX" line and a teal square that bleeds off the bottom-left. The right 50% scrolls and holds project cards.
3. Project card: 4px ink frame around a 16:10 image, then a row with the short bold uppercase title (0.05em tracking), a muted subtitle and the year on the right.
4. Services: a 2x2 grid for Brand, Digital, Print and Motion, each with a one-line claim.
5. Contact: a big "Let's work together" heading, a short prompt and the form.
6. Mobile: stack panes, name above the feed.
### Design system
- Tokens: `--paper: #f9f7ec`, `--ink: #1a1a1a`, `--signal: #d62828`, `--teal: #2e9a9a`, `--muted: #6b6b6b`, `--focus: #2e9a9a`. Red and the teal block are decorative fills, never text colors.
- Fonts: Space Mono (700/400) for display, labels and buttons, and Work Sans 400/500 for paragraphs, both from Google Fonts. Scale: 12 / 14 / 16 / 24 / 48 / 96 / 160px; 12px only for short mono labels, paragraphs in Work Sans 16px with 1.6 line-height and a ~65ch measure.
- Borders are always 4px solid ink. Radius is 0 everywhere. Use hard offset shadows (`6px 6px 0 var(--ink)`) and no blur.
- Spacing: 8px base, 24px card gap, 64px sections.
- Motion: 150ms steps or linear for hovers and 400ms ease-out for reveals. Light only.
### Components & interactions
- NavButton: bordered by default. On hover or focus it gets an ink fill with paper text; the active state offsets by 2px.
- ProjectCard: grayscale by default. On hover or focus it shows full color and a hard shadow, and the image may scale 1.02.
- ContactForm: name, email, budget select and message. Include disabled and loading states, inline errors and a success panel.
- Detail page: cover, full/half image rows, wrap-around prev/next with arrow-key support.
### Data & state
Keep everything as typed static data. Projects look like `{slug, title, subtitle, year, cover, discipline, gallery}`. Services and optional testimonials are arrays. Seed six invented projects across the four disciplines.
### Accessibility
- Ink on paper passes AAA (16.2:1); muted #6b6b6b stays at 4.96:1 for subtitles and years. Red is decorative only; never use it to carry meaning or small text.
- The independently scrolling right pane must be keyboard-scrollable (`tabindex="0"` with a label) and must not trap focus.
- Focus ring: a 3px teal outline offset 3px, which stays visible against ink borders.
- Respect reduced-motion. Use proper `<nav>`, `<main>` and `<footer>` landmarks.
- Verified contrast: ink #1a1a1a on #f9f7ec = 16.2:1; muted #6b6b6b on #f9f7ec = 4.96:1; inverted button #f9f7ec on #1a1a1a = 16.2:1.
### Security
- Validate the contact form with zod on the client and on the server.
- Add a honeypot field and per-IP throttling on the function.
- No secrets in client-side code.
- External links use `rel="noopener noreferrer"`.
### Performance & SEO
The giant name is live text, not an image. Lazy-load project images with explicit width and height to avoid layout shift. Preload the mono display font. Add per-route meta and OG tags.
### 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:
- [ ] Desktop shows a sticky left name pane and an independently scrolling project column
- [ ] Mobile stacks panes with no horizontal overflow
- [ ] Cards switch grayscale to color on hover and keyboard focus
- [ ] Detail pages support arrow-key prev/next with wrap-around
- [ ] Contact form validates and shows loading, error and success states