Pre-Flight & Review

The Iron Law: never ship the first version. Build it, then run these checks with fresh, critical eyes. Sources: emil (review format + checklist) and taste-skill (pre-flight matrix).

Review Format (required when reviewing UI code)

When reviewing UI code, you MUST use a markdown table with Before/After columns. Do NOT use a list with “Before:” and “After:” on separate lines. Always output an actual markdown table like this:

Before After Why
transition: all 300ms transition: transform 200ms ease-out Specify exact properties; avoid all
transform: scale(0) transform: scale(0.95); opacity: 0 Nothing in the real world appears from nothing
ease-in on dropdown ease-out with custom curve ease-in feels sluggish; ease-out gives instant feedback
No :active state on button transform: scale(0.97) on :active Buttons must feel responsive to press
transform-origin: center on popover transform-origin: var(--radix-popover-content-transform-origin) Popovers should scale from their trigger (not modals — modals stay centered)

Wrong format (never do this):

Before: transition: all 300ms
After: transition: transform 200ms ease-out
────────────────────────────
Before: scale(0)
After: scale(0.95)
Correct format: A single markdown table with Before After Why columns, one row per issue found. The “Why” column briefly explains the reasoning.

Motion Review Checklist (from emil)

When reviewing UI code, check for:

Issue Fix
transition: all Specify exact properties: transition: transform 200ms ease-out
scale(0) entry animation Start from scale(0.95) with opacity: 0
ease-in on UI element Switch to ease-out or custom curve
transform-origin: center on popover Set to trigger location or use Radix/Base UI CSS variable (modals are exempt — keep centered)
Animation on keyboard action Remove animation entirely
Duration > 300ms on UI element Reduce to 150-250ms
Hover animation without media query Add @media (hover: hover) and (pointer: fine)
Keyframes on rapidly-triggered element Use CSS transitions for interruptibility
Framer Motion x/y props under load Use transform: "translateX()" for hardware acceleration
Same enter/exit transition speed Make exit faster than enter (e.g., enter 2s, exit 200ms)
Elements all appear at once Add stagger delay (30-80ms between items)

Full Pre-Flight Matrix (from taste-skill)

Run this matrix before outputting code. This is the last filter.

