Template
Harborline Law
A credible, conversion-focused website for a personal injury law firm. It explains when to hire a lawyer, lists practice areas with illustrations, introduces attorneys, demystifies costs and captures case intake through forms and click-to-call.
Personal injury law firm website · Website · Small business site · static site
A mock-up of the homepage, drawn from this design’s layout, palette and typefaces. A build follows the full prompt below.
Start from this templateRead the build prompt
Typefaces
EB Garamond signals legal tradition with a gentler, more approachable voice than a didone, and Roboto Flex keeps forms and nav crisp.
- EB GaramondHeadings: hero 60px 700, italic first line, tight leading
- Roboto FlexBody: body 16px, forms and nav
Who it is for
- Personal injury law firms
- Injured people seeking representation
- Small legal practices
- Legal marketing agencies
Layout
- Navy utility bar: credential chip left, star rating + review count and language switch right
- Main header: two-tone wordmark left, links (About Us, Practice Areas dropdown, Costs, Contact) centered, navy pill phone button right
- Split hero: large serif headline with an italic first line, three check-mark trust bullets, violet 'Get help' button; staggered collage of three professional portraits right
- Explainer section on when to hire an injury lawyer
- 4x2 practice area grid with flat violet illustrations, titles and chevrons
- 'Our commitment' split section on lavender-tinted background with offset photo
- News cards with category badges
- Contact form with map; FAQ accordion; Costs page; 404
Palette
trustworthy, reassuring, professional, approachable, modern. It feels like a law firm that is easier to talk to than you expect.
- background
#ffffff - primary navy
#0c1f40 - utility bar navy
#2b3a55 - accent violet
#5b52c7 - tinted section
#f5f5fd - text
#1a212d - border
#e1e7ef - illustration violet (decorative)
#736ad7 - input border
#7c96b9
Every checked pair, measured again
| Sample | Where | Ratio | Needs |
|---|---|---|---|
| Aa | body text on white | 16.16:1 | 4.5:1 |
| Aa | body text on tinted section | 14.90:1 | 4.5:1 |
| Aa | white text on navy pill | 16.33:1 | 4.5:1 |
| Aa | white text on utility bar | 11.42:1 | 4.5:1 |
| Aa | white text on violet button | 6.04:1 | 4.5:1 |
| Aa | violet link/hover title on white | 6.04:1 | 4.5:1 |
| Aa | violet text on tinted section | 5.57:1 | 4.5:1 |
| input border | 3.03:1 | 3:1 | |
| focus ring | 6.04:1 | 3:1 |
As vibld’s tokens
The palette on the fifteen colour tokens vibld styles a project with, each text colour on the fill it is read on. Marked tokens are solved from the palette, because no swatch held that role at 4.5:1.
- background
- card
- muted
- primary
- secondary
- accent
- destructive *
Type scale
- Display
- EB Garamond Bold 700, 60px hero, first line italic, tight leading
- Body
- Roboto Flex 16px, weight 400, line-height 1.6, #1a212d
The serif signals legal tradition; Roboto Flex keeps forms and nav crisp. The logo uses a sans with one violet word.
Spacing and imagery
1216px container, 4-column grids, 96px section padding, 8px radius, pill buttons.
Bright stock portraits of friendly professionals in an offset collage; flat violet and black spot illustrations for practice areas; justice-scale photo with a violet offset block.
Components
- Utility bar with rating and language
- Two-tier sticky header
- Practice Areas dropdown menu
- Phone pill CTA
- Trust bullet list
- Portrait collage
- Practice area illustration cards
- Split feature section with offset image
- News card with category badge
- FAQ accordion
- Contact form + embedded map
- Mobile slide-out drawer with collapsible submenu
Interactions
- Sticky header with dropdown on hover/click
- Fade-in-up hero animations
- Practice card hover: chevron shift and title color change
- FAQ expand/collapse
- Mobile drawer (Vaul) with nested practice menu
- Form submit toast (Sonner)
- Click-to-call on mobile
Data
PracticeArea{slug, title, illustration, summary, body, faqs[]}Attorney{slug, name, title, photo, bio, barAdmissions}Article{slug, title, category, excerpt, author, date, body}FAQ{question, answer}Intake{name, email, phone, incidentType, message, consent}
Build prompt
The baseline every prompt in the catalog assumes, then this design’s own ten sections, from goal to guardrails.
The baseline
### How to use these prompts Paste a template's build prompt into your coding agent as the first message. Each prompt names its own stack, tokens and acceptance criteria; the rules below apply to all of them and can be prepended once per project. ### Engineering baseline - TypeScript strict mode, no `any`, small typed components, feature folders, and one source of truth for design tokens (CSS variables consumed by Tailwind). - Validate every input with a shared zod schema on the client and again on the server or edge function. Never trust client-side checks alone. - Show loading, empty and error states for every async view. Surface errors in plain language with a retry, and log details to the console in development only. - Keep secrets out of the bundle. Only publishable keys (for example a Supabase anon key) belong in client code; service-role keys, API keys and webhooks live in server or edge-function environment variables. ### Data and auth baseline (full-stack templates) - Enable Row Level Security on every table before inserting data. Default-deny, then add owner-scoped policies (`auth.uid() = user_id`) and explicit role checks for admin views. - Store roles in a separate table checked by a security-definer function, never in a user-editable profile field. - Upload files to private storage buckets with size and MIME limits, and serve them through signed URLs. - Rate-limit public endpoints (forms, auth, AI calls) and add a honeypot field or captcha to anonymous forms. - Take payments through a hosted checkout and verify webhooks by signature. Never handle raw card data. ### Accessibility and UX baseline - Target WCAG 2.2 AA: 4.5:1 contrast for normal text and 3:1 for large text, input borders, focus rings and meaningful icons or chart lines. Every palette in this catalog lists its verified pairs; re-check with a contrast tool after any colour change. - Keep body text at 16px or larger with 1.5 line height, nothing below 12px, no light weights under 24px, and uppercase only for short labels. - Give every interactive element a visible focus ring, full keyboard support, semantic landmarks, labelled form fields, and alt text on meaningful images. - Respect `prefers-reduced-motion` for every animation. Give drag-and-drop and carousels keyboard and button alternatives. - Build mobile-first and test at 375px, 768px and 1280px. ### Content guardrails - Use original copy, fictional sample data and placeholder or licensed imagery. Do not reuse another product's name, logo, screenshots or marketing text. - Label demo testimonials and metrics as samples. Collect the minimum personal data the feature needs.
### Goal
Build "Harborline Law", a multi-page website for a personal injury firm. Visitors who were recently injured arrive stressed, so the site must reassure them, explain options and costs plainly, and make calling or requesting a case review effortless.
### Stack
React 18 + TypeScript + Vite, Tailwind CSS, shadcn/ui (NavigationMenu, Accordion, Drawer via Vaul, Toast via Sonner, Form), lucide-react. Framer Motion for gentle fade-up entrances. react-hook-form + zod for intake. React Router for about 18 routes. The one backend piece is an Edge Function (Supabase) that validates and emails intake submissions and stores them in a table only staff can read.
### Pages & layout
1. **Utility bar** (navy): a credential chip left; star rating, review count and language switch right.
2. **Header**: a wordmark with one word in violet, links (About, Practice areas with a dropdown of 8, Costs, Contact) and a navy pill phone button.
3. **Home hero**: split. The left side has a serif headline with an italic first word, three check-icon trust bullets and a violet "Get help" button; the right side has three overlapping portrait photos in a staggered collage.
4. An explainer ("Why hire an injury lawyer?") with a secondary CTA.
5. A practice area grid (4x2) with flat illustrations, titles and chevrons.
6. "Our commitment": a lavender section with a photo and an offset violet block.
7. Three news cards with category badges.
8. FAQ accordion, then the footer with office address, hours and legal disclaimers.
9. Inner pages: About, Attorneys, Practice area detail (8), Costs explainer (no-win-no-fee, compensation types), News index and article, Contact (form plus map), and 404.
### Design system
Tokens: `--background: #ffffff`, `--primary: #0c1f40` (navy), `--utility: #2b3a55`, `--accent: #5b52c7` (violet, darkened from a lighter `#736ad7` for AA text), `--tint: #f5f5fd`, `--foreground: #1a212d`, `--border: #e1e7ef` (decorative), `--input-border: #7c96b9`, `--radius: 0.5rem`. Fonts: EB Garamond 700 for headings, Roboto Flex 400/500/600 for UI. Scale: 60/48/32/20/16/14px. Spacing: 8px base, 96px sections, 1216px container. Motion: 400ms fade-up and 150ms hover transitions. Light theme.
### Components & interactions
- Dropdown nav: opens on hover and click, is keyboard navigable, and closes on Escape.
- Practice card: on hover the chevron moves 4px and the title turns violet; the whole card is one link.
- Intake form: name, email, phone, incident type (Select), message and a consent checkbox. States: inline errors, submitting spinner, success toast, and a failure toast that shows the phone number.
- Mobile drawer: a full-height Vaul drawer with a collapsible practice submenu and a sticky call button.
- FAQ: single-open accordion.
### Data & state
Typed content files: `PracticeArea{slug, title, illustration, summary, sections, faqs}`, `Attorney{slug, name, role, photo, bio, admissions}`, `Article{slug, title, category, excerpt, author, date, body}`. Intake goes to the `intakes` table. Seed fictional attorneys and articles with no real names or case results.
### Accessibility
Check the palette: navy on white is AAA, and use the darkened violet for text and buttons (white on `#5b52c7` is about 5.9:1). Use large tap targets (44px) for the phone buttons, labelled form fields with `aria-describedby` errors, and a visible 2px `#5b52c7` focus ring. Provide a skip link, `nav`, `main` and `footer` landmarks, alt text on portraits, and decorative illustrations with `alt=""`. The map embed needs a title and a text address beside it. Respect reduced motion. Verified contrast: body #1a212d on #ffffff = 16.16:1; button #ffffff on #5b52c7 = 6.04:1; violet on tint #5b52c7 on #f5f5fd = 5.57:1; input border #7c96b9 on #ffffff = 3.03:1.
### Security
Validate intake with zod on the client and again in the Edge Function. Add a honeypot, per-IP rate limiting and an optional Turnstile captcha. The `intakes` table has RLS with insert-only access for anon and read access for the staff role only. Collect the minimum injury detail, show a notice that submitting does not create an attorney-client relationship, and keep API keys only in function env. Links to external resources use `rel="noopener noreferrer"`.
### Performance & SEO
Pre-render or add per-route meta, and use LegalService and FAQPage JSON-LD. Lazy-load illustrations and the map (click to load). Keep one H1 per page and give practice pages descriptive titles. Target Lighthouse 90+.
### Guardrails
- Use original copy and placeholder portraits and illustrations only, with no real firm names, bar logos or trademarks.
- Do not show invented reviews, ratings or case results as real.
- Do not collect medical records or IDs through the form.
- Keep components small and typed, with no `any`, and show errors visibly.
- Done when: every route renders with correct meta; the dropdown and drawer work by keyboard; intake validates both sides and rejects spam; the 404 page shows for unknown routes; click-to-call works on mobile.