# DESIGN.md. General contract for AI-built web apps

> A general-purpose design contract used by the Design Scan when auditing
> any Lovable-built app. Distilled from broadly accepted best practices in
> visual design, UX, information architecture, accessibility, and front-end
> craft. Not a style guide for any one product. A floor.
>
> If a generated surface violates anything in this file, the change is
> probably wrong, no matter how well-formed the code is. Project-level
> DESIGN.md files override this when they conflict.

---

## 1. First principles

A surface earns its right to exist if it does three things at once:

1. **Communicates clearly.** The user knows where they are, what they can
   do, and what just happened, within one second of looking.
2. **Behaves predictably.** Same control, same affordance, same outcome,
   everywhere. Surprise is a bug.
3. **Stays out of the way.** The interface disappears into the task. It
   does not perform itself.

Anything that fails one of these is a finding, even if it looks polished.

---

## 2. Voice and copy

- **Lead with the answer.** No throat-clearing. No "Welcome to..." No
  "Let's get started." No "In today's landscape..."
- **Use the user's words.** Never invent jargon. Never use marketingspeak
  ("seamless", "innovative", "unlock", "leverage", "best-in-class",
  "synergy", "ecosystem", "empower").
- **No filler.** Cut "simply", "just", "easily", "actually", "very",
  "really", "in order to", "at the end of the day", "that said".
- **Sentence case in UI.** Title Case Belongs In Marketing, Not Buttons.
- **Buttons are verbs.** "Save changes", not "Submit". "Delete account",
  not "OK". One verb, one outcome.
- **Errors blame the system, not the user.** "We couldn't save that. Try
  again." not "Invalid input."
- **Empty states do work.** They explain what goes here, why it matters,
  and what the next action is. Never a sad illustration with no
  instruction.
- **No emojis in product UI.** They age badly and read as decoration.

---

## 3. Typography

- **Pick at most two type families.** One for UI and body, one for
  display or mono if needed. Three families is almost always wrong.
- **Body text is 15-18px.** Never under 14px. Never over 20px for body.
- **Body line-height is 1.5-1.7.** Tight line-height on body text is a
  reading bug.
- **Display text uses tighter tracking.** Negative letter-spacing
  (-0.01em to -0.03em) for headings 32px+. Default tracking for body.
- **Limit measure to 50-75 characters per line.** Long lines are
  fatiguing. Use `max-width` on prose containers (typically 60-72ch).
- **One heading per visual level.** Don't mix h2 sizes within the same
  page. Heading scale should be deliberate, not improvised.
- **Numerics use tabular figures** in tables, dashboards, and any column
  of comparable numbers. CSS: `font-variant-numeric: tabular-nums`.

---

## 4. Color

- **Define semantic tokens.** Colors live in CSS variables or a theme
  object: `background`, `foreground`, `muted`, `border`, `accent`,
  `destructive`. Components reference tokens, never raw hex or Tailwind
  color classes (`text-white`, `bg-blue-500`).
- **WCAG AA minimum.** Body text contrast >= 4.5:1 against its
  background. Large text (18px+ bold or 24px+) >= 3:1. UI controls and
  graphical objects >= 3:1. Test in both light and dark themes.
- **Color is never the only signal.** Don't use red alone to mean
  "error" or green alone to mean "success". Pair color with an icon, a
  label, or a position. Color-blind users exist.
- **One accent color, used sparingly.** The accent earns attention by
  being rare. If the accent is everywhere, nothing is accent.
- **Avoid pure black on pure white.** `#000` on `#fff` produces eye
  strain. Use a near-black (`#0a0a0a`-`#1a1a1a`) on a near-white
  (`#fafafa`-`#ffffff`) or an off-white background.

---

## 5. Spacing and layout

- **Use a spacing scale.** 4px or 8px base, with a consistent ramp
  (4, 8, 12, 16, 24, 32, 48, 64, 96). Never freelance values like
  `13px` or `27px`.
- **Vertical rhythm matters.** Section breaks, paragraph spacing, and
  component gaps should feel like multiples of one rhythm, not random.