THIS IS NOT OPTIONAL. Run every box. If any box fails, the output is not done.

  • Brief inference declared (Section 0.B one-liner)?
  • Dial values explicit and reasoned from the brief, not silently using baseline?
  • Design system chosen from Section 2 if applicable, or aesthetic labeled honestly?
  • Redesign mode detected and audit performed (if applicable, Section 11)?
  • ZERO em-dashes (—) anywhere on the page. Headlines, eyebrows, pills, body, quotes, attribution, captions, buttons, alt text. Zero. (Section 9.G - non-negotiable.)
  • Page Theme Lock: ONE theme (light, dark, or auto) for the whole page. No section flips to inverted mode mid-page (Section 4.11)?
  • Color Consistency Lock: one accent color used identically across all sections (Section 4.2)?
  • Shape Consistency Lock: one corner-radius system applied consistently (Section 4.4)?
  • Button Contrast Check: every CTA text is readable against its background (no white-on-white, WCAG AA 4.5:1)?
  • CTA Button Wrap: no CTA label wraps to 2+ lines at desktop?
  • Form Contrast Check: form inputs, placeholders, focus rings, labels all pass WCAG AA against the section background?
  • Serif discipline: if a serif is used, it is NOT Fraunces or Instrument_Serif (or it is, with explicit brand justification)? Different serif from your previous project?
  • Premium-consumer palette check: if the brief is premium-consumer (cookware / wellness / artisan / luxury), the palette is NOT the AI-default beige+brass+oxblood+espresso family? Different family from your previous premium-consumer project?
  • Italic descender clearance: every italic word with y g j p q has leading-[1.1] min + pb-1 reserve?
  • Hero fits the viewport: headline ≤ 2 lines, subtext ≤ 20 words AND ≤ 4 lines, CTA visible without scroll, font scale planned around image?
  • Hero top padding: max pt-24 at desktop, hero content does not float halfway down the viewport?
  • Hero stack discipline: max 4 text elements in hero (eyebrow OR brand strip, headline, subtext, CTAs)? No tiny tagline below CTAs, no trust micro-strip in hero?
  • EYEBROW COUNT (mechanical): count instances of uppercase tracking micro-labels above section headlines across all components. Count ≤ ceil(sectionCount / 3)? Hero counts as 1.
  • Split-Header Ban: no “left big headline + right small explainer paragraph” pattern as a section header (vertical stack instead)?
  • Zigzag Alternation Cap: no 3+ consecutive sections with the same image+text-split layout?
  • No Duplicate CTA Intent: no two CTAs with the same intent (“Get in touch” + “Let’s talk” both on page = Fail)?
  • Logo wall = logo only: no industry / category labels printed below logos?
  • Bento Background Diversity: at least 2-3 bento cells have real visual variation (image, gradient, pattern), not all white-on-white text cards?
  • “Used by / Trusted by” logo wall lives UNDER the hero, not inside it, uses REAL SVG logos (Simple Icons / devicon) or generated SVG marks, NOT plain text wordmarks?
  • Copy Self-Audit: every visible string re-read, no grammatically-broken or AI-hallucinated phrases (“free on its past” type) shipped?
  • Motion motivated: every animation can be justified in one sentence (hierarchy / storytelling / feedback / state transition), no GSAP-for-show?
  • Marquee max-one-per-page: no two horizontal marquees on the same page?
  • Navigation on ONE line at desktop, height ≤ 80px?
  • Section-Layout-Repetition check: no two sections share the same layout family (at least 4 different families across 8 sections)?
  • Bento has rhythm AND exact cell count (N items → N cells, no empty cells in middle or at end)?
  • Long lists use the right UI component (not default <ul> with divide-y for > 5 items - see Section 4.9 alternatives)?
  • Real images used (gen-tool first, then Picsum-seed, then explicit placeholder slots) - NO div-based fake screenshots, NO hand-rolled decorative SVGs, NO pure-text minimalism?
  • No pills/labels overlaid on images (no Plate · Brand, no Field notes - journal)?
  • No photo-credit captions as decoration (Field study no. 12 · Ines Caetano)?
  • No version footers (v1.4.2, Build 0048) on marketing pages?
  • No micro-meta-sentences under eyebrows (“Each of these is a feature we ship today…”)?
  • No decoration text strip at hero bottom (BRAND. MOTION. SPATIAL.)?
  • No floating top-right sub-text in section headings?
  • No scoring/progress bars with filled background tracks as comparison visuals?
  • No locale / city-name / time / weather strips unless brief is genuinely globally-distributed or place-focused?
  • No scroll cues (Scroll, ↓ scroll, Scroll to explore)?
  • No version labels in hero (V0.6, BETA, INVITE-ONLY) unless the brief is a launch?
  • No section-numbering eyebrows (00 / INDEX, 001 · Capabilities, 06 · how it works)?
  • No decorative dots (zero by default, only for real semantic state)?
  • No border-t + border-b on every row of long lists / spec tables?
  • Content density sane: no 20-row data tables, no fake-precise specs without justification, ≤ 25-word sub-paragraphs by default?
  • Quotes ≤ 3 lines of body, attribution clean (no em-dash)?
  • Motion claimed = motion shown: if MOTION_INTENSITY > 4, page actually animates, not just claimed?
  • GSAP sticky-stack / horizontal-pan implemented per Section 5.A / 5.B canonical skeleton (start: "top top", pin: true, correct scrub)?
  • No window.addEventListener('scroll') - using Motion useScroll() / ScrollTrigger / IntersectionObserver / CSS scroll-driven animations only?
  • Reduced motion wrapped for everything MOTION_INTENSITY > 3?
  • Dark mode tokens defined and tested in both modes?
  • Mobile collapse explicit (w-full, px-4, max-w-7xl mx-auto) for high-variance layouts?
  • Viewport stability: min-h-[100dvh], never h-screen?
  • useEffect animations have strict cleanup functions?
  • Empty / loading / error states provided?
  • Cards omitted in favor of spacing where possible?
  • Icons from an allowed library only (Phosphor / HugeIcons / Radix / Tabler), no hand-rolled SVG paths?
  • Motion isolated in client-leaf components with 'use client' at the top, memoized?
  • No AI Tells from Section 9 (Inter as default, AI-purple, three-equal cards, Jane Doe, Acme, “Quietly in use at”)?
  • Core Web Vitals plausibly hit (LCP < 2.5s, INP < 200ms, CLS < 0.1)?
  • One design system per project (no Material + shadcn mixed)?

If a single checkbox cannot be honestly ticked, the page is not done. Fix it before delivering.


Built at Harris Computer · Constellation Software. Licensed under MIT.