# Anti-AI gate

The canonical pre-commit grep gate and the eyeball checklist that catch AI-generated design tells before they ship.

Run this before finishing any landing page. The [hard-rules table](/design/overview#hard-rules-non-negotiable) defines what's forbidden and the fix for each rule; this page gives the canonical gate commands that catch violations mechanically.

The installed `LandingPage.tsx` and `primitives.tsx` contain known rule 5/6 violations. Treat their gate hits as bugs in the app copy, not false positives.

## The grep gate — run before finishing

From the app root, scoped to landing files:

```bash
# ── Hardcoded colors — should never appear ───────────────────────────────────
grep -rnE "#[0-9a-fA-F]{6}|#[0-9a-fA-F]{3}\b" --include="*.tsx" src/pages/index.tsx 'src/pages/(app)/landing.tsx' src/components/landing/ 2>/dev/null
grep -rnE "rgba?\([0-9]" --include="*.tsx" src/pages/index.tsx 'src/pages/(app)/landing.tsx' src/components/landing/ 2>/dev/null
grep -rnE "\b(violet|indigo|purple|fuchsia|rose|amber|emerald|teal|cyan|sky|blue|green|red|orange|yellow|lime|pink)-[0-9]{3}" --include="*.tsx" src/pages/index.tsx 'src/pages/(app)/landing.tsx' src/components/landing/ 2>/dev/null

# ── Fractional-opacity foreground patterns ───────────────────────────────────
grep -rnE "(bg|text|border)-foreground/(\[|[0-9])" --include="*.tsx" src/pages/index.tsx 'src/pages/(app)/landing.tsx' src/components/landing/ 2>/dev/null

# ── Continuous animations — advisory; review each for a useReducedMotion gate
grep -rnE "repeat:\s*Infinity|setInterval\(|requestAnimationFrame\(" --include="*.tsx" src/pages/index.tsx 'src/pages/(app)/landing.tsx' src/components/landing/ 2>/dev/null

# ── Pictograph emojis (Unicode 1F000-1FFFF). Plain marks like ✓ ✗ → ★ are NOT
# caught (they're in the BMP < 1F000) and are allowed as text glyphs.
# Needs PCRE: use `rg "[\u{1F000}-\u{1FFFF}]" src/pages/index.tsx 'src/pages/(app)/landing.tsx' src/components/landing/` if `grep -P` is unavailable.
grep -rnP "[\x{1F000}-\x{1FFFF}]" --include="*.tsx" src/pages/index.tsx 'src/pages/(app)/landing.tsx' src/components/landing/ 2>/dev/null

# ── Template placeholder copy + generic marketing phrases ────────────────────
grep -rniE "My App|Welcome to [Mm]y|[Ll]orem [Ii]psum|Your DeepSpace app is running" --include="*.tsx" src/pages/index.tsx 'src/pages/(app)/landing.tsx' src/components/landing/ 2>/dev/null
grep -rniE "streamline your|transform your|cutting.edge|state.of.the.art|next.generation|revolutionary|world.class|best.in.class|game.chang" --include="*.tsx" src/pages/index.tsx 'src/pages/(app)/landing.tsx' src/components/landing/ 2>/dev/null

# ── Unfilled TODOs ───────────────────────────────────────────────────────────
grep -rnE "TODO[: ]" --include="*.tsx" src/pages/index.tsx 'src/pages/(app)/landing.tsx' src/components/landing/ 2>/dev/null

# ── Illegal import from a read-only example composition ─────────────────────
grep -rn "from.*landing-design/examples" --include="*.tsx" src/ 2>/dev/null
```

**Any hit is a bug to fix before shipping.** The third block (continuous animations) is advisory rather than a hard failure — review each hit for a `useReducedMotion` gate rather than deleting the animation.

## The eyeball checklist

If the grep gate is clean but you're still unsure, run the eyeball checks:

* Design Direction block (prose, not placeholders) is present at the top of the landing page file
* Hero headline is 3–8 words
* Hero has a commanding visual (mockup, atmospheric background, signature element), not just centered text
* Features section is not 3 identical cards
* Every image slot is filled (a real `integration.post('freepik|openai|gemini/generate-image...')` URL, an uploaded R2 asset, or a code-based React visual)
* The page doesn't look like a generic purple-gradient SaaS landing page
* The scaffolded landing sections have been replaced or substantively rewritten — not shipped as-is

## The root-cause rule

If any eyeball check fails, the bug isn't in the grep gate — it's in the design. Go back to the [Design Direction block](/design/direction) and check: does the code actually serve the direction you wrote? Usually the answer is "the direction is too vague" or "I drifted from my own direction."