- **Prose columns max 680-720px.** Wider lines hurt reading.
- **Page width has a maximum.** Centered layouts cap at 1200-1440px on
  large screens. Full-bleed only for hero or visualization sections.
- **Padding is responsive.** 16-24px on mobile, 32-48px on tablet,
  48-120px on desktop. Never the same padding everywhere.
- **Whitespace is a feature.** Crowded layouts read as careless.
  Generous space around primary content reads as confident.

---

## 6. Responsive and mobile

- **Mobile first, not mobile last.** If a layout was designed at desktop
  width and "made responsive", it usually shows.
- **Touch targets >= 44x44px.** Smaller targets are a usability and
  accessibility bug.
- **No horizontal scroll on mobile** except in deliberate carousels.
- **Modals on mobile are full-screen sheets.** Centered modals on a
  small screen are a desktop habit that doesn't survive contact.
- **Fixed positioning is dangerous on mobile.** Sticky headers eat
  viewport. Bottom-fixed CTAs cover content. Use sparingly.

---

## 7. Components and patterns

- **Reuse, don't reinvent.** A second button style needs a reason. A
  third does not exist. Same for inputs, cards, modals, tabs.
- **Border radius is a system value, not per-component.** Pick one
  (typically 4-12px), apply consistently. Pills only for status chips.
- **Shadows are restrained.** One or two elevation levels max. Never
  drop-shadow on text or icons. Never glassmorphism without intent.
- **No card sprawl.** Wrapping every block in a bordered card creates
  visual noise. Cards earn their borders by grouping a real unit.
- **Forms have one column.** Multi-column forms slow down completion
  and confuse keyboard order. Side-by-side fields only for genuinely
  paired inputs (city/zip, first/last name).
- **Labels above inputs, always visible.** Placeholder-as-label
  disappears the moment users start typing. It is an accessibility
  failure.
- **Required fields are marked, optional fields are not** (or
  vice-versa, but consistently). Both marked is noise.
- **Disabled states must explain themselves.** A disabled button with
  no tooltip or helper text leaves the user stuck.

---

## 8. Interaction and motion

- **Hover, focus, active, disabled states for every interactive
  element.** Missing focus rings is the most common accessibility
  failure.
- **Transitions are 100-300ms.** Faster feels broken, slower feels
  laggy. Use ease-out for entrances, ease-in for exits.
- **Never animate layout.** Animating width, height, top, left causes
  jank. Animate transform and opacity.
- **No bouncy springs in product UI.** Spring physics belong in
  marketing pages and games, not in a CRUD form.
- **Respect `prefers-reduced-motion`.** Users with vestibular
  disorders disable animations system-wide. Honor it.
- **Loading states beat spinners.** Use skeleton screens for content
  shape, progress bars for known-duration operations, optimistic UI
  for actions that usually succeed.
- **Optimistic UI requires real rollback.** If you show success before
  the server confirms, you must show a clear, recoverable error if it
  fails.

---

## 9. Accessibility (the floor)

- **Use semantic HTML.** `<button>` for buttons, `<a>` for links,
  `<nav>`, `<main>`, `<header>`, `<h1>`-`<h6>` in order. Divs with
  click handlers are a bug.
- **Every form input has a `<label>`.** With `for` matching `id`, or
  the input nested inside.
- **Every image has alt text.** Decorative images get `alt=""`. There
  is no in between.
- **Keyboard navigation works everywhere.** Tab, Shift+Tab, Enter,
  Space, Esc, Arrow keys where appropriate. Test by unplugging the
  mouse.
- **Visible focus rings.** Never `outline: none` without replacing it
  with a visible focus state.
- **Color contrast meets WCAG AA.** See section 4.
- **Headings are hierarchical.** One h1 per page. h2s under it. Don't
  skip levels for visual reasons; use CSS to size them.
- **Modals trap focus and return it.** Opening a modal moves focus
  inside. Closing returns focus to the trigger.
- **Live regions announce dynamic changes.** Toasts, validation
  messages, and async results need `aria-live` so screen readers hear
  them.
- **Forms announce errors.** `aria-invalid`, `aria-describedby`
  pointing to error text.

---

## 10. Information architecture

- **Navigation is shallow and predictable.** Three clicks to anything
  important. Persistent primary nav. Breadcrumbs for depth >= 2.
