2 cases built from this template
Same prompt, different [VARIABLES]. Click one to preview it above.About this template
A two-page website for a small litigation and employment law firm, built to read like a serious publication rather than a brochure. The home page runs as a set of numbered sections: a masthead hero with an oversized high-contrast serif headline and a ledger of three firm figures, six practice areas with what each covers and its typical outcome, case results set as large figures on a dark ground, attorney profiles with monogram avatars, education and bar admissions, a four-step consultation intake, an insights list that opens inline, a fee table with an FAQ, and a contact block that shows whether the office is open right now. The second page goes deep on each practice area with a sticky index that tracks your position as you read. It suits small law practices, solo attorneys, and other professional services that sell judgement and track record: tax advisers, mediators, consultancies, architects. The look is warm paper, near-black ink and a single oxblood accent, with hairline rules, small mono labels and real photographs of offices, corridors, libraries and documents treated in a muted, slightly desaturated way and captioned like figures in a report. People's faces never appear; attorneys are shown as typographic monograms. Motion is quiet: headlines rise out of a mask, figures count up once, links draw their underline, and everything stops under reduced-motion settings. The intake form validates each step, shows a review screen and ends in a success state with a reference number, all in the browser. To adapt it, change the firm name, the practice focus, the city and the clients you serve; the prompt asks the builder to rewrite every headline, figure, profile and answer to match, and to keep all copy in one content file so later edits stay simple.
The template prompt
The live demo was built from exactly this text — nothing added. The other cases only change the values of the [VARIABLES].
# Editorial Law Firm Website
Build this website exactly as described below. Replace the [VARIABLES] with your own values; keep everything else.
## Brief
A two-page website for [BRAND], a small [PRACTICE_FOCUS] firm in [CITY] that represents [CLIENTS]. It reads like a serious editorial publication: oversized high-contrast serif headlines on warm paper, numbered sections separated by hairline rules, case results set as big figures, attorney profiles with monogram avatars, real documentary photographs of the office, the city, corridors, libraries and documents (never faces), and a client-side four-step consultation intake with a review step and a success state. Page 1 (index.html) is the firm's home; page 2 (practice-areas.html) explains each practice area in depth with a sticky index.
- Audience: People in [CITY] facing a dispute at work or in business ([CLIENTS]) who are comparing two or three firms late at night, often anxious, and want to see quickly what the firm handles, what it has won, who would represent them, what it costs and how to start.
- Goal: Turn a worried visitor into a consultation request: make the firm's scope, record and fees legible in under a minute, then make the four-step intake form feel safe and easy to finish. Secondary goal: send readers to the practice-areas page to confirm the firm handles their exact problem.
- Tone: Serious, plain-spoken and confident. Short declarative sentences, concrete numbers, no legal jargon without an explanation, no hype words, no exclamation marks. The firm sounds like a calm senior partner explaining things across a table.
## 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 (ISC), tailwindcss (MIT), postcss (MIT), autoprefixer (MIT), vite (MIT), @vitejs/plugin-react (MIT), typescript (Apache-2.0), @fontsource-variable/bodoni-moda (OFL-1.1), @fontsource-variable/public-sans (OFL-1.1), @fontsource/ibm-plex-mono (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. Two real HTML pages at the project root: index.html (entry src/main-home.tsx) and practice-areas.html (entry src/main-practice.tsx).
- vite.config.ts: base './', plugins [react()], build { outDir 'dist', sourcemap false, assetsInlineLimit 0, rollupOptions { input { index: resolve(__dirname, 'index.html'), practice: resolve(__dirname, 'practice-areas.html') } } }. Do not copy src/ into dist/.
- Tailwind 3.4 through PostCSS (tailwindcss + postcss + autoprefixer), content ['./index.html', './practice-areas.html', './src/**/*.{ts,tsx}']. In tailwind.config.ts add every color under Design to theme.extend.colors with kebab-case keys (paper, paper-deep, ink, night, graphite, muted, rule, oxblood, oxblood-deep, ivory) and fontFamily display ['Bodoni Moda Variable', 'Georgia', 'serif'], sans ['Public Sans Variable', 'system-ui', 'sans-serif'], mono ['IBM Plex Mono', 'ui-monospace', 'monospace']. Set borderRadius DEFAULT to 0.
- In src/fonts.ts import '@fontsource-variable/bodoni-moda/opsz.css', '@fontsource-variable/bodoni-moda/opsz-italic.css', '@fontsource-variable/public-sans', '@fontsource/ibm-plex-mono/400.css' and '@fontsource/ibm-plex-mono/500.css'; import src/fonts.ts and src/index.css from both entry files.
- File layout: src/content.ts (every string, figure, profile, article, FAQ answer, fee, hour, image path and alt text for both pages, typed), src/index.css (Tailwind layers, .eyebrow, .hairline, .link-draw, .photo, reduced-motion overrides), src/lib/useCountUp.ts, src/lib/useOpenNow.ts, src/lib/useActiveSection.ts.
- Components in src/components/: TopBar.tsx, Header.tsx, MobileMenu.tsx, SectionHead.tsx (number + label + hairline), Reveal.tsx (Motion whileInView wrapper), Figure.tsx (photo + caption), Hero.tsx, Principles.tsx, PracticeList.tsx, Results.tsx, Attorneys.tsx, Monogram.tsx, Intake/ (IntakeForm.tsx, StepMatter.tsx, StepDetails.tsx, StepContact.tsx, StepReview.tsx, Success.tsx, validate.ts), Insights.tsx, Fees.tsx, Faq.tsx, Contact.tsx, StreetMap.tsx (inline SVG), Footer.tsx, PracticeIndex.tsx, PracticeDetail.tsx, CtaBand.tsx. src/pages/Home.tsx and src/pages/PracticeAreas.tsx compose them.
- 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. Both HTML files: lang en, <meta name='theme-color' content='#F3EFE7'>, <link rel='icon' href='./favicon.svg' type='image/svg+xml'>. Titles: index.html '<title>[BRAND] — [PRACTICE_FOCUS] in [CITY]</title>' (capitalize the first letter of the focus), practice-areas.html '<title>Practice areas — [BRAND]</title>'.
- Write ASSETS.md at the project root as described under Assets.
- dist/ holds index.html, practice-areas.html, hashed JS/CSS, the woff2 fonts, favicon.svg and the ten images. Keep it under 10 MB.
## Variables
- [BRAND] — Firm name (default: "Wrenfield & Osei"). Invented firm name. Used in the wordmark ('Wrenfield & Osei' with a small 'LLP' after it), titles, footer, monogram reference prefix (WO-) and the intake success text. The two founding partners' surnames come from it.
- [PRACTICE_FOCUS] — Practice focus (default: "litigation and employment law"). Lowercase phrase. Drives the hero, the six practice areas, case results, attorney focus lines, intake matter types, insights and FAQ answers. Rewrite all of them when this changes.
- [CITY] — City (default: "Portland, Oregon"). Where the office is. Used in the hero label, contact block, footer, bar admissions (state and federal district) and the FAQ about cases outside the city. Street names stay invented.
- [CLIENTS] — Who the firm represents (default: "employees, executives and growing companies"). Lowercase list of client types. Used in the hero paragraph, the intake 'Who are you?' choices and the brief tone of the practice areas.
- [CREDIT] — keep a small "Template by VibeFather" link to https://vibefather.ai/t/editorial-law-firm-website 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.
## Design
### Colors
- Paper `#F3EFE7` — Page background on both pages.
- Paper Deep `#E8E2D6` — Alternate section background (Principles, Intake, practice-page masthead), row hover, monogram tiles, input fill on focus.
- Ink `#17150F` — Headlines, body text on paper, the top bar, the footer background, primary outline buttons.
- Night `#1E1C18` — Background of the Case results section.
- Graphite `#4A463E` — Secondary body text and paragraph text in long-form sections.
- Muted `#857E71` — Eyebrow labels, captions, section numbers, placeholder text, read times.
- Rule `#D3CBBC` — All 1px hairlines, card borders, input borders, table lines on paper.
- Oxblood `#7A1E1E` — The only accent: primary buttons, active index item, italic highlight words in headings, the small bars above result figures, progress bar, error text, focus rings.
- Oxblood Deep `#5C1515` — Hover and pressed state of oxblood buttons.
- Ivory `#EEE8DC` — Text on Night and Ink backgrounds; hairlines on dark use Ivory at 14% opacity.
### Typography
- Display: H1, H2, wordmark, practice names, result figures, article titles, monogram initials (family 'Bodoni Moda Variable', optical size axis auto). Italic 400 for the highlighted phrase in each heading.: Bodoni Moda (OFL), weights 400/500/600
- Text: body, nav, buttons, form fields, FAQ answers, captions longer than one line (family 'Public Sans Variable').: Public Sans (OFL), weights 400/500/600
- Mono: eyebrows, section numbers (§ 01), figure captions ('Fig. 1 —'), step labels, read times, reference numbers, office-hours table (family 'IBM Plex Mono').: IBM Plex Mono (OFL), weights 400/500
### Layout & motion
- Spacing: 8px base unit. Container max-width 1360px, centered, side padding 40px desktop, 24px tablet, 20px under 640px. 12-column grid, column gap 24px. Section vertical padding 128px desktop, 88px under 768px. Every home section starts with SectionHead: a full-width 1px Rule hairline, then 20px below it a row with the mono section number left ('§ 01', IBM Plex Mono 500 12px, Oxblood) and the mono label next to it ('PRACTICE AREAS', 12px uppercase, letter-spacing 0.14em, Muted), and on the far right a mono count where useful ('06 AREAS'). Type scale: H1 clamp(56px, 8.6vw, 136px) Bodoni 500, line-height 0.94, letter-spacing -0.025em; H2 clamp(40px, 5.2vw, 84px) Bodoni 500, line-height 0.98, letter-spacing -0.02em; H3 32px Bodoni 500 line-height 1.1; body Public Sans 400 17px / 1.65 (16px under 768px), long-form paragraphs max-width 64ch; lead paragraphs 21px / 1.5 Graphite; eyebrow IBM Plex Mono 400 12px uppercase letter-spacing 0.14em Muted. Buttons: height 52px, padding 0 28px, Public Sans 500 15px, letter-spacing 0.01em.
- Radius: Square corners everywhere (0) — cards, photos, buttons, inputs, radio tiles, accordion rows. The only rounded shapes are the 8px 'open now' status dot, the 999px status pill in Contact and the success check circle.
- Motion: Easing: --ease-out cubic-bezier(0.2, 0.7, 0.2, 1) for reveals; --ease-io cubic-bezier(0.65, 0, 0.35, 1) for accordions and form steps.
- Motion: Reveal: blocks wrapped in <Reveal> start at opacity 0, translateY(16px) and animate to rest over 700ms --ease-out when 15% visible (Motion whileInView, viewport once). Siblings in the same list stagger by 70ms (pass index prop).
- Motion: Headline mask: H1 and every H2 are split into lines in content.ts (an array of line strings, the italic phrase marked with *asterisks*). Each line sits in an overflow-hidden block; the inner span rises from translateY(105%) to 0 over 900ms --ease-out, 90ms stagger, when the heading enters the viewport (H1 on load after 120ms).
- Motion: Count-up: numeric parts of result figures and hero ledger figures count from 0 to their value over 1400ms easeOutCubic when 40% visible, once (useCountUp with requestAnimationFrame). Prefix and suffix ('$', 'M', '%', ' months') stay static; decimals keep their precision (4.2, 48.6). Non-numeric figures ('Dismissed') only fade in.
- Motion: Hero photo: on load it scales from 1.06 to 1 over 1600ms --ease-out; while scrolling, the image inside its frame translates from 0 to -6% of its height (Motion useScroll + useTransform on the frame's scroll progress). The frame itself does not move.
- Motion: Link underline: .link-draw uses background-image linear-gradient(currentColor, currentColor), background-size 0% 1px at bottom left, no-repeat; on hover and focus-visible it grows to 100% 1px over 300ms --ease-out.
- Motion: Rows and cards: practice rows and insight rows fade their background to Paper Deep over 200ms on hover, the arrow icon moves 6px right, the number turns Oxblood. Attorney monogram tiles swap to Ink background with Ivory initials over 300ms.
- Motion: Accordions (FAQ, insights): height animates with Motion (AnimatePresence, height 0 → auto, opacity 0 → 1) over 320ms --ease-io; the Plus icon rotates 45° into an X.
- Motion: Intake steps: the outgoing step fades and moves 24px left, the incoming step enters from 24px right, 260ms --ease-io (AnimatePresence mode 'wait'); going Back reverses the direction. The progress bar width animates over 400ms.
- Motion: Header: transparent with no border at the top of the page; after 24px of scroll it gets Paper at 92% opacity, backdrop-filter blur(8px) and a 1px Rule bottom border, 200ms transition.
- Motion: prefers-reduced-motion: reduce — disable the headline mask, reveals, parallax, hero scale, count-up (show final values), step slide (crossfade 0ms) and smooth scrolling. Hover color changes stay.
- Imagery: Real documentary photography only: the firm's own conference room, reception, consultation room, desk with case files, the view from its window and its street entrance (six photos made for this template), plus four public-domain / CC0 photos of a courthouse corridor, a law library, legal stacks and a nineteenth-century handwritten deed. No people or faces anywhere. Every photo gets the .photo treatment: filter saturate(0.82) contrast(1.04) sepia(0.06), object-fit cover, a 1px Rule outline, no shadow, square corners, and a caption below in IBM Plex Mono 12px Muted that starts with 'Fig. n —' (numbered in page order). Attorneys are typographic monograms, never photos. Everything else is drawn in code: the favicon, the SVG street map in Contact, dividers, the success check. Icons from lucide-react only, stroke 1.5.
## Pages & Sections
### Home (`index.html`)
1. **Content file and copy rules** — All copy below is written for the default values ([BRAND] = Wrenfield & Osei, [PRACTICE_FOCUS] = litigation and employment law, [CITY] = Portland, Oregon, [CLIENTS] = employees, executives and growing companies). Put every string, number and list in src/content.ts and render from it. If any variable value differs, rewrite every headline, figure, practice area, result, attorney profile, intake option, article, fee and FAQ answer so it is specific and believable for the new firm, keeping the same structure, counts and lengths. All people, cases, figures, schools and streets are invented. Office: 1120 Calder Row, Suite 900, Portland, OR 97204. Phone (503) 555-0148. Email [email protected]. Hours: Mon–Thu 8:30–18:00, Fri 8:30–16:00, Sat by appointment, Sun closed (time zone America/Los_Angeles).
Layout: No visual output. content.ts exports typed objects: firm, nav, hero, principles, practiceAreas (shared with page 2), results, attorneys, intake, insights, fees, faq, contact, footer, images.
2. **Top bar** — One line in IBM Plex Mono 12px Ivory on Ink: left 'Free 30-minute consultation · Reply within one business day'; right 'Call (503) 555-0148' as a tel: link with a Lucide Phone icon (14px) and, separated by a 1px Ivory/20% vertical rule, the live status from useOpenNow: an 8px dot (Oxblood-tinted #C4544A when closed, #7FAF8A when open) and 'Open now · until 18:00' or 'Closed · opens Mon 8:30'.
Layout: Height 36px, full width, container inside, flex space-between. Under 768px only the right part shows, centered.
Motion: None.
3. **Header** — Wordmark 'Wrenfield & Osei' in Bodoni Moda 500 24px Ink with the ampersand in italic Oxblood, followed by 'LLP' in IBM Plex Mono 11px Muted with 6px left margin; links to ./index.html. Nav (Public Sans 500 15px Ink): 'Practice areas' (./practice-areas.html), 'Results' (#results), 'Attorneys' (#attorneys), 'Insights' (#insights), 'Fees' (#fees), 'Contact' (#contact), each with .link-draw. Right: primary button 'Free consultation' (#consult) — Oxblood background, Ivory text, Lucide ArrowRight 16px. On practice-areas.html hash links become ./index.html#results etc. and 'Practice areas' gets a permanent 1px Oxblood underline.
Layout: Sticky top 0, z-50, height 80px, container flex items-center justify-between, nav gap 32px. Under 1024px the nav collapses into a Menu icon button (44×44px) that opens MobileMenu: a full-screen Paper sheet sliding down from the top with the six links in Bodoni 500 40px stacked with 1px Rule separators, the consultation button full width at the bottom, phone and hours in mono below; X icon to close; Escape closes; body scroll locked while open.
Motion: Background and border transition after 24px of scroll as described under Design motion. Mobile sheet slides from translateY(-100%) over 360ms --ease-io.
4. **Hero (#top)** — Label row: left eyebrow 'Litigation & employment law — Portland, Oregon'; right eyebrow 'Est. 2009 · 11 attorneys · 1 office'. H1 in three lines: 'Serious counsel' / 'for the fights' / '*that matter at work.*' (the italic line in Bodoni 400 italic Oxblood). Paragraph (lead, Graphite): 'We represent employees, executives and growing companies in wrongful termination, discrimination, wage and contract disputes — from the first demand letter to a jury verdict. Every matter is led by a partner who has tried cases in Oregon and federal court.' Buttons: primary 'Book a free consultation' (#consult) and a text link 'See our case results' with Lucide ArrowDown 16px (#results, .link-draw). Ledger of three figures, each a Bodoni 500 56px number over a Public Sans 14px Graphite line, separated by 1px Rule hairlines: '$48.6M' / 'recovered for clients since 2009'; '312' / 'matters resolved'; '87%' / 'settled before trial, on terms our clients approved'. Photo: conference-room.webp with caption 'Fig. 1 — The conference room, ninth floor, 1120 Calder Row.'
Layout: Padding-top 72px. Label row flex justify-between with a 1px Rule hairline 16px below it. H1 spans the full 12 columns, margin-top 40px. Below it a 12-column row with margin-top 56px: paragraph + buttons in columns 1–6 (buttons row gap 24px, margin-top 32px); the ledger in columns 8–12 as a vertical list, each item padding 18px 0 with a top hairline. Photo frame below at margin-top 80px: full container width, aspect 21/9 on desktop, 4/5 under 768px, overflow hidden; caption 12px below, left aligned. Under 768px the ledger becomes a 3-column row with 32px numbers.
Motion: H1 line mask on load; label row, paragraph, buttons and ledger reveal with 70ms stagger after the H1; ledger figures count up; photo scale-in and parallax as in Design motion.
5. **Principles** — Four numbered commitments, each a mono number, a Bodoni 500 24px title and a 15px Graphite sentence: '01' 'A partner on every matter' 'The partner you meet in the consultation is the one who signs the pleadings and stands up in court.'; '02' 'Trial-ready from day one' 'We prepare every case as if it will reach a jury. That is why most of them don't have to.'; '03' 'Fees you can predict' 'Contingency, flat or hourly — set out in writing before we start, with no surprise invoices.'; '04' 'Answers within one business day' 'Calls and emails are returned by the end of the next business day, by someone who knows your file.'
Layout: Paper Deep background, padding 72px 0. Container grid 4 columns, each column separated by a 1px Rule vertical line (border-left on columns 2–4), column padding 0 32px (first column padding-left 0). Under 1024px 2×2 with horizontal hairlines; under 640px one column.
Motion: Columns reveal with 70ms stagger.
6. **Practice areas (#practice)** — SectionHead '§ 01' 'PRACTICE AREAS' right '06 AREAS'. H2 '*Six areas.*' / 'Every one of them' / 'litigated.' Intro (Graphite): 'We keep the practice narrow on purpose. Each area below is one we have taken to trial, and each has a partner who leads it.' Link 'Read every area in detail' with Lucide ArrowUpRight → ./practice-areas.html. Six rows (shared with page 2, same order and slugs): 01 'Wrongful termination' (slug wrongful-termination) — covers 'Firings that break a contract, punish a complaint, or follow medical or family leave.' — typical outcome 'Severance of 6–18 months' pay, or reinstatement.'; 02 'Discrimination & harassment' (discrimination) — 'Race, sex, age, disability, pregnancy and religion; hostile work environments.' — 'Back pay, damages, a neutral reference and policy changes.'; 03 'Wage & hour' (wage-and-hour) — 'Unpaid overtime, misclassification as exempt or contractor, final-pay penalties, class claims.' — 'Unpaid wages plus statutory penalties, often doubled.'; 04 'Executive & contract disputes' (executive) — 'Employment agreements, bonuses, equity and options, non-competes and severance terms.' — 'Equity paid out, bonus enforced, or a non-compete narrowed.'; 05 'Business litigation' (business) — 'Partner and shareholder disputes, breach of contract, trade secrets and unfair competition.' — 'A fair buy-out or a judgment after trial.'; 06 'Employer counsel' (employer) — 'Investigations, handbooks, agency charges and defence of claims for companies under 200 people.' — 'Charges dismissed and policies that hold up.'
Layout: 12-column grid. Columns 1–4: H2, intro (margin-top 24px) and link (margin-top 32px), position sticky top 120px on desktop. Columns 6–12: the list. Each row is an <a href='./practice-areas.html#<slug>'> with a 1px Rule top border (last row also a bottom border), padding 32px 16px, grid columns [56px | 1fr | 32px]: mono number (Muted) top-aligned; middle cell with the name in Bodoni 500 36px, the covers line in 16px Graphite (margin-top 8px), then a row with the eyebrow 'TYPICAL OUTCOME' and the outcome in Public Sans 500 15px Ink (margin-top 16px); the right cell a Lucide ArrowRight 22px. Under 1024px the left column stops being sticky and stacks above the list; names 28px.
Motion: Rows reveal with 70ms stagger; hover as in Design motion.
7. **Case results (#results)** — SectionHead on dark (hairline Ivory/14%, number Oxblood-light #C4544A, label Ivory/60%): '§ 02' 'CASE RESULTS' right 'SELECTED'. H2 in Ivory: 'Figures,' / '*not adjectives.*' (italic in #C4544A). Six results, each with a figure, a mono type label and one sentence: '$4.2M' 'JURY VERDICT' 'Age discrimination claim for a 58-year-old operations director dismissed after 22 years with a regional freight company.'; '$1.85M' 'CLASS SETTLEMENT' 'Unpaid overtime for 340 warehouse workers who had been classified as exempt managers.'; '$960K' 'PRE-SUIT SETTLEMENT' 'Retaliation against a charge nurse who reported unsafe staffing ratios to the state.'; '$2.3M' 'EQUITY RECOVERED' 'Vested options withheld from a departing vice president of engineering at a software company.'; '18 months' 'SEVERANCE' 'Pay and benefits for an executive terminated during medical leave, agreed 41 days after our first letter.'; 'Dismissed' 'DEFENCE' 'A discrimination charge against a 60-person employer, dismissed by the agency with no finding.' Photo: corridor.jpg with caption (Ivory/55%) 'Fig. 2 — A courthouse corridor before the morning calendar.' Disclaimer under the grid in 13px Ivory/55%: 'Prior results do not guarantee a similar outcome. Each matter turns on its own facts. Figures are gross recoveries before fees and costs.'
Layout: Night background, Ivory text. 12-column grid. Columns 1–5: H2, then the photo (aspect 4/5, margin-top 48px) and caption. Columns 7–12: a 2-column grid of the six results with 1px Ivory/14% hairlines between cells (border-top on every cell, border-left on the right column), cell padding 36px 28px. In each cell: a 32px × 2px Oxblood-light bar, then the figure in Bodoni 500 64px Ivory (margin-top 20px, tabular), the mono label (12px, Ivory/60%, margin-top 12px), the sentence in 15px Ivory/80% (margin-top 12px). Disclaimer spans columns 7–12, margin-top 32px. Under 1024px everything stacks: H2, results grid (2 columns), photo at aspect 16/9 last; under 640px results are one column and figures 52px.
Motion: Cells reveal with 70ms stagger, figures count up.
8. **Attorneys (#attorneys)** — SectionHead '§ 03' 'ATTORNEYS' right '04 OF 11'. H2 'The people who' / '*stand up in court*' / 'for you.' Four profiles, each: monogram, name, role, focus line, 'EDUCATION' list, 'BAR ADMISSIONS' list. (1) 'CW' Clara Wrenfield — Founding Partner — 'Leads wrongful termination and discrimination trials; 27 jury trials to verdict.' — Education: 'J.D., Northbridge University School of Law, cum laude', 'B.A. History, Halden College' — Bar: 'Oregon', 'Washington', 'U.S. District Court, District of Oregon', 'Ninth Circuit Court of Appeals'. (2) 'DO' Daniel Osei — Founding Partner — 'Executive, equity and contract disputes; former in-house counsel at a manufacturer.' — 'J.D., Larchmont Law School', 'B.S. Economics, Corwen State University' — 'Oregon', 'California', 'U.S. District Court, District of Oregon'. (3) 'MC' Mira Castellanos — Partner — 'Wage and hour class actions; has recovered over $11M in unpaid wages.' — 'J.D., Northbridge University School of Law', 'B.A. Labor Studies, Pinecrest University' — 'Oregon', 'Washington', 'U.S. District Court, Western District of Washington'. (4) 'TL' Theo Lindqvist — Senior Associate — 'Business litigation and employer counsel; leads workplace investigations.' — 'J.D., Larchmont Law School, Order of the Barristers', 'B.A. Philosophy, Halden College' — 'Oregon', 'U.S. District Court, District of Oregon'. Under the grid a 14px Muted line (not a link): 'Seven more attorneys and three paralegals work alongside them on every file.'
Layout: H2 in columns 1–8. Grid of 4 equal cards below (margin-top 64px), gap 24px; 2 columns under 1024px, 1 under 640px. Card: 1px Rule border, no background. Monogram tile: full card width, aspect 1/1, Paper Deep, initials centered in Bodoni 400 italic 120px Ink, a 1px Rule inset frame 16px from the edges, and the mono index '01'–'04' at top-left 24px. Body padding 24px: name Bodoni 500 28px, role eyebrow below (margin-top 6px), focus 15px Graphite (margin-top 16px), then two definition groups with 1px Rule top borders and padding-top 14px, each an eyebrow label then a list of 14px Ink lines with 4px gap.
Motion: Cards reveal with 70ms stagger; monogram hover swap as in Design motion.
9. **Consultation intake (#consult)** — SectionHead '§ 04' 'FREE CONSULTATION' right '4 STEPS · ABOUT 3 MINUTES'. Left: H2 'Tell us what happened.' / '*A partner reads every request.*'; lead 'The first 30 minutes are free, by phone, video or at our office. Everything you send is confidential.'; three checklist lines with Lucide Check 16px Oxblood: 'Reply within one business day', 'No obligation to hire us', 'Interpreters available on request'; photo consult-room.webp with caption 'Fig. 3 — Consultation room two, where most first meetings happen.' Right: the form card. Progress header: four step labels in IBM Plex Mono 12px — '01 Matter', '02 Details', '03 Contact', '04 Review' — current one Ink, done ones Ink with a Check icon, upcoming Muted; under them a 2px Rule track with an Oxblood bar at 25/50/75/100%. Step 1 'What is this about?': radio tiles for the six practice area names plus 'Something else' (seven tiles); then 'Who are you?' segmented control 'An employee' / 'An executive' / 'An employer' / 'Other' (both required; error 'Choose the closest match.'). Step 2 'The details': select 'When did it happen?' (Within the last month / 1–6 months ago / 6–12 months ago / More than a year ago) required; text 'Employer or other party' required ('Who is this against?'); textarea 'What happened?' required, minimum 40 characters, live counter '0 / 40 minimum' that turns Ink at 40, placeholder 'In a few sentences: what happened, when, and what you would like to happen next.'; checkbox 'I have been told about a deadline (a hearing, a signature date, a filing date)'. If the date answer is 'More than a year ago', show an inline note in a 1px Oxblood-bordered box: 'Some claims have short deadlines. We will tell you on the call whether yours is still open.' Step 3 'How to reach you': Full name (required), Email (required, must match /^[^\s@]+@[^\s@]+\.[^\s@]+$/, error 'Enter an email like [email protected].'), Phone (optional), 'Best way to reach you' radios Email / Phone / Either (default Either), required checkbox 'I understand that sending this form does not create an attorney–client relationship.' Step 4 'Review': a definition list of every answer grouped by step, each group with an 'Edit' text button that jumps to that step; the textarea answer shown in full. Buttons: 'Back' (outline Ink, Lucide ChevronLeft, hidden on step 1) and 'Continue' (Oxblood) on steps 1–3; 'Send request' on step 4. Sending: button shows 'Sending…' and is disabled for 900ms, then the Success panel replaces the form: a 56px Oxblood circle with an Ivory Check icon, H3 'Thank you, {first name}. Your request is in.', text 'Your reference is WO-{5 random digits}. A partner will reply to {email} within one business day. If a deadline falls in the next 7 days, call (503) 555-0148 now.', and a text button 'Start a new request' that resets all state to step 1.
Layout: Paper Deep background. 12-column grid: left columns 1–5 (H2, lead margin-top 24px, checklist margin-top 32px with 12px gaps, photo aspect 4/3 margin-top 48px); right columns 7–12 the card: Paper background, 1px Rule border, padding 40px (24px under 640px), min-height 620px on desktop so steps don't jump. Fields: label Public Sans 500 14px Ink above, input height 52px, 1px Rule border, Paper background, padding 0 16px, 16px text; focus: border Ink, background Paper Deep, 2px Oxblood outline offset 2px; error: border Oxblood and a 13px Oxblood message 6px below with role alert. Radio tiles: 2-column grid gap 12px, each 1px Rule border, padding 16px, Public Sans 500 15px, selected = Ink border 1px plus 3px Oxblood left bar and Paper Deep background. Segmented control: one row of 4 equal cells sharing borders, selected cell Ink background Ivory text. Button row at the bottom, flex justify-between, margin-top 40px. On Continue, validate the current step; if invalid, show errors and focus the first invalid field; otherwise advance and move focus to the step heading. Real <form> with onSubmit preventDefault; nothing is sent anywhere. Under 1024px the left column stacks above the card and the photo is hidden.
Motion: Step slide transitions, progress bar width animation and success panel fade-up (16px, 500ms) as in Design motion.
10. **Insights (#insights)** — SectionHead '§ 05' 'INSIGHTS' right '05 NOTES'. H2 'Notes from' / '*the trial table.*' Photo law-library.jpg with caption 'Fig. 4 — The reading room we use for research afternoons.' Five articles, each a mono category, a Bodoni title, a one-line dek, a read time and a two-paragraph excerpt that opens inline: (1) 'EMPLOYEES' 'Fired after asking for leave? Write these five things down first.' — 'Notes made in the first week carry more weight than memories a year later.' — '6 min read' — excerpt: 'Write down the date you asked for leave, who you told, what they said, and the date and words of the termination. Save every email and text as a file, not just in the app.' / 'Do not sign anything that day. A severance agreement usually gives you at least 21 days to consider it, and that time is worth using.'; (2) 'WAGE & HOUR' 'Salaried is not the same as exempt.' — 'Your job duties, not your pay schedule, decide whether you are owed overtime.' — '8 min read' — excerpt about the duties test and keeping a simple hours log; (3) 'EXECUTIVES' 'Before you sign the severance agreement, read clause 7.' — 'The release, the non-disparagement clause and what happens to unvested equity.' — '5 min read'; (4) 'LITIGATION' 'What actually happens at a deposition, hour by hour.' — 'Who is in the room, how long it lasts, and the three answers we will rehearse with you.' — '9 min read'; (5) 'EMPLOYERS' 'Running a workplace investigation that holds up later.' — 'Who should interview, what to write down, and when to bring in outside counsel.' — '7 min read'. Write two concrete excerpt paragraphs for articles 2–5 in the same plain style.
Layout: 12-column grid. Columns 1–4: H2 then the photo (aspect 3/4, margin-top 40px) and caption, sticky top 120px on desktop. Columns 6–12: list of five rows as <button aria-expanded> elements, 1px Rule top border each (bottom border on the last), padding 28px 0, grid [140px | 1fr | 96px]: mono category (Muted) top-aligned; title in Bodoni 500 30px and dek in 15px Graphite below (margin-top 8px); right cell read time in mono 12px Muted and a Lucide Plus 20px below it, right aligned. The open row shows the excerpt paragraphs in 16px Graphite, max-width 60ch, padding 0 0 28px 140px. One row open at a time; first row closed by default. Under 768px the grid becomes one column (category above title, read time and icon in a row under the dek, excerpt without left padding) and the photo is hidden.
Motion: Rows reveal with stagger; accordion height animation and Plus rotation as in Design motion.
11. **Fees and FAQ (#fees)** — SectionHead '§ 06' 'FEES' right 'IN WRITING, BEFORE WE START'. H2 'What it costs,' / '*in plain numbers.*' Fee table with three columns: 'Contingency' — '33%' (Bodoni 500 56px) — 'of the recovery, 40% if the case goes to trial. Nothing if we recover nothing.' — 'Most employee cases'; 'Hourly' — '$385–575' — 'per hour for partners, $260 for associates, billed in 6-minute increments with monthly statements.' — 'Employers and business disputes'; 'Flat fee' — '$1,250' — 'for a severance agreement review with a written memo in five business days. Agreement drafting from $2,400.' — 'Executives and fixed-scope work'. FAQ (six items): 'Is the first consultation really free?' — 'Yes. Thirty minutes by phone, video or at our office, with a partner. If we can't help, we will tell you who can.'; 'How does a contingency fee work?' — 'Our fee is a percentage of what we recover for you, agreed in writing. If there is no recovery, you owe no fee.'; 'Who pays costs like filing fees and depositions?' — 'On contingency matters we advance them and are repaid from the recovery only. Typical costs run $3,000–$15,000 for a case that reaches trial.'; 'Will I owe anything if we lose?' — 'Not our fee, and not the costs we advanced. In rare cases a court can award the other side its costs; we explain that risk before you sign.'; 'Do you take cases outside Portland?' — 'Yes, anywhere in Oregon and southwest Washington. Hearings and depositions can often happen by video.'; 'How long does a typical case take?' — 'Pre-suit negotiations take two to four months. A filed lawsuit usually takes 14 to 24 months, and most resolve at mediation before trial.'
Layout: H2 in columns 1–7. Fee table margin-top 56px: 3 equal columns sharing 1px Rule borders (outer border plus vertical dividers), each cell padding 32px: eyebrow name, figure (margin-top 20px, Oxblood for the figure only), description 15px Graphite (margin-top 12px), then a 1px Rule hairline and the 'best for' line in mono 12px Muted (margin-top 24px, padding-top 14px). Under 768px the columns stack. FAQ margin-top 96px in a 12-column grid: label column 1–4 with eyebrow 'QUESTIONS ABOUT FEES', a 15px Graphite line 'Still unsure? Ask on the call — there is no charge for it.' and below it (margin-top 32px) the photo reception.webp at aspect 4/5 with caption 'Fig. 5 — Reception, ninth floor. Coffee is on us.' (photo hidden under 1024px); accordion in columns 5–12, rows with 1px Rule borders, question as a <button aria-expanded> in Bodoni 500 24px with a Lucide Plus 20px on the right, padding 24px 0; answer 16px Graphite max-width 62ch, padding-bottom 24px. One open at a time, first open by default.
Motion: Fee cells reveal with stagger; figures do not count up. Accordion as in Design motion.
12. **Contact (#contact)** — SectionHead '§ 07' 'CONTACT' right 'MON–FRI'. H2 'Come and see us' / '*on Calder Row.*' Photo entrance.webp with caption 'Fig. 6 — The Calder Row entrance. Suite 900 is on the ninth floor.' Details with Lucide icons (MapPin, Phone, Mail, Clock at 18px Oxblood): address '1120 Calder Row, Suite 900' / 'Portland, OR 97204'; phone '(503) 555-0148' (tel: link); email '[email protected]' (mailto: link); 'Two blocks from the Calder Row streetcar stop. Validated parking in the Larch Street garage.' Status pill from useOpenNow: 'Open now · until 18:00' or 'Closed · opens Mon 8:30', 999px radius, 1px Rule border, 8px dot. Office hours table in IBM Plex Mono 14px: Monday–Thursday 8:30–18:00; Friday 8:30–16:00; Saturday By appointment; Sunday Closed; the current day's row in Ink with a 2px Oxblood left bar, others Graphite. StreetMap: an inline SVG (viewBox 0 0 600 360) of invented streets — Paper Deep fill, a grid of 1px Rule streets at slight angles, three labeled streets in IBM Plex Mono 10px Muted ('CALDER ROW', 'LARCH ST', '11TH AVE'), a 2px Ink line for the streetcar with two small circles for stops, a river band in #DCD5C6 along the bottom-left, and an Oxblood 14px square marker with a 1px Ink ring and the label 'W&O · SUITE 900'.
Layout: 12-column grid. Columns 1–6: the photo (aspect 4/3) and caption, then the StreetMap below it (margin-top 24px, full column width, 1px Rule border). Columns 8–12: H2, details list (margin-top 40px, each row an icon and 16px text with 16px gap, rows separated by 20px), status pill (margin-top 28px), hours table (margin-top 28px, rows 44px with 1px Rule bottom borders, day left, hours right) and the button 'Book a free consultation' (#consult, margin-top 36px). Under 1024px stack: H2, details, pill, hours, button, photo, map.
Motion: Reveal only. The map marker pulses its ring once on reveal (scale 1 → 1.8, opacity 0.6 → 0, 900ms), skipped under reduced motion.
13. **Footer** — Ink background, Ivory text. Top: giant wordmark 'Wrenfield & Osei' in Bodoni Moda 500 clamp(56px, 11vw, 184px), line-height 0.9, letter-spacing -0.03em, ampersand italic in #C4544A. Four columns below: 'Practice areas' (the six names, linking to ./practice-areas.html#<slug>); 'Firm' (Results, Attorneys, Insights, Fees, Contact — ./index.html#<id>); 'Office' ('1120 Calder Row, Suite 900', 'Portland, OR 97204', '(503) 555-0148', '[email protected]'); 'Hours' (the four hour lines). Column titles mono 12px uppercase Ivory/55%, items Public Sans 15px Ivory/85% with .link-draw. Disclaimer paragraph (13px Ivory/55%, max-width 80ch): 'Attorney advertising. The information on this site is general information, not legal advice, and reading it does not create an attorney–client relationship. Prior results do not guarantee a similar outcome. Wrenfield & Osei LLP is responsible for the content of this site.' Bottom row: '© Wrenfield & Osei LLP' left; right, if [CREDIT] is kept, the small credit link in mono 11px Ivory/55%.
Layout: Padding 96px 0 40px. Wordmark block with a 1px Ivory/14% hairline below it (margin 0 0 56px, padding-bottom 32px). 4-column grid gap 32px (2 columns under 1024px, 1 under 640px). Disclaimer margin-top 64px. Bottom row margin-top 32px, padding-top 20px, 1px Ivory/14% top border, flex justify-between, stacked under 640px.
Motion: Wordmark lines rise with the headline mask when it enters.
### Practice areas (`practice-areas.html`)
1. **Top bar and header** — The same Top bar and Header as index.html, with hash links pointing to ./index.html#<id>, 'Practice areas' marked current (aria-current='page', permanent 1px Oxblood underline) and the consultation button linking to ./index.html#consult.
Layout: Identical to page 1.
Motion: Identical to page 1.
2. **Masthead** — Breadcrumb in IBM Plex Mono 12px: 'Home' (./index.html, .link-draw) / 'Practice areas' (Muted). H1 'Practice' / '*areas.*' Lead (Graphite): 'Six areas of litigation and employment law, each led by a partner who has taken it to trial. Find yours below, see what it covers, what usually happens, and how we would run it.' Small ledger in mono 12px below the lead: '06 AREAS · 4 PARTNERS · 27 JURY TRIALS TO VERDICT'. Photo window-city.webp (aspect 3/4) with caption 'Fig. 1 — The view down Calder Row from the eighth floor.' Then a full-width band with deed.jpg and caption 'Fig. 2 — An executed indenture, nineteenth century. We still read every clause.'
Layout: Paper Deep background, padding 64px 0 96px. 12-column grid: columns 1–7 breadcrumb, H1 (margin-top 40px), lead (margin-top 32px, max-width 52ch), ledger (margin-top 28px); columns 9–12 the window photo, aligned to the bottom of the H1 block. The deed band below: full container width, aspect 16/5 on desktop (object-position 50% 35%), 4/3 under 768px, margin-top 72px, caption below. Under 1024px the window photo is hidden.
Motion: H1 line mask on load; lead, ledger and photo reveal with stagger; the deed band image translates 0 → -5% with scroll inside its frame (same technique as the home hero).
3. **Practice index and detail sections** — Left: PracticeIndex — eyebrow 'ON THIS PAGE', then the six areas as links '01 Wrongful termination' … '06 Employer counsel' to #<slug>; below them a small box (1px Rule border, padding 20px) with 'Not sure which fits?' in Bodoni 500 20px and the link 'Ask on a free call' → ./index.html#consult. Right: six PracticeDetail sections with id = slug, in the same order as the home list. Each section: mono number and eyebrow ('01 · WRONGFUL TERMINATION'); H2 with the area name (italic second word where natural, e.g. 'Wrongful *termination*'); lead paragraph (2–3 sentences); two columns 'WHAT IT COVERS' (5 items) and 'TYPICAL OUTCOMES' (3 items, each starting with a figure or range in Public Sans 600); 'HOW WE RUN IT' — a 3-step timeline with a mono time label, a Bodoni 500 20px title and one sentence; 'REPRESENTATIVE RESULT' — a box with a Bodoni 500 48px Oxblood figure and one sentence; then 'Led by' with the partner's monogram (40px square, Paper Deep, Bodoni italic 18px initials) and name. Write all six in full. Example for 01: lead 'Oregon is an at-will state, but at-will has limits. You cannot be fired for complaining about discrimination or safety, for taking protected leave, or in breach of a written promise.' Covers: 'Termination after reporting harassment, safety or fraud', 'Firing during or after medical, family or military leave', 'Breach of an employment contract or offer letter', 'Constructive discharge — being pushed until you quit', 'Mass layoffs used to target one person or group'. Outcomes: '6–18 months' pay in negotiated severance', '$150K–$900K typical settlement range in retaliation cases', 'Reinstatement with back pay when the client wants it'. How we run it: 'Week 1–2' 'Gather the record' 'We collect your emails, reviews and pay records and build a dated timeline.'; 'Month 1–3' 'Demand and negotiation' 'A detailed demand letter to the employer's counsel, usually followed by a negotiated severance.'; 'Month 4+' 'File and prepare for trial' 'If talks stall, we file in state or federal court and prepare every witness as if trial is certain.' Result '$1.2M' 'Settlement for a warehouse manager fired nine days after reporting forklift safety violations.' Led by Clara Wrenfield. Write 02–06 at the same level of detail, consistent with the home list, results and attorneys (02 Clara Wrenfield, 03 Mira Castellanos, 04 Daniel Osei, 05 Daniel Osei, 06 Theo Lindqvist). Insert stacks.jpg between sections 03 and 04 (caption 'Fig. 3 — Bound reporters in a court library stack.') and case-files.webp between 05 and 06 (caption 'Fig. 4 — A case file on the morning of a deposition.').
Layout: Padding 96px 0. 12-column grid. Columns 1–3: PracticeIndex, position sticky top 120px; links in Public Sans 500 15px Graphite with 12px vertical padding and a 1px Rule left border; the active link (useActiveSection: IntersectionObserver on the six sections, rootMargin '-40% 0px -55% 0px') turns Ink with a 2px Oxblood left border and its number in Oxblood. Columns 5–12: the detail sections, each separated by a 1px Rule hairline and 96px of space, scroll-margin-top 120px. Inside: covers and outcomes in a 2-column grid gap 40px (one column under 768px), list items 16px with a 1px Rule bottom border and padding 12px 0; timeline as 3 equal columns with a top 1px Ink line and 12px Oxblood squares at each step start (stacked under 768px); result box 1px Rule border, Paper Deep background, padding 32px, grid [auto | 1fr] gap 32px. Inline photos span the column at aspect 16/9 with captions. Under 1024px the index becomes a sticky horizontal chip row under the header (top 80px, Paper at 95%, 1px Rule bottom border, overflow-x auto, chips 40px high with 1px Rule border, active chip Ink background Ivory text) and the detail column spans all 12 columns.
Motion: Index active state changes instantly with a 200ms color transition; clicking an index link smooth-scrolls (instant under reduced motion) and updates the URL hash. Section blocks reveal with stagger; H2 line mask; result figures count up.
4. **Call to action band** — H2 in Ivory: 'Not sure which of these fits?' / '*That's what the first call is for.*' Line in Ivory/80%: 'Thirty minutes with a partner, free and confidential. We reply within one business day.' Button 'Book a free consultation' (Ivory background, Ink text, Lucide ArrowRight) → ./index.html#consult and a text link 'Or call (503) 555-0148' (tel:).
Layout: Oxblood background, padding 112px 0. 12-column grid: H2 in columns 1–8; text and buttons in columns 1–6 below with margin-top 32px, buttons in a row gap 24px. A thin 1px Ivory/20% hairline runs across the top inside the container.
Motion: H2 line mask and reveal.
5. **Footer** — The same Footer as index.html.
Layout: Identical to page 1.
Motion: Identical to page 1.
## Assets
- image: Template photos made for this design (free to redistribute with the template). Download each with curl -L -o into public/images/: https://media.vibefather.ai/assets/d4dca035-993f-4721-a9f8-7a6404ceece7/conference-room.webp → public/images/conference-room.webp (Home hero, Fig. 1; alt 'Walnut conference table with case files and a brass lamp before tall windows over the city at dusk'); https://media.vibefather.ai/assets/d4dca035-993f-4721-a9f8-7a6404ceece7/reception.webp → public/images/reception.webp (Home Fees and FAQ, Fig. 5; alt 'Oak-panelled reception with oxblood armchairs and a brass lamp'); https://media.vibefather.ai/assets/d4dca035-993f-4721-a9f8-7a6404ceece7/consult-room.webp → public/images/consult-room.webp (Home Consultation intake, Fig. 3; alt 'Small consultation room with two chairs at a round walnut table'); https://media.vibefather.ai/assets/d4dca035-993f-4721-a9f8-7a6404ceece7/entrance.webp → public/images/entrance.webp (Home Contact, Fig. 6; alt 'Green double doors with brass plates in a limestone entrance at dusk'); https://media.vibefather.ai/assets/d4dca035-993f-4721-a9f8-7a6404ceece7/window-city.webp → public/images/window-city.webp (Practice areas masthead, Fig. 1; alt 'View from an office window down a rainy street of brick and limestone buildings'); https://media.vibefather.ai/assets/d4dca035-993f-4721-a9f8-7a6404ceece7/case-files.webp → public/images/case-files.webp (Practice areas between sections 05 and 06, Fig. 4; alt 'Open case file, legal pad, fountain pen and coffee on a walnut desk').
- image: Public-domain photo: https://thumb.wikimedia.org/wikipedia/commons/thumb/e/ee/Corridor%2C_Joseph_P._Kinnerary_U.S._Courthouse%2C_Columbus%2C_Ohio_LCCN2010719612.tif/lossy-page1-1920px-Corridor%2C_Joseph_P._Kinnerary_U.S._Courthouse%2C_Columbus%2C_Ohio_LCCN2010719612.tif.jpg → public/images/corridor.jpg. Home Case results, Fig. 2 (aspect 4/5, object-position 40% 50%; alt 'Empty marble courthouse corridor with a coffered ceiling and wall lamps'). Source page https://commons.wikimedia.org/wiki/File:Corridor,_Joseph_P._Kinnerary_U.S._Courthouse,_Columbus,_Ohio_LCCN2010719612.tif, author Carol M. Highsmith (Library of Congress, Carol M. Highsmith Archive), license Public domain.
- image: Public-domain photo: https://thumb.wikimedia.org/wikipedia/commons/thumb/7/77/Law_library%2C_Robert_N.C._Nix_Federal_Building%2C_Philadelphia%2C_Pennsylvania_LCCN2010718953.tif/lossy-page1-1920px-Law_library%2C_Robert_N.C._Nix_Federal_Building%2C_Philadelphia%2C_Pennsylvania_LCCN2010718953.tif.jpg → public/images/law-library.jpg. Home Insights, Fig. 4 (aspect 3/4, object-position 62% 50%; alt 'Quiet law library with wooden reading desks, lamps and shelves of bound volumes'). Source page https://commons.wikimedia.org/wiki/File:Law_library,_Robert_N.C._Nix_Federal_Building,_Philadelphia,_Pennsylvania_LCCN2010718953.tif, author Carol M. Highsmith (Library of Congress, Carol M. Highsmith Archive), license Public domain.
- image: CC0 photo: https://live.staticflickr.com/3421/5725642109_af89c3f79f_b.jpg → public/images/deed.jpg. Practice areas masthead band, Fig. 2 (aspect 16/5, object-position 50% 35%; alt 'Handwritten nineteenth-century legal deed with signatures'). Source page https://www.flickr.com/photos/58558794@N07/5725642109/, author Provenance Online Project (Flickr), license CC0 1.0.
- image: CC0 photo: https://thumb.wikimedia.org/wikipedia/commons/thumb/4/43/Indiana_Supreme_Court_Law_Library_bookshelves.jpg/1920px-Indiana_Supreme_Court_Law_Library_bookshelves.jpg → public/images/stacks.jpg. Practice areas between sections 03 and 04, Fig. 3 (aspect 16/9, object-position 50% 70% so the painted ceiling is cropped; alt 'Two tiers of dark iron library stacks filled with bound law reporters'). Source page https://commons.wikimedia.org/wiki/File:Indiana_Supreme_Court_Law_Library_bookshelves.jpg, author LingLass (Wikimedia Commons), license CC0 1.0.
- image: Write ASSETS.md at the project root with a table: path, source URL, author, license — one row for each of the ten images (the six template photos list source 'media.vibefather.ai, made for this template', author 'VibeFather', license 'Distributed with the template'), plus rows for the three Fontsource font packages (OFL-1.1) and lucide-react (ISC). If you change [CITY] or [PRACTICE_FOCUS], keep the CC0 and public-domain photos or replace them only with other CC0 / public-domain files, and replace the six template photos only with your own photos of your own office shot the same way (no faces, no signage).
- icon: lucide-react only: Phone, Mail, MapPin, Clock, ArrowRight, ArrowUpRight, ArrowDown, ChevronLeft, Check, Plus, Menu, X. Stroke width 1.5, 16–22px, color inherits (Ink, Ivory or Oxblood as specified). No emoji, no other icon sets.
- icon: public/favicon.svg hand-written: viewBox 0 0 32 32, a 32×32 square filled #7A1E1E, and a centered italic ampersand as an SVG <text> (x 16, y 23, text-anchor middle, font-family Georgia, serif, font-style italic, font-size 22, fill #EEE8DC). No other logo: the firm name is always set as text in Bodoni Moda.
- font: Install @fontsource-variable/bodoni-moda, @fontsource-variable/public-sans and @fontsource/ibm-plex-mono and import them in src/fonts.ts as listed in Setup. Vite bundles the woff2 files into dist/.
- image: Drawn in code: the StreetMap (inline SVG), monogram tiles (HTML + CSS), hairlines, progress bar, status dots and the success check circle. No other bitmaps, no illustrations.
## Don'ts
- No backend of any kind: no server code, API routes, databases, auth, analytics, email services or third-party APIs. The intake form calls preventDefault and only changes local React state; it never submits, stores or sends anything.
- Do not load fonts from fonts.googleapis.com, fonts.gstatic.com, Adobe Fonts or any CDN. Self-host through the Fontsource packages only.
- No CDN <script>, <link> or import maps. Every script, style, font, icon and image is in the project and bundled into dist/.
- No hotlinked images: every photo is downloaded into public/images/ once and served from there, and every third-party file is listed in ASSETS.md.
- No source maps in the production build (build.sourcemap false), and src/ is not copied into dist/.
- Relative asset paths (Vite base './'). Internal links are hash anchors or file names such as ./index.html, ./index.html#consult and ./practice-areas.html#wage-and-hour, never a bare directory or a leading slash.
- Do not change the stack (Vite 5 + React 18 + TypeScript + Tailwind CSS 3.4 + Motion + lucide-react + Fontsource, two HTML entries) unless the user asks. No router library, no UI kit, no 3D.
- No real law firm's name, logo, crest or tagline; no real attorneys' names, photos or biographies; no real case names, docket numbers or rulings. Every person, case, school, figure and street is invented. Real states and federal districts may appear only as bar admissions.
- No state bar, court, government or university seals, scales-of-justice clip art, gavels or column icons. The firm has no logo mark beyond its typeset name and the favicon ampersand.
- Never promise outcomes. Keep the 'Prior results do not guarantee a similar outcome' disclaimer under the results and the attorney-advertising disclaimer in the footer, and the required acknowledgment checkbox in the intake form.
- No photos with people's faces, handshakes, readable signage, logos or recognizable landmarks. Use only the listed images, and no Unsplash, Pexels, Pixabay or other stock sites with their own licenses. Attorneys are monograms, never photos or AI portraits.
- No commercial or custom fonts: only Bodoni Moda, Public Sans and IBM Plex Mono (OFL).
- Only dependencies under MIT, ISC, BSD, Apache-2.0, 0BSD, CC0 or Unlicense (OFL for fonts). No Aceternity UI, Tailwind Plus / Tailwind UI or purchased template code; write every effect from scratch.
- One accent only: Oxblood (and its lighter #C4544A on dark backgrounds). No gradients, glows, glassy cards, drop shadows, rounded cards or second accent color.
- Respect prefers-reduced-motion exactly as described under Design motion. Every interactive element is keyboard reachable with a visible 2px Oxblood focus ring; accordions and the menu use aria-expanded; form errors use role alert.
- Must render at 1440×900 and 390×844 with zero console errors and no horizontal page scroll (only the mobile practice-index chip row scrolls inside itself).
- Keep dist/ under 20 MB (target under 10 MB).
- No lorem ipsum, filler or hype words. Use the exact headlines, figures, fees, hours and CTAs given here for the default values. No meta descriptions, Open Graph tags, JSON-LD or sitemap: only the <title> and favicon.
---
— Prompt by VibeFather · https://vibefather.ai/t/editorial-law-firm-website · CC BY-NC 4.0 (non-commercial; commercial use needs a VibeFather Pro license) · Request removal: https://vibefather.ai/takedown
Free for personal projects under CC BY-NC 4.0. Commercial use comes with Pro.
DESIGN.md
The design system on its own — colors, type, spacing and motion. Apply this look to a project you already have.
---
name: "Editorial Law Firm Website"
colors:
paper: "#F3EFE7"
paper_deep: "#E8E2D6"
ink: "#17150F"
night: "#1E1C18"
graphite: "#4A463E"
muted: "#857E71"
rule: "#D3CBBC"
oxblood: "#7A1E1E"
oxblood_deep: "#5C1515"
ivory: "#EEE8DC"
typography:
display_h1_h2_wordmark_practice_names_result_figures_article_titles_monogram_initials_family_bodoni_moda_variable_optical_size_axis_auto_italic_400_for_the_highlighted_phrase_in_each_heading: { family: "Bodoni Moda", weights: [400, 500, 600] }
text_body_nav_buttons_form_fields_faq_answers_captions_longer_than_one_line_family_public_sans_variable: { family: "Public Sans", weights: [400, 500, 600] }
mono_eyebrows_section_numbers_01_figure_captions_fig_1_step_labels_read_times_reference_numbers_office_hours_table_family_ibm_plex_mono: { family: "IBM Plex Mono", weights: [400, 500] }
spacing: "8px base unit. Container max-width 1360px, centered, side padding 40px desktop, 24px tablet, 20px under 640px. 12-column grid, column gap 24px. Section vertical padding 128px desktop, 88px under 768px. Every home section starts with SectionHead: a full-width 1px Rule hairline, then 20px below it a row with the mono section number left ('§ 01', IBM Plex Mono 500 12px, Oxblood) and the mono label next to it ('PRACTICE AREAS', 12px uppercase, letter-spacing 0.14em, Muted), and on the far right a mono count where useful ('06 AREAS'). Type scale: H1 clamp(56px, 8.6vw, 136px) Bodoni 500, line-height 0.94, letter-spacing -0.025em; H2 clamp(40px, 5.2vw, 84px) Bodoni 500, line-height 0.98, letter-spacing -0.02em; H3 32px Bodoni 500 line-height 1.1; body Public Sans 400 17px / 1.65 (16px under 768px), long-form paragraphs max-width 64ch; lead paragraphs 21px / 1.5 Graphite; eyebrow IBM Plex Mono 400 12px uppercase letter-spacing 0.14em Muted. Buttons: height 52px, padding 0 28px, Public Sans 500 15px, letter-spacing 0.01em."
radius: "Square corners everywhere (0) — cards, photos, buttons, inputs, radio tiles, accordion rows. The only rounded shapes are the 8px 'open now' status dot, the 999px status pill in Contact and the success check circle."
---
# Editorial Law Firm Website — 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
- **Paper** `#F3EFE7` — Page background on both pages.
- **Paper Deep** `#E8E2D6` — Alternate section background (Principles, Intake, practice-page masthead), row hover, monogram tiles, input fill on focus.
- **Ink** `#17150F` — Headlines, body text on paper, the top bar, the footer background, primary outline buttons.
- **Night** `#1E1C18` — Background of the Case results section.
- **Graphite** `#4A463E` — Secondary body text and paragraph text in long-form sections.
- **Muted** `#857E71` — Eyebrow labels, captions, section numbers, placeholder text, read times.
- **Rule** `#D3CBBC` — All 1px hairlines, card borders, input borders, table lines on paper.
- **Oxblood** `#7A1E1E` — The only accent: primary buttons, active index item, italic highlight words in headings, the small bars above result figures, progress bar, error text, focus rings.
- **Oxblood Deep** `#5C1515` — Hover and pressed state of oxblood buttons.
- **Ivory** `#EEE8DC` — Text on Night and Ink backgrounds; hairlines on dark use Ivory at 14% opacity.
## Typography
- **Display: H1, H2, wordmark, practice names, result figures, article titles, monogram initials (family 'Bodoni Moda Variable', optical size axis auto). Italic 400 for the highlighted phrase in each heading.** — Bodoni Moda (OFL), weights 400/500/600. Self-host the font files.
- **Text: body, nav, buttons, form fields, FAQ answers, captions longer than one line (family 'Public Sans Variable').** — Public Sans (OFL), weights 400/500/600. Self-host the font files.
- **Mono: eyebrows, section numbers (§ 01), figure captions ('Fig. 1 —'), step labels, read times, reference numbers, office-hours table (family 'IBM Plex Mono').** — IBM Plex Mono (OFL), weights 400/500. Self-host the font files.
## Spacing & shape
- Spacing: 8px base unit. Container max-width 1360px, centered, side padding 40px desktop, 24px tablet, 20px under 640px. 12-column grid, column gap 24px. Section vertical padding 128px desktop, 88px under 768px. Every home section starts with SectionHead: a full-width 1px Rule hairline, then 20px below it a row with the mono section number left ('§ 01', IBM Plex Mono 500 12px, Oxblood) and the mono label next to it ('PRACTICE AREAS', 12px uppercase, letter-spacing 0.14em, Muted), and on the far right a mono count where useful ('06 AREAS'). Type scale: H1 clamp(56px, 8.6vw, 136px) Bodoni 500, line-height 0.94, letter-spacing -0.025em; H2 clamp(40px, 5.2vw, 84px) Bodoni 500, line-height 0.98, letter-spacing -0.02em; H3 32px Bodoni 500 line-height 1.1; body Public Sans 400 17px / 1.65 (16px under 768px), long-form paragraphs max-width 64ch; lead paragraphs 21px / 1.5 Graphite; eyebrow IBM Plex Mono 400 12px uppercase letter-spacing 0.14em Muted. Buttons: height 52px, padding 0 28px, Public Sans 500 15px, letter-spacing 0.01em.
- Radius: Square corners everywhere (0) — cards, photos, buttons, inputs, radio tiles, accordion rows. The only rounded shapes are the 8px 'open now' status dot, the 999px status pill in Contact and the success check circle.
## Motion
- Easing: --ease-out cubic-bezier(0.2, 0.7, 0.2, 1) for reveals; --ease-io cubic-bezier(0.65, 0, 0.35, 1) for accordions and form steps.
- Reveal: blocks wrapped in <Reveal> start at opacity 0, translateY(16px) and animate to rest over 700ms --ease-out when 15% visible (Motion whileInView, viewport once). Siblings in the same list stagger by 70ms (pass index prop).
- Headline mask: H1 and every H2 are split into lines in content.ts (an array of line strings, the italic phrase marked with *asterisks*). Each line sits in an overflow-hidden block; the inner span rises from translateY(105%) to 0 over 900ms --ease-out, 90ms stagger, when the heading enters the viewport (H1 on load after 120ms).
- Count-up: numeric parts of result figures and hero ledger figures count from 0 to their value over 1400ms easeOutCubic when 40% visible, once (useCountUp with requestAnimationFrame). Prefix and suffix ('$', 'M', '%', ' months') stay static; decimals keep their precision (4.2, 48.6). Non-numeric figures ('Dismissed') only fade in.
- Hero photo: on load it scales from 1.06 to 1 over 1600ms --ease-out; while scrolling, the image inside its frame translates from 0 to -6% of its height (Motion useScroll + useTransform on the frame's scroll progress). The frame itself does not move.
- Link underline: .link-draw uses background-image linear-gradient(currentColor, currentColor), background-size 0% 1px at bottom left, no-repeat; on hover and focus-visible it grows to 100% 1px over 300ms --ease-out.
- Rows and cards: practice rows and insight rows fade their background to Paper Deep over 200ms on hover, the arrow icon moves 6px right, the number turns Oxblood. Attorney monogram tiles swap to Ink background with Ivory initials over 300ms.
- Accordions (FAQ, insights): height animates with Motion (AnimatePresence, height 0 → auto, opacity 0 → 1) over 320ms --ease-io; the Plus icon rotates 45° into an X.
- Intake steps: the outgoing step fades and moves 24px left, the incoming step enters from 24px right, 260ms --ease-io (AnimatePresence mode 'wait'); going Back reverses the direction. The progress bar width animates over 400ms.
- Header: transparent with no border at the top of the page; after 24px of scroll it gets Paper at 92% opacity, backdrop-filter blur(8px) and a 1px Rule bottom border, 200ms transition.
- prefers-reduced-motion: reduce — disable the headline mask, reveals, parallax, hero scale, count-up (show final values), step slide (crossfade 0ms) and smooth scrolling. Hover color changes stay.
## Imagery
Real documentary photography only: the firm's own conference room, reception, consultation room, desk with case files, the view from its window and its street entrance (six photos made for this template), plus four public-domain / CC0 photos of a courthouse corridor, a law library, legal stacks and a nineteenth-century handwritten deed. No people or faces anywhere. Every photo gets the .photo treatment: filter saturate(0.82) contrast(1.04) sepia(0.06), object-fit cover, a 1px Rule outline, no shadow, square corners, and a caption below in IBM Plex Mono 12px Muted that starts with 'Fig. n —' (numbered in page order). Attorneys are typographic monograms, never photos. Everything else is drawn in code: the favicon, the SVG street map in Contact, dividers, the success check. Icons from lucide-react only, stroke 1.5.
## Tone
Serious, plain-spoken and confident. Short declarative sentences, concrete numbers, no legal jargon without an explanation, no hype words, no exclamation marks. The firm sounds like a calm senior partner explaining things across a table.
---
— Prompt by VibeFather · https://vibefather.ai/t/editorial-law-firm-website · CC BY-NC 4.0 (non-commercial; commercial use needs a VibeFather Pro license) · Request removal: https://vibefather.ai/takedown