/audit
Final verifier before /deploy. Categories: anti-slop (what killed prior projects), technique (perf, a11y, SEO), contract (matches DESIGN-LOCK, brief, and the approved manifest).
When to use
- After
/build+/mobile(site assembled). - Before
/deploy(required gate). - Regularly during development for sanity checks.
Check categories
A. Anti-AI-slop (DESIGN-LOCK enforcement)
Walk HTML/CSS/JS. Each check = pass / fail with file/line.
- Emoji in HTML — grep
[\u{1F300}-\u{1F9FF}]in HTML. Fail if found (unless emoji is in the brand book). - More than one gradient — grep
linear-gradient|radial-gradient|conic-gradient. Fail if > 1 unique. - More than one radius — grep all
border-radius:. Everything must bevar(--radius). Fail on hardcode. - More than 2 font-weights — grep
font-weight:. Fail if > 2 unique values project-wide. - Center-align > 50% — count sections with
text-align: centervs total. Warning if > 50%. - More than 5 section types — count unique
<section class="sec sec-...">. Fail if > 5 (see DESIGN-LOCK §8). - Decorative icons — visually check: icons purely for decoration? Warning.
- Bounce/spring motion — grep
cubic-bezierfor out-of-range values (>1 or <0). Fail if found and not allowed in DESIGN-LOCK. - Mixed icon libraries — > 1 SVG sprite or > 1 icon font. Fail.
- Pill everywhere — if DESIGN-LOCK radius ≠ 999 but
border-radius: 999pxpresent — Fail.
A2. Typography (English print-quality rules)
- Hanging short words at line end — grep the rendered HTML for space-separated short words at potential line breaks. Specifically: scan each text node for space-terminated sequences ending in words from the
/typographycanonical short-word list (a,an,the,and,or,but,of,to,in,on,for,with,is,are,be,it,we,you, etc.). If the space is a regular space (not ) and the next word exists, this is a violation. Fail with line reference. - Dashes at line end — grep for
[-–—](space, dash, space). If the space before the dash is a regular space (not ), this is a violation. Fail. - Orphans in headings and paragraphs — for each
<h1>,<h2>,<h3>,<p>,<li>,<blockquote>, verify the last two words are joined by . Fail if a regular space separates the last two words of a text node. - Language contract — if
<html lang="en">is not set, and the copy is English, fail the language attribute check (also caught in D). Typography rules only apply to English. -
no-typoopt-outs — count elements withclass="no-typo". Warning if > 3 (user disabled typography on many blocks — worth reviewing).
B. Hardcode (tokens.css enforcement)
- Hex colors in CSS outside tokens.css — grep
#[0-9a-f]{3,8}insite/css/*.cssexcepttokens.css. Fail. - rgb/rgba in CSS outside tokens.css and outside
var(--c-overlay)— greprgba?\(. Fail on each. - Hardcoded px (except 1px border) — grep
\d+pxexcept1px solid. Fail. - Hardcoded ms/s — grep
\d+(ms|s)\bin CSS outside tokens. Fail. - Hardcoded cubic-bezier in CSS/JS outside tokens.css. Fail.
- Inline styles — grep
style="..."in HTML. Fail. - !important — grep. Fail (except
responsive.cssmobile parallax kill — allowed there).
C. Perf
- HTML size —
wc -c index.html— target ≤ 100KB post-build (without inline SVG). - Total CSS size — sum all CSS — target ≤ 50KB.
- Total JS size — target ≤ 50KB (excluding external analytics).
- Media sizes — every
.webpunder 500KB (special cases aside);.mp4under 3MB. - Preload on hero —
<link rel="preload" as="image" href="/media/hero.webp">in head. Fail if missing. - font-display: swap — on every @font-face. Fail.
- loading="lazy" on every img outside hero. Warning if missing.
- decoding="async" on every img. Warning if missing.
- Cache headers — vercel.json contains immutable for media. Fail if missing.
D. A11y
- Alt on every img — grep
<imgwithoutalt=. Fail per instance. - Aria-label on textless buttons — burger, close, prev/next carousel. Fail.
- Label on every input — not just placeholder. Fail.
- Contrast text/background — run WCAG formula; ≥ 4.5:1 (AA). Fail.
- Keyboard navigation — every interactive element reachable via Tab. Manual check.
- Focus visible — CSS
:focus-visibledefined. Warning if missing. - prefers-reduced-motion — @media rule present. Fail if missing and animations exist.
- Skip-link —
<a href="#main">Skip to content</a>first in body. Warning. - Lang attribute —
<html lang="en">or other. Fail if missing.
E. SEO
- Title — not "TBD", not empty, ≤ 60 chars. Fail.
- Meta description — not empty, 120–160 chars. Fail.
- OG tags — og:title, og:description, og:image, og:url. Fail on missing.
- OG image — 1200×630, ≤ 300KB. Fail.
- Twitter card —
<meta name="twitter:card" content="summary_large_image">. Warning. - Canonical —
<link rel="canonical" href="https://...">. Warning. - Robots — if /thank-you exists — must be noindex. Warning.
- Sitemap.xml — exists. Warning.
- One H1 per page — grep
<h1. Fail if > 1.
F. Security
- Vercel headers — X-Frame-Options, X-Content-Type-Options, Referrer-Policy set. Fail if missing.
- HTTPS-only links — grep
http://in HTML. Fail per instance (except localhost, mailto:, tel:). - External links rel — every
<a target="_blank">hasrel="noopener noreferrer". Fail. - No inline event handlers — grep
onclick=|onload=in HTML. Fail. - No secrets — grep
api_key|secret|password|token=in HTML/JS. Fail. - Secret storage documented — verify
site/_deploy-log.mdorbrief/06-technical.mdnames where sensitive keys live (Vercel env / GCP Secret Manager / other). Warning if undocumented.
G. Contract (matches brief)
- Every section from
brief/copy-analysis.md→ structure present? Fail on omission. - Every interactive block from
brief/07-interactive.md [x]implemented? Fail on omission. - CTA button matches
brief/03-goals.md? Fail. - Contacts in footer from
brief/01-business.md→ contacts? Fail. - Analytics IDs from
brief/06-technical.mdwired? Fail. - Privacy Policy page exists if applicable (see
brief/blocks/legal-privacy.md)? Fail.
H. Mobile
- Viewport meta present. Fail.
- Emulate 375×667, 390×844, 414×896 — visual smoke test. Warning on any breakage.
- Cache-bust
?v=Non every CSS/JS link. Fail. - Tap-target size ≥ 44px on every interactive. Fail.
-
site/_mobile-check-report.mdexists and its verdict is OK (produced by/mobileStep 7). Fail if missing or FAIL verdict.
I. References compliance (approved-manifest enforcement)
- Manifest exists —
references/approved-manifest.mdpresent. Fail if missing. - All items checked — every
[ ]in the manifest must be[x]by the end of/build. For each unchecked item, fail with a citation showing which reference source expected it. - Manifest not empty (advisory) — if the manifest has zero items even though
references/had files, warning: probably a/refsskip. - Removed items logged — any item that was in the manifest historically but is now absent must have a corresponding decision-log entry in
DESIGN.mdexplaining why. Fail on silent drops (compare against git history if available; otherwise warn).
Report format
site/_audit-report.md:
# Audit report — 2026-08-08 15:30
## Summary
- ✅ Passed: 56
- ⚠️ Warnings: 3
- ❌ Failed: 2
## ❌ Blocking fails (must fix before /deploy)
1. **B — Hardcoded hex** — site/css/hero.css:23 `#0A0A0A` not in tokens.css
2. **I — References compliance** — approved-manifest item unmet:
`[ ] motif: horizontal thin rule between sections ← ref: mood/aesop`
Expected in: sections separator layer. Not found.
## ⚠️ Warnings (non-blocking, discuss)
1. **A — Center-align** — 3 of 5 sections centered — risk of flatness. Keep?
2. **D — Focus visible** — :focus-visible not defined in CSS
3. **E — Sitemap.xml** — missing
## ✅ Passed
- 56 checks passed. Full list in _audit-full.md.
## Verdict
❌ /deploy blocked. Fix fails and rerun /audit.
Rules of behavior
- Do not "improve" found problems automatically. Report to user, let them decide.
- Fail = strict. Warning = soft.
- Always cite file/line. Without it, the user wastes time searching.
- Deep check once per project. Quick check for frequent runs — modified sections only.
What NOT to do
- Do not run
/deployif there are fails. - Do not rewrite code for the user (dev feedback loop).
- Do not skip a category — always run all of A through I.
Next
- Fix fails → rerun
/audit. - Everything pass →
/deploy.