- **Active state in nav is always visible.** Users should know where
  they are without reading the URL.
- **Search where appropriate.** Any list >= 50 items needs filter or
  search. Any text-heavy app needs global search.
- **Empty list = explain + next action.** Never an empty grid with no
  context.
- **Destructive actions confirm.** Delete, archive, send-to-everyone.
  Confirmation modal with the consequence in plain language and the
  destructive verb on the destructive button.
- **Undo beats confirm where possible.** "Deleted. Undo." is faster
  and friendlier than "Are you sure?"

---

## 11. Performance and perceived speed

- **First contentful paint < 1s on broadband, < 2.5s on 3G.** Lazy-load
  below-the-fold images, defer non-critical JS, inline critical CSS.
- **Images are sized.** `width` and `height` attributes prevent
  layout shift. Use modern formats (AVIF, WebP) with fallbacks.
- **Fonts don't block render.** Use `font-display: swap` or
  `font-display: optional`. Self-host or preconnect to the font
  provider.
- **Skeleton screens for slow loads.** Don't show a blank screen for
  more than 200ms. Don't show a spinner for less than 500ms.
- **Debounce expensive interactions.** Search inputs, filters, slider
  updates. 150-300ms is typical.

---

## 12. SEO and metadata

- **Every route has unique `<title>` and `<meta name="description">`.**
  Length: title under 60 chars, description under 160.
- **Open Graph and Twitter Card metadata** on every shareable route.
  `og:title`, `og:description`, `og:image`. Don't reuse home page
  metadata everywhere.
- **One `<h1>` per page.** Search engines and screen readers both
  rely on this.
- **Canonical URL on every page.** Prevents duplicate content
  penalties.
- **Semantic HTML helps SEO too.** Bots parse `<article>`, `<nav>`,
  `<main>`, `<section>` more reliably than `<div>` soup.

---

## 13. Trust and safety

- **No dark patterns.** No pre-checked email opt-ins. No "Are you
  sure you want to leave us?" with the cancel button styled as
  primary. No countdown timers manufacturing urgency.
- **Privacy is opt-in, tracking is disclosed.** Cookie banners are
  honest, not coercive. "Reject all" is as easy as "Accept all".
- **Destructive actions are recoverable.** Soft delete with a window.
  Trash, not shred.
- **Auth flows are paranoid.** Show password requirements before
  submission. Never echo the password back. Never email it. Rate
  limit attempts.

---

## 14. Anti-patterns (immediate findings)

If a surface contains any of these, flag it.

- **Stock-photo hero with smiling team.** Lazy and dated.
- **"Trusted by" logo bar with logos at random sizes.** Unconvincing
  and chaotic.
- **Testimonial carousel that auto-advances.** Carousels under-perform
  on every metric.
- **Newsletter modal on first visit.** Hostile.
- **Cookie banner that can't be dismissed without accepting.** Illegal
  in many jurisdictions, hostile everywhere.
- **Animated background gradient or particles behind text.** Hurts
  reading, signals "template".
- **Glass card with backdrop-blur over a busy background.** Almost
  always fails contrast.
- **Generic AI-illustration mascot.** Reads as default.
- **More than three font weights on one screen.**
- **Buttons styled as links and links styled as buttons.** Affordance
  scrambled.
- **Pop-up support widget that opens on page load.** Not a feature.
- **"Sign up to read more" walls on content the page advertised.**
  Bait and switch.

---

## 15. How a model should use this file

When auditing any surface against this contract, the model should:

1. Read this file first. Treat it as the floor, not the ceiling.
2. If a project DESIGN.md exists and conflicts, prefer the project
   file. Project intent overrides general best practice.
3. Flag the most material findings first. A failing primary CTA
   beats a font-weight nit.
4. Categorize findings: voice, drift, slop, novelty, accessibility.
5. Always propose a concrete fix. "Reduce to one accent color and
   re-test contrast" beats "color usage is inconsistent".
6. Be specific. Quote the offending element when possible.

---

*General contract. Maintained as the floor for AI-built web apps.
Project-level DESIGN.md files override where they conflict.*
