2 cases built from this template
Same prompt, different [VARIABLES]. Click one to preview it above.About this template
A four-page website for an architecture practice: a home page with one large hero project and a three-project tease; a project index of twelve works filterable by typology (housing, cultural, education, retrofit) with a live count; project detail pages (query-driven, first project when opened without one) carrying large photographs, a facts block (location, area, span, status) and a floor plan drawn in SVG with room labels; a studio page with the practice's story, its approach in three points, people as initials cards, an awards strip and a contact block with a client-side inquiry line. The default content follows an invented seven-person practice, but the structure suits any architecture or interior practice: change the practice name, city and approach and every project, plan and award still reads true. The typographic system feels like a drawing set — numbered sections, hairline rules, uppercase labels — in pale concrete gray with near-black ink and one rust accent, Archivo wide-caps display over IBM Plex Sans. All twelve project photographs come from one consistent generated shoot: concrete, wood and light, no people. To adapt it, swap the variables and rewrite the copy in one content file; projects, plans and awards all read from it.
The template prompt
The live demo was built from exactly this text — nothing added. The other cases only change the values of the [VARIABLES].
# Architecture Firm Portfolio
Build this website exactly as described below. Replace the [VARIABLES] with your own values; keep everything else.
## Brief
A four-page website for [PRACTICE], an architecture practice based in [CITY], working through [APPROACH]. It must read like a good drawing set: a home with one hero project and a tease, a twelve-project index filterable by typology, project detail pages with large photos, a facts block and a drawn SVG floor plan, a studio page (story, approach, people, awards), and a client-side inquiry block. Pages: index.html, projects.html, project.html?p=<slug> (first project without a query), studio.html. Everything runs in the browser; nothing is submitted anywhere.
- Audience: Potential clients (developers, institutions, private commissioners) and peers. They look for rigor: clear facts per project, honest plans, a practice that can explain its approach in three sentences.
- Goal: Produce inquiry emails. Within ten seconds a visitor sees the quality bar; within two minutes they have filtered the typology they build and opened one project.
- Tone: Precise and quiet, like a set of specifications. Short declarative sentences, exact numbers (square meters, years), no poetry about light unless it is structural.
## Stack
- Framework: Vite 5 + React 18 + TypeScript
- Styling: Tailwind CSS 3.4
- Libraries: react (MIT), react-dom (MIT), motion (motion.dev, import from 'motion/react') (MIT), lucide-react (MIT), tailwindcss (MIT), postcss (MIT), autoprefixer (MIT), vite (MIT), @vitejs/plugin-react (MIT), typescript (Apache-2.0), @fontsource-variable/archivo (OFL-1.1), @fontsource/ibm-plex-sans (OFL-1.1)
- Build: `npm run build` → static files in `dist/`. No backend, no server code, no external APIs.
- Setup:
- Scaffold with npm create vite@latest using the react-ts template. Four real HTML pages at the project root: index.html (entry src/main-home.tsx), projects.html (src/main-projects.tsx), project.html (src/main-project.tsx) and studio.html (src/main-studio.tsx).
- vite.config.ts: base './', plugins [react()], build { outDir 'dist', sourcemap false, assetsInlineLimit 0, rollupOptions { input { index: resolve(__dirname, 'index.html'), projects: resolve(__dirname, 'projects.html'), project: resolve(__dirname, 'project.html'), studio: resolve(__dirname, 'studio.html') } } }. Do not copy src/ into dist/.
- Tailwind 3.4 through PostCSS, content ['./index.html', './projects.html', './project.html', './studio.html', './src/**/*.{ts,tsx}']. In tailwind.config.ts add every color under Design to theme.extend.colors with kebab-case keys (concrete, concrete-deep, paper, ink, ink-soft, rust, rust-deep, hairline, drawing) and fontFamily display ['Archivo Variable', 'Arial', 'sans-serif'], sans ['IBM Plex Sans', 'system-ui', 'sans-serif']. Set borderRadius DEFAULT to 0px — the practice draws squares — and add maxWidth { container: '1280px' }.
- In src/fonts.ts import '@fontsource-variable/archivo' and '@fontsource/ibm-plex-sans/300.css', '@fontsource/ibm-plex-sans/400.css', '@fontsource/ibm-plex-sans/500.css'; import src/fonts.ts and src/index.css from all four entry files.
- File layout: src/content.ts (every string, project, fact, plan label, person, award and image path, typed), src/lib/brand.ts (practiceSlug = [PRACTICE] lowercased with every run of non-alphanumeric characters replaced by '-', emailDomain = practiceSlug without hyphens + '.com'), src/lib/storage.ts (safe localStorage get/set wrapped in try/catch, keys prefixed with practiceSlug + ':'), src/lib/project.ts (reads the query 'project.html?p=<slug>', returns the matching project or the first — never a not-found), src/lib/filters.ts (applyTypology(projects, key)).
- State: src/store/inquiry.ts is a tiny external store (useSyncExternalStore) holding { name, email, typologyInterest, note, sent } persisted to localStorage key practiceSlug + ':inquiry'.
- Components in src/components/: Header.tsx, Reveal.tsx (Motion whileInView wrapper), SectionNumber.tsx (the numbered-label system), Footer.tsx; home: Hero.tsx, Tease.tsx (ProjectCard.tsx), ApproachStrip.tsx; projects: IndexMasthead.tsx, TypologyBar.tsx, ProjectRow.tsx, EmptyIndex.tsx; project: ProjectHero.tsx, FactsBlock.tsx, PlanDrawing.tsx (inline SVG per project), NextProject.tsx, InquiryCard.tsx (shared with studio); studio: Story.tsx, People.tsx (PersonCard.tsx initials), Awards.tsx, ContactBlock.tsx. src/pages/Home.tsx, Projects.tsx, Project.tsx, Studio.tsx compose them; every page renders Header and Footer.
- Before the first build, download every image listed under Assets into public/images/ with curl -L -o using the exact file names given. The build itself never fetches anything.
- public/favicon.svg as described under Assets. All four HTML files: lang en, <meta name='theme-color' content='#F2F1EE'>, <link rel='icon' href='./favicon.svg' type='image/svg+xml'>. Titles: index.html '<title>[PRACTICE] — Architecture, [CITY]</title>', projects.html '<title>Work — [PRACTICE]</title>', project.html '<title>Work — [PRACTICE]</title>' (the project page sets document.title to the project name on load), studio.html '<title>Studio — [PRACTICE]</title>'.
- Write ASSETS.md at the project root as described under Assets.
- dist/ holds the four HTML files, hashed JS/CSS, the woff2 fonts, favicon.svg and the six images. Keep it under 12 MB.
## Variables
- [PRACTICE] — Practice name (default: "Cardinal & Grid"). Invented practice name. Used in the wordmark, titles, footer, email (studio@ + practiceSlug without hyphens + .com) and localStorage keys. Never a real practice.
- [CITY] — City (default: "Montreal, Quebec"). Where the practice is based. Used in the title, story, facts blocks' locations (projects sit in and around it) and the footer. Real cities fine; project streets invented.
- [APPROACH] — Approach (default: "long-life buildings from short-list materials"). One lowercase phrase naming the practice's method. Drives the home approach strip, the studio story's second paragraph and one FAQ-style line. Concrete and repeatable, not poetic.
- [TYPOLOGIES] — Typologies (default: "Housing, cultural, education and retrofit"). The practice's four project typologies, comma-separated, title case. Drives the index filter and every project's typology tag. Keep exactly four.
- [CREDIT] — keep a small "Template by VibeFather" link to https://vibefather.ai/t/architecture-firm-portfolio in the footer (default: yes; delete this line to remove it)
The copy under Pages & Sections is written for the default values. If your values differ, rewrite every headline, paragraph, label and image for them — same length, tone and structure. Layout, colors, type and motion stay as described.
Keep all copy, image paths and links in one content file (for example `src/content.ts`), keyed by section, so the content can be swapped later without touching components.Pro template. The design, sections, motion and assets parts of this prompt are for Pro members. The live demo and DESIGN.md stay free.
Join Pro early access →DESIGN.md
The design system on its own — colors, type, spacing and motion. Apply this look to a project you already have.
---
name: "Architecture Firm Portfolio"
colors:
concrete: "#F2F1EE"
concrete_deep: "#E8E6E1"
paper: "#FBFAF8"
ink: "#1A1B1D"
ink_soft: "#5C5F63"
rust: "#B0491F"
rust_deep: "#8F3A17"
hairline: "#D6D4CE"
drawing: "#B9B7B0"
typography:
display_h1_h2_project_names_the_wordmark_typology_filter_labels_archivo_in_wide_uppercase_with_letterspacing: { family: "Archivo", weights: [600, 800] }
text_and_ui_body_facts_values_captions_buttons_plan_room_labels_numbers_tabular_numerals_for_areas: { family: "IBM Plex Sans", weights: [300, 400, 500] }
spacing: "8px base unit. Container max-width 1280px, centered, side padding 48px desktop, 32px tablet, 20px under 640px. 12-column grid, column gap 24px. Section vertical padding 120px desktop, 88px under 1024px, 72px under 640px — architecture breathes at the top of the scale. Section headers carry the SectionNumber system: '01' in Archivo 800 13px Rust + the label in Archivo 600 13px uppercase letterspaced + a 1px Hairline rule running to the container edge. Type scale: H1 clamp(44px, 6.4vw, 92px) Archivo 800 uppercase, line-height 1.0, letter-spacing 0.01em; H2 clamp(30px, 3.8vw, 52px) Archivo 800 uppercase; project names Archivo 800 26px uppercase; lead IBM Plex 300 19px / 1.7 Ink at 92%; body 16px / 1.75 (max-width 64ch); labels IBM Plex 500 11px uppercase letter-spacing 0.22em Ink Soft; facts values IBM Plex 400 15px tabular. Buttons: height 48px, Archivo 600 13px uppercase letter-spacing 0.08em. Primary: Ink fill, Concrete text. Secondary: 1px Ink border, Ink text. Inputs: height 48px, 1px Hairline border, Paper fill, focus Ink border. Focus ring everywhere: 2px Rust outline with 3px offset."
radius: "0px on everything — cards, buttons, inputs, images, the plan panel. The practice draws squares."
---
# Architecture Firm Portfolio — Design System
Apply this design system to an existing project. It describes the look and feel only; for the full site, use prompt.md.
## Colors
- **Concrete** `#F2F1EE` — Page background throughout.
- **Concrete Deep** `#E8E6E1` — Alternate section background (index rows, awards), hover fills.
- **Paper** `#FBFAF8` — Facts block, inquiry card, plan panel surfaces.
- **Ink** `#1A1B1D` — Headlines, body text, plan lines, icon color.
- **Ink Soft** `#5C5F63` — Secondary text, captions, labels, facts values.
- **Rust** `#B0491F` — The one accent: section numbers, filter active state, plan's dimension ticks, focus ring, inquiry send.
- **Rust Deep** `#8F3A17` — Hover and pressed states.
- **Hairline** `#D6D4CE` — 1px hairlines everywhere: rows, facts grid, plan frame, dividers.
- **Drawing** `#B9B7B0` — Plan hatch fills and furniture strokes (lighter than Ink).
## Typography
- **Display: H1, H2, project names, the wordmark, typology filter labels — Archivo in wide uppercase with letterspacing** — Archivo (OFL), weights 600/800. Self-host the font files.
- **Text and UI: body, facts values, captions, buttons, plan room labels, numbers (tabular numerals for areas)** — IBM Plex Sans (OFL), weights 300/400/500. Self-host the font files.
## Spacing & shape
- Spacing: 8px base unit. Container max-width 1280px, centered, side padding 48px desktop, 32px tablet, 20px under 640px. 12-column grid, column gap 24px. Section vertical padding 120px desktop, 88px under 1024px, 72px under 640px — architecture breathes at the top of the scale. Section headers carry the SectionNumber system: '01' in Archivo 800 13px Rust + the label in Archivo 600 13px uppercase letterspaced + a 1px Hairline rule running to the container edge. Type scale: H1 clamp(44px, 6.4vw, 92px) Archivo 800 uppercase, line-height 1.0, letter-spacing 0.01em; H2 clamp(30px, 3.8vw, 52px) Archivo 800 uppercase; project names Archivo 800 26px uppercase; lead IBM Plex 300 19px / 1.7 Ink at 92%; body 16px / 1.75 (max-width 64ch); labels IBM Plex 500 11px uppercase letter-spacing 0.22em Ink Soft; facts values IBM Plex 400 15px tabular. Buttons: height 48px, Archivo 600 13px uppercase letter-spacing 0.08em. Primary: Ink fill, Concrete text. Secondary: 1px Ink border, Ink text. Inputs: height 48px, 1px Hairline border, Paper fill, focus Ink border. Focus ring everywhere: 2px Rust outline with 3px offset.
- Radius: 0px on everything — cards, buttons, inputs, images, the plan panel. The practice draws squares.
## Motion
- Easing: --ease-out cubic-bezier(0.22, 0.61, 0.36, 1) for reveals and filter shuffles; --ease-io cubic-bezier(0.65, 0, 0.35, 1) for the plan draw and inquiry swap. Structural and unhurried.
- Reveal: blocks wrapped in <Reveal> start at opacity 0, translateY(14px) and settle over 700ms --ease-out when 12% visible (Motion whileInView, viewport once). Siblings stagger 70ms.
- Hero: the large project photo scales 1.04→1.0 over 2800ms; the practice name's letters rise with 40ms stagger; the section number '01' ticks in last.
- Index filtering: rows use Motion layout with AnimatePresence mode 'popLayout'; leaving rows fade 180ms, survivors glide 380ms --ease-io; the count crossfades; the empty index (impossible with defaults, still coded) shows 'No work in this typology yet — the folder is honest.' with Reset.
- Index rows: hover fills Concrete Deep and slides a 4px Rust rule in from the left; the photo desaturates 5%.
- Plan draw: when the plan enters view, the walls draw (stroke-dashoffset, 1100ms), then room labels fade in with 60ms stagger, then the Rust dimension ticks pop; hatching fills settle last. Under reduced motion, the plan renders complete.
- Facts block: the values count once on reveal (areas in tabular numerals, 600ms).
- Inquiry: invalid submit shakes 4px with inline labels; sending swaps to the sent state (280ms --ease-io) — a drawn Rust square stamp 'RECEIVED' rotating in 6deg to rest -3deg.
- Awards: rows reveal with a 40ms stagger; the year spans stay static.
- Links: .link-draw grows a 1px Ink underline over 250ms on hover and focus-visible.
- prefers-reduced-motion: reduce — no scales, staggers, draws or counts; everything renders at rest. Use CSS @media in index.css plus Motion's useReducedMotion in components.
## Imagery
Architectural photography, all six made for this template in one consistent shoot: overcast-even light, concrete and pale wood, muted greens, straight-on and one-point perspectives, studio photos are AI-generated fictional people at work (consistent overcast-window light); building photography stays people-free with no readable signage. Every photo uses object-fit cover with the object-position given under Assets, 0px corners (square, like the practice), no shadow; photos on Concrete get a 1px Hairline outline. Captions in IBM Plex 12px Ink Soft. Drawn in code: the per-project floor plans (walls, hatching, furniture strokes, room labels, dimension ticks — pure SVG geometry), the section-number system, the 'RECEIVED' stamp and the favicon. Icons: lucide-react only, stroke width 1.5, used sparingly (ArrowUpRight, Plus, Check, X, ArrowRight).
## Tone
Precise and quiet, like a set of specifications. Short declarative sentences, exact numbers (square meters, years), no poetry about light unless it is structural.
---
— Prompt by VibeFather · https://vibefather.ai/t/architecture-firm-portfolio · CC BY-NC 4.0 (non-commercial; commercial use needs a VibeFather Pro license) · Request removal: https://vibefather.ai/takedown