UI/UX Kit
Design interfaces that look intentional and brand-specific — never templated — and
leave behind a single source of truth (DESIGN_SYSTEM.md) that keeps every future page
consistent. Works for every surface: marketing, dashboards, apps, stores, content/docs,
mobile, redesigns, and standalone design systems.
Follow the steps in order. Four are non-negotiable:
- Step 1 routing — apply the right rules, not one recipe.
- Step 2.7 concept — commit to one distinctive idea before building.
- Step 4.5 adversarial review — judge the work as a critic, not its author.
- Step 5 documentation — leave a
DESIGN_SYSTEM.md behind, always.
One law above all: read the brief and adapt. Every rule is the smart default, not a
reflex. When the brief contradicts a default, the brief wins — say so and proceed.
This file is the always-loaded core. Heavier detail lives in references/ and is loaded
on demand:
references/surface-rules.md — per-surface rules (landing, dashboard, app, mobile,
store, content). Load your Step 1 profile's section before building.
references/quality-floor.md — Step 3/4 depth: the contrast computation, gradients/
glass, icons, images, the full accessibility floor, the nine performance levers, and the
official-design-system table. Load it when you reach Step 3.
references/experiential.md — 3D/WebGL/physics tier. Load only if Step 2 picks it.
references/component-libraries.md — capability→library cheatsheet.
references/DESIGN_SYSTEM.template.md — the Step 5 deliverable template.
Step 1 — Analyze the request, then ROUTE (REQUIRED)
1a. Extract the brief
Identify: surface type (landing/marketing, dashboard/admin, app/product, mobile,
store, portfolio, redesign, design-system-only), brand, industry, audience,
design style, color system (map to 60/30/10), typography intent,
animation level, card/section style, image strategy, tech stack/platform.
If the user gave only colors + a name, infer the rest from industry and style — but list
your inferences so they can correct you.
1b. State a one-line Design Read
"Reading this as: a <surface> for <audience>, <style> direction,
<color/type/motion summary>, built in <stack>."
1c. Route to a surface profile (first match wins; note hybrids)
Match the profile, then immediately use the Read tool to open the listed
references/surface-rules.md section before building — its rules and per-surface gate
are required, not optional. A hybrid brief reads two sections.
| Profile |
Pick when |
→ Read now |
| Landing / Marketing |
landing, marketing, campaign, portfolio, long-form |
references/surface-rules.md §B1 — page anatomy + hero + conversion |
| Dashboard / Admin / Data |
dashboard, admin, analytics, console, internal tool |
references/surface-rules.md §B2 — density, tables, charts |
| App / Product UI |
web app, SaaS surface, settings, onboarding, flows |
references/surface-rules.md §B3 — navigation + forms + full state set |
| E-commerce / Store |
store, shop, catalog, PDP, cart, checkout |
references/surface-rules.md §B5 — listing, PDP, cart, checkout, trust |
| Content / Editorial / Docs |
blog, article, docs, KB, news, long reading |
references/surface-rules.md §B6 — reading measure, TOC, prose |
| Mobile / Native |
iOS, Android, React Native, Flutter |
references/surface-rules.md §B4 — HIG/Material, touch, safe areas |
| Redesign |
"redesign / improve / fix / clean up" existing UI |
Audit first (1d), then Read the matching profile's section |
| Design-system-only |
"create a design system / tokens / DESIGN_SYSTEM.md" |
Skip page building → Step 3 → 4 → 5; the artifact IS the deliverable |
1d. Redesign audit (Redesign profile only)
Before changing anything, read the existing code/UI and list (a) what works and must be
preserved (brand, palette, IA, components), (b) the concrete slop/quality issues scored
against Step 3 + the pre-flight gate, (c) the minimal set of changes that fixes the most.
Never overhaul what isn't broken. Seeing the current UI is part of auditing it — the
"don't open a browser unless asked" rule is about verification theater after building,
not this. You may render/screenshot the current state to ground the audit (say so);
if you can't, note the audit is code-only with reduced confidence.
1e. The category-reflex test (run before choosing colors/theme)
If someone could guess your palette from the domain alone — "fintech → navy + gold",
"healthcare → white + teal", "crypto → neon on black", "coffee → cream + brown", "AI
startup → purple gradient on dark" — that's the training reflex, not a decision. Rework
until the answer is no longer obvious from the category. The brief overrides only when it
explicitly names those colors.
Step 2 — Clarify only what's missing (REQUIRED)
Use what the user gave. Only ask for genuine gaps. Re-asking provided info is its own
failure.
- Inventory the prompt — mark each checklist item provided (even if loosely
phrased — "fintech startup", "brand blue #1A4FFF", "Next.js repo" all count) or
missing.
- Ask only missing items via
AskUserQuestion, batched ≤4 (usually ≤1 round, often
zero). If all provided, skip questions and restate the brief.
- Never re-ask, never override a named framework/palette/niche/library.
Checklist (ask each ONLY if missing):
- Niche / industry — drives mood + imagery.
- Tech stack / platform — adopt an existing project's stack without asking.
- Design direction — offer: Minimal, Modern, Editorial, Bold, Luxury, Brutalist,
Playful.
- Color scheme — don't assume. Propose 2–3 named palettes (with hex) or ask for
theirs. If given, map to 60/30/10 and move on.
- Animation level + library — None / Subtle / Smooth / Motion-rich, and GSAP /
Framer Motion / CSS-only.
- Image / asset strategy — AI-generated, stock, web, or user-provided.
- Experience tier — Standard (DOM + CSS/GSAP/Framer — the right default) or
Experiential (3D/WebGL/physics — only when the user wants an immersive experience
and the content justifies it; if picked, Read
references/experiential.md before
building the scene). Match the tier to the need — never force 3D, never flatten an
immersive brief.
Logo is a separate question (ask on its own only if unhandled): offer AI-generated /
niche web image / text wordmark, and tell the user up front to supply logos as SVG/PNG.
After answers, restate the full brief in one paragraph, then proceed.
Step 2.5 — AI asset generation (never silently bail)
When the user chooses AI-generated, produce real images — don't probe for an API key,
find none, and downgrade to a placeholder. Order:
/chatgpt-image-gen — PREFERRED, no API key. Drives the user's logged-in ChatGPT
via browser. If not logged in, tell them clearly ("A Chrome window is open — log in,
then tell me") and WAIT for confirmation. Non-interactive/headless runs (no one
to log in): skip straight to option 2, and if that's unavailable, scaffold with a
clearly-marked placeholder asset module and note it must be regenerated — never block a
headless run waiting on a login that can't happen.
/ai-image-generation (inference.sh) when INFERENCE_API_KEY is set or supplied;
if missing, ask or offer to switch to /chatgpt-image-gen.
For reference images before building, consider /imagegen-frontend-web (one per
section) or /imagegen-frontend-mobile. Fall back to a custom SVG/text mark only if the
user explicitly agrees. Keep generated assets isolated (one Logo component / assets
module) so they're swappable from one file.
Step 2.6 — Pull real design references (REQUIRED for non-trivial work)
Ground the design in proven award-winning work, not the model's averaged defaults — one
of the strongest anti-slop moves. Skip only if the user says "no research" or supplies
references.
If web access is unavailable: say so, then compensate — reason from named exemplars
("Linear's density / Stripe's restraint / Arc's playfulness") and lean harder on Step 2.7
and the category-reflex test. State that references were unavailable.
The style word is a first-class search driver. When the brief names a direction
(minimal, editorial, brutalist, luxury, bold, playful, modern, swiss…), run three
style-keyed searches and let them set the design before building:
- Reference designs of that style — "
<style> <surface> design awards".
- Color schemes for that style — "best palettes for
<style> <industry>" — then run
results through the category-reflex test before committing.
- Fonts for that style — "best fonts for
<style> <surface>" — confirm/sharpen the
Move A→C pick.
How: WebSearch the galleries, then WebFetch the top hits for concrete patterns.
Text-fetching image-heavy galleries (Awwwards, Dribbble) returns little visual signal
— for true visual grounding prefer a vision browse (/use-my-browser / /agent-browser
to screenshot) or named exemplars; use WebFetch mainly for structure, names, copy. For
login-gated sources use the browser skills with a live session. Deep sweep: /deep-research.
Sources: Landing/brand → Awwwards, Godly, Land-book, Lapa Ninja, Httpster, Refero.
App/dashboard → Mobbin, Page Flows, UI Sources, Refero. Mobile → Mobbin, Apple/Google
galleries. Mood → Dribbble, Behance, Cosmos, Savee.
Translate, never clone. Adapt every reference into the project's own tokens. Output a
short "References pulled" note: 3–5 links + the specific move adapted from each.
Step 2.7 — Commit to ONE design concept (REQUIRED)
Avoiding banned patterns still leaves clean-but-bland. The fix is positive: commit to a
single distinctive concept before building, and let it drive specific decisions.
Write it as one sentence — a concrete organizing idea, not an adjective:
"The concept is: <one specific idea> — expressed through <layout>, <type>,
<color>, <motion>."
- Weak: "modern, clean, professional fintech dashboard." (defaults, not a concept)
- Strong: "a trading terminal that feels like precision instrumentation — mono numerals
everywhere, hairline grid, near-black field with one signal-green accent, data animates
in like a ticker."
The concept must be falsifiable (if it could describe any competitor, sharpen it) and
show up in ≥3 of {layout, type, color, motion, imagery}. Record it as the design system's
"Design personality / concept." The adversarial review checks it landed.
Step 3 — Design with taste (the quality bar)
Shared laws below apply to every surface. Before building you must have Read both
your Step 1 profile's section in references/surface-rules.md and
references/quality-floor.md (contrast math, gradients/glass, icons, images, the full a11y
floor, the nine perf levers, the official-design-system table). Apply those on top of these
laws. If you haven't opened them yet, do it now.
Color — strategy first, then 60/30/10, in OKLCH
- Pick a strategy first: Restrained (tinted neutrals + one accent ≤10% — product/
dashboard default), Committed (one saturated color carries 30–60%), Full palette
(3–4 named roles), Drenched (the surface IS the color). The "≤10%" rule is
Restrained-only — don't collapse everything to it by reflex.
- 60/30/10: 60% dominant (backgrounds/large surfaces), 30% secondary (raised sections/
cards), 10% accent (buttons/links/focus rings).
- Work in OKLCH. Reduce chroma near L 0 or 100. Tint every neutral toward the brand
hue (chroma ~0.005–0.01) rather than using raw
#000/#fff — unless the concept
explicitly calls for pure ink (brutalist, hard-edged editorial, true-OLED black), in
which case pure #000/#fff is a deliberate, documented choice, not a default.
- One palette per project. No warm/cool drift; no surprise CTA color in section 7.
- Dark mode is derived, not inverted. Theme semantic tokens (
--bg, --surface,
--surface-raised, --text, --text-muted, --accent) — never flip raw hex. In dark:
tinted near-black (~L 0.15–0.20), raise surfaces by getting lighter (shadows barely
read), lower accent chroma / raise its lightness, and re-verify every text pair's
contrast independently.
Separation by depth first, not borders-by-reflex
- Background contrast + (hue-tinted) shadow is the primary way to separate and elevate
containers — not a border drawn around everything. A border is not banned outright; it
is the wrong default for elevation. Borders are legitimate and expected for: input/
control outlines that need a perceivable edge on a flat surface, thin token dividers in
dense data UIs, table cell/row rules, and
:focus-visible rings. Use them for those
jobs; don't use them as the go-to device for separating cards and sections.
- Never nest an elevated surface in another (no card-in-card-in-card).
- One depth hierarchy: page base → raised section → floating element.
- Elevation/selection state changes through background color, not by toggling a
decorative border on and off.
Text contrast (enforce — never ship gray-on-white body)
- Body/supporting text meets WCAG AA (≥4.5:1); large text (≥24px or ≥19px bold) and
UI/graphical elements ≥3:1. Light-gray on near-white (e.g.
#9aa on #fff) is a fail.
- Verify by computing, not by eye, in light and dark separately — the linearization
formula and the OKLCH-Δ45 pre-check are in
references/quality-floor.md. Don't assert
"passes AA" without the number.
- Muted/secondary copy is still high-contrast — darken until it reads clearly.
Typography — choose fonts FOR THE BRAND, then lock one scale
Typography is the fastest way a design reads as generic. Never reuse the same fonts by
reflex. Choose in three moves:
Move A — name the personality (1–2 words): corporate-clean, editorial-luxury,
warm-human, bold-loud, playful/funky/cartoon, minimal-swiss, brutalist-technical,
elegant-fashion. There is always a personality — if the brief states none, infer one
from industry + audience. Inferring is what makes type read as chosen, not templated.
No-signal default = a neutral grotesque, never a serif. When the personality is
neutral/modern/corporate/minimal (the common "professional/clean/unstated" case), pick a
self-hostable grotesque sans from the Corporate-clean row below and say which and why
— rotate by sub-nuance (Geist, Hanken Grotesk, Mona Sans, Neue Montreal, Space Grotesk all
qualify) rather than reaching for the same one every time; mandating a single font is its
own reflex. Reach for a serif/display face only when the personality is explicitly
editorial-luxury, elegant-fashion, or heritage — a serif on a "modern minimal" brief is a
mis-inference and a fail.
Move B — map personality → category → pick a face (self-hostable / Google Fonts unless
the brand owns one). The personality→category→face lookup table is in
references/quality-floor.md — pick the row that fits this brief's nuance, and write
one line tying the face to the personality (if it'd read the same on any brief, you picked
by reflex).
Move C — pair with intent. Heading carries the personality; body stays quiet and
readable; both in the same emotional family. Max 2 families (+ optional mono). Emphasis =
italic/bold of the same family.
Anti-reflex (enforce): don't default to Inter; for a no-signal brief pick a grotesque
sans (never a serif) and justify the specific face; don't reach for serif just because the
brief says "creative/premium"; a playful/cartoon brand must NOT get a corporate grotesque.
- Define the type scale ONCE as tokens (
display, h1, h2, h3, body-lg,
body, body-sm, caption, button) and reference them everywhere — no inline
one-off sizes; same role = same size every section.
- Minimums: body never below 16px; captions ~13–14px; line-height ~1.5; line length
60–75ch.
- Responsive scaling is part of the scale — prefer fluid
clamp(); headings scale down
on mobile; never clip or truncate.
Components (build them reusable)
Buttons, cards, badges, navbar, footer, forms, inputs, feature/CTA sections — plus
feedback primitives (Toast, Spinner, Modal, Skeleton, empty/error state) — each defined
once and reused. Interactive states live inside the primitive. No one-off inline variants.
Select a component base by capability (see references/component-libraries.md); one
styled base per project, re-themed to your tokens — never a library's default look.
Interaction feedback & states (nothing static or silent)
- Every interactive element ships its full state set: default, hover,
focus (
:focus-visible, not :focus), active/pressed (visible — slight
scale-down + shadow shift, fires immediately), disabled.
- Focus ring uses
:focus-visible so it appears for keyboard/programmatic focus only and
stays hidden on mouse click. A ring that flashes on every mouse click reads as slop —
but the fix is :focus-visible, never outline:none or deleting the ring (that
fails WCAG 2.4.7 and locks out keyboard users). Many component libraries ship :focus
(mouse-visible) by default — re-map them to :focus-visible.
- Floating elements stay on-screen. Tooltips, dropdowns, popovers, menus, selects, and
date pickers must use collision-aware positioning — flip/shift to stay inside the
viewport, never overflow or get clipped at an edge. Use the Popover API /
anchor
positioning or a positioning engine (Floating UI, or Radix/Headless UI which bundle it);
never hand-position with a fixed offset that runs off-screen near the edges.
- Async actions show a loading state the moment they start (label → working verb +
spinner, or skeleton). Never freeze the UI unexplained.
- Resolve every action with explicit success/error (toast / inline / micro-feedback)
— paired with icon or label, never color alone.
- Forms: inline validation on blur (not keystroke), errors below the field, visible
required markers, helper text, label above input (never placeholder-as-label). Disable
submit only with a visible reason.
- Data views design three states: empty (helpful, branded), loading (skeleton/spinner),
error (recoverable + retry). Drive all from shared components + motion tokens.
Motion
- Consistent, purposeful; reuse the same durations/easings. Micro-interactions ~150–300ms;
ease-out entering, ease-in exiting; avoid linear. Animate only
transform/opacity.
- Motion must be motivated — communicates hierarchy, feedback, storytelling, or state.
If you can't name what it communicates in one sentence, drop it.
- Always support
prefers-reduced-motion — instant, content fully visible. Pointer
cursor on all interactive elements.
UX copy & content (write like a person, not a placeholder)
- Specific over generic. Headlines say what the thing does for this audience — not
"Elevate your workflow / Seamless solutions / Next-gen platform." If it fits any company
in the category, rewrite it.
- Verb-first CTAs: "Start the 14-day trial" > "Get started"; one label per intent.
- Real or honestly-marked mock data — never "Acme / John Doe / Lorem ipsum" shipped as
real; no invented fake-precise stats.
- Microcopy carries UX: empty states explain the next action; errors say what happened
- how to fix (never bare "Something went wrong"); loading buttons name the work.
Icons, images, gradients/glass, the full accessibility floor, and the
official-design-system honesty table now live in references/quality-floor.md — apply
them as part of this step.
Step 4 — Build (source-of-truth first, modular always)
- Tokens first. One tokens layer (CSS vars / theme / Tailwind config) for every color,
the type scale, spacing, radii, shadows, motion durations/easings. Nothing hardcodes a
value. Mirrors
DESIGN_SYSTEM.md exactly.
- Modular components, small files. Reusable primitives once, then compose pages. One
responsibility per file; split when a file grows. States live in the primitive.
- Use only approved colors + defined components; animate from shared motion tokens; use
matched imagery; make every page responsive (verify each section per breakpoint).
- Layer cleanly — primitives hold no business logic / no data fetching; feature modules
own data/state; shared logic lives in a common location, not cross-imported.
- Verify dependencies — check
package.json before importing; output the install
command if missing. Match the project's package manager (detect from lockfile; no
lockfile → pnpm).
- Experiential tier is code-split and isolated (see
references/experiential.md) — the
Standard page renders and is usable before and without the 3D layer.
Performance & delivery (production-ready means fast)
Target Core Web Vitals: LCP < 2.5s, CLS < 0.1, INP < 200ms. Apply all nine levers
— the full list is in references/quality-floor.md. In short: perceived speed, smaller
first load, critical-path-first CSS, ship less JS, lazy-load below-fold, protect the main
thread, stable layouts (CLS), optimized images, smart caching.
Engineering principles
- DRY / KISS / YAGNI — any value/logic appearing twice is declared once; simplest thing
that works; build only what's needed now.
- Code lazily (
/ponytail ladder): native HTML/CSS before a JS lib (<dialog>,
<details>, scroll-snap, :has() before a dependency); installed dep before a new one;
one line before fifty; fewest files. Mark deliberate shortcuts with a ponytail: comment.
If /ponytail is installed, invoke it for non-trivial components; if not, just follow the
ladder.
- Ponytail governs how you implement, not what the design requires. Never lazy away:
the token layer, reusable primitives, the full state set, empty/loading/error states,
accessibility, the adversarial review, or
DESIGN_SYSTEM.md. Be lazy on mechanism; never
on the design system itself.
Step 4.5 — Adversarial review (REQUIRED before documenting)
Judge as an adversary, not the author. Your goal this pass is to make the case that the
design is generic. Any "yes-it's-generic" is a finding to fix:
- Concept test. Cover the brand name — could this be any competitor? If yes, sharpen
and re-apply the Step 2.7 concept.
- Reflex test (1e), as attacker. Is the palette guessable from the category? Is the
type the familiar default? Assume yes; try to prove yourself wrong with specifics.
- Reference test. Name the specific premium move each section earns. Any section whose
honest answer is "the default AI layout" gets reworked.
- One real weakness. State the single weakest part out loud and fix it. A review that
finds nothing didn't review.
- Hero composition self-check (landing/marketing). Name out loud which composition the
hero uses — centered editorial / oversized-typographic / full-bleed / asymmetric-off-grid
/ split. If the answer is "split," write the one specific distinctive move that earns
it; if you can't, it's the reflex left-text/right-image template — rebuild it as a
non-split composition. Also confirm: hero vertically centered, no empty band above it, no
sparkle/AI-icon or vague-tagline eyebrow. (When no browser is available to screenshot,
this stated self-check is your last line of defense against the render-only hero slop.)
For high-stakes briefs, run this as a genuinely separate pass (fresh read or subagent).
Record the concept-test verdict in the design system, then run the countable gate.
Step 5 — Document in DESIGN_SYSTEM.md (REQUIRED)
After any full design or improvement, create DESIGN_SYSTEM.md at the project root
from references/DESIGN_SYSTEM.template.md, filling every section with the actual values
used (real hex/OKLCH, real fonts, real component specs) across all 14 sections. Record the
surface profile (Step 1) in section 1 so future work routes the same way. Then tell the
user, verbatim:
"Your project now includes a DESIGN_SYSTEM.md file. Use this file as the design guide
for future pages, sections, and components so the full website remains visually
consistent."
Pre-flight check — COUNTABLE anti-slop gate (the single source of truth)
Anti-slop is counted. Any failure means not done. This gate is the canonical list —
DESIGN_SYSTEM.template.md §12 points back here rather than restating it, so there is one
list to maintain. Run the universal gate below, plus your profile's gate at the end of its
references/surface-rules.md section.
Hard bans (any hit = fail)
- ❌ Any color outside the approved palette; default purple/blue-purple gradient (unless
approved); raw
#000/#fff used by default (pure ink is allowed only when the
concept explicitly calls for it — brutalist / hard editorial / true-OLED — and it's
documented).
- ❌ Lucide by default; mixed icon families; emojis as structural icons.
- ❌ Low-contrast text (any body/supporting pair <4.5:1, light OR dark).
- ❌ Body text below 16px; any inline one-off size not mapped to a scale step.
- ❌ Typography not matching personality (playful brand on corporate grotesque; editorial on
generic sans; a serif as the no-signal default where a grotesque sans is correct); the
same pairing reused by reflex instead of chosen via Move A→C.
- ❌ Borders used as the primary device for separating/elevating cards and sections, or an
elevation/selection state changed by toggling a decorative border. (Input outlines, token
dividers, table rules, and focus rings are fine — they're not elevation.)
- ❌ Nested elevated surfaces (card-in-card-in-card).
- ❌ A static interactive element (missing hover/focus/active/disabled); a silent async
action (no loading + success/error); a blank empty/loading/error screen.
- ❌ Clipped hero text; truncated mobile text; any content clipped/overflowing at any
breakpoint — incl. a hero overflowing vertically at ~700–800px laptop height, or
top-aligned instead of centered, or an empty full-width band/gap above the hero
(a stray spacer or empty section pushing content down off-center).
- ❌ The left-text / right-image (or right-mockup/video) hero split is a FAIL by default
— it is the single most templated hero on the web. It counts as done only if you wrote
down the specific distinctive move that earns it (asymmetric ratio, image bleeds off the
edge, an overlap/depth or motion move) AND it lands. A plain 50/50 text-left + rounded
image-card-right is an automatic fail — pick another composition (centered editorial,
oversized-typographic, full-bleed, asymmetric/off-grid) instead.
- ❌ A decorative sparkle / ✨ / ✦ / magic-wand / "AI" star icon in an eyebrow, badge, or
pill (the "✨ AI-powered" tell); an eyebrow that's a vague tagline ("From colors to a
complete system") rather than a real section label/category. Eyebrows carry information,
not decoration.
- ❌ A focus ring that appears on mouse click (used
:focus instead of :focus-visible,
or shipped a library's mouse-visible default) — fix with :focus-visible, never by
removing the ring.
- ❌ A floating element (tooltip / dropdown / popover / menu / select / datepicker) that
overflows or is clipped at the viewport edge — must flip/shift to stay on-screen via
collision-aware positioning.
- ❌ A designed horizontal card row with a visible native scrollbar (incl. the phantom
vertical bar from
overflow-x:auto — set overflow-y:hidden + hide bars); raw
overflow-x with no snap/controls/smoothing; hard-cut edges with no mask-image fade; a
half-clipped card beside a scrollbar.
- ❌ Gradient text (
background-clip:text); decorative glass; side-stripe border-left/right
accents.
- ❌ Giant do-everything files.
- ❌ 3D forced onto a brief that didn't ask, or an immersive brief flattened; a WebGL scene
with no fallback / no mobile degrade / no reduced-motion static; copy baked into canvas;
heavy 3D/animation bundle in the critical path.
- ❌ Generic AI-SaaS layout pasted without adapting; palette guessable from the category;
a design that fails the concept test; generic filler copy.
- ❌ A library/registry component in its default theme (stock shadcn/Aceternity/Magic UI,
default gradients, demo copy); more than one styled component base in one project.
- ❌ A hand-rolled
div+onClick widget where an accessible primitive exists; or a whole
library pulled for what native HTML/CSS or an installed dep already does.
Countable limits
- Eyebrows (small uppercase tracked labels): ≤ ceil(sections ÷ 3), and each must be
a real label/category — no decorative sparkle/AI icon, no vague tagline as an eyebrow.
- Consecutive zigzag (alternating image+text rows): ≤ 2 in a row; the 3rd breaks the
pattern.
- One label per CTA intent across the whole page.
- One primary CTA style, reused; secondary quieter; CTA text one line (≤3 words primary).
- Marquee ≤ 1 per page. Theme: light/dark inversion must be a deliberate, repeated
system, never accidental drift; every text pair passes AA in both. Utility surfaces stay
single-theme per view.
- Layout-family repetition: a multi-section page uses ≥3 different section layout families.
- Fake-precise numbers / generic names / filler copy = 0 unless real or marked mock.
Performance gates
- ❌ Any image/media/embed without
width/height or aspect-ratio.
- ❌ Hero/LCP image not prioritized; below-fold images/components not lazy.
- ❌ Animating any property other than
transform/opacity.
- ❌ Web fonts without
display: swap; render-blocking non-critical CSS/JS on the critical
path.
- ❌ A heavy/3D bundle on the initial path; continuous scroll/mouse driven through component
state.
- ✅ All nine levers applied. The CWV numbers are the goal those levers serve — state them
as "targeted via the levers"; report a number only if you actually measured it.
Verify before done
- Typecheck. Run the project's typecheck (
<pm> run typecheck, or <pm> exec tsc --noEmit, or the lint command) using the detected package manager. Don't run a
production build just to find errors.
- Compute, don't eyeball, the things that are computable. Run the contrast ratios in a
one-off script (formula in
references/quality-floor.md). This is required, not optional.
- Render-verify the things that are only observable after layout — this is not
verification theater, it is the only way to confirm them. The gate asserts several
rendered outcomes that cannot be read from source: the hero fits inside
100svh at
~700px and ~800px laptop heights, nothing clips/overflows at 375/768/1280 widths, and a
horizontal rail shows no phantom scrollbar. For those specific items, take a quick
headless screenshot at those viewports (/use-my-browser, /agent-browser, or
Playwright) and confirm — or, if you genuinely cannot render, say so explicitly and
downgrade the claim from "verified" to "built to target, not visually confirmed." Do not
assert a render-only gate item passes without having looked. (This is the one sanctioned
exception to "don't open a browser to verify"; the rule still bans decorative
after-the-fact screenshotting of things you already know from the code.)
- Adversarial review (4.5) + the countable gate, one final time, before declaring
complete.
Future work & updates
Every future page reuses the colors, typography, spacing, components, icons, cards,
animation, and image style from DESIGN_SYSTEM.md — no new visual style unless the user
updates it. If anything changes, update DESIGN_SYSTEM.md immediately so it never drifts.
1---2name: ui-ux-kit3description: Design and improve ANY web or app interface with a taste-first, anti-AI-slop workflow, then document the result in a project DESIGN_SYSTEM.md so every future page stays visually consistent. Universal: routes the brief to the right rules for a landing/marketing page, dashboard/admin, product/app UI, e-commerce/store, content/editorial/docs, mobile/native app, a redesign, or a design-system-only task. The engine is web-first (CSS/tokens/Tailwind); for iOS/Android it layers platform-idiom guidance over that engine and defers deep platform-component work to HIG/Material. Use when the user asks to design, build, redesign, audit, or polish any interface — especially when they mention a brand name, color palette, mood/style, fonts, animations, card style, image source, framework, or platform (web / iOS / Android). Triggers: "design a landing page", "build a dashboard", "design a mobile app", "build a store / product page / checkout", "design a docs or blog site", "redesign this", "make the UI look premium", "create 4---56# UI/UX Kit78Design interfaces that look intentional and brand-specific — never templated — and9leave behind a single source of truth (`DESIGN_SYSTEM.md`) that keeps every future page10consistent. Works for every surface: marketing, dashboards, apps, stores, content/docs,11mobile, redesigns, and standalone design systems.1213Follow the steps in order. Four are non-negotiable:14- **Step 1 routing** — apply the *right* rules, not one recipe.15- **Step 2.7 concept** — commit to one distinctive idea before building.16- **Step 4.5 adversarial review** — judge the work as a critic, not its author.17- **Step 5 documentation** — leave a `DESIGN_SYSTEM.md` behind, always.1819One law above all: **read the brief and adapt.** Every rule is the smart default, not a20reflex. When the brief contradicts a default, the brief wins — say so and proceed.2122This file is the always-loaded core. Heavier detail lives in `references/` and is loaded23on demand:24- **`references/surface-rules.md`** — per-surface rules (landing, dashboard, app, mobile,25 store, content). Load your Step 1 profile's section before building.26- **`references/quality-floor.md`** — Step 3/4 depth: the contrast computation, gradients/27 glass, icons, images, the full accessibility floor, the nine performance levers, and the28 official-design-system table. Load it when you reach Step 3.29- **`references/experiential.md`** — 3D/WebGL/physics tier. Load only if Step 2 picks it.30- **`references/component-libraries.md`** — capability→library cheatsheet.31- **`references/DESIGN_SYSTEM.template.md`** — the Step 5 deliverable template.3233---3435## Step 1 — Analyze the request, then ROUTE (REQUIRED)3637### 1a. Extract the brief38Identify: **surface type** (landing/marketing, dashboard/admin, app/product, mobile,39store, portfolio, redesign, design-system-only), **brand**, **industry**, **audience**,40**design style**, **color system** (map to 60/30/10), **typography intent**,41**animation level**, **card/section style**, **image strategy**, **tech stack/platform**.42If the user gave only colors + a name, infer the rest from industry and style — but list43your inferences so they can correct you.4445### 1b. State a one-line Design Read46> **"Reading this as: a `<surface>` for `<audience>`, `<style>` direction,47> `<color/type/motion summary>`, built in `<stack>`."**4849### 1c. Route to a surface profile (first match wins; note hybrids)5051Match the profile, then **immediately use the Read tool to open the listed52`references/surface-rules.md` section before building** — its rules and per-surface gate53are required, not optional. A hybrid brief reads two sections.5455| Profile | Pick when | → Read now |56|---|---|---|57| **Landing / Marketing** | landing, marketing, campaign, portfolio, long-form | `references/surface-rules.md` §B1 — page anatomy + hero + conversion |58| **Dashboard / Admin / Data** | dashboard, admin, analytics, console, internal tool | `references/surface-rules.md` §B2 — density, tables, charts |59| **App / Product UI** | web app, SaaS surface, settings, onboarding, flows | `references/surface-rules.md` §B3 — navigation + forms + full state set |60| **E-commerce / Store** | store, shop, catalog, PDP, cart, checkout | `references/surface-rules.md` §B5 — listing, PDP, cart, checkout, trust |61| **Content / Editorial / Docs** | blog, article, docs, KB, news, long reading | `references/surface-rules.md` §B6 — reading measure, TOC, prose |62| **Mobile / Native** | iOS, Android, React Native, Flutter | `references/surface-rules.md` §B4 — HIG/Material, touch, safe areas |63| **Redesign** | "redesign / improve / fix / clean up" existing UI | Audit first (1d), then Read the matching profile's section |64| **Design-system-only** | "create a design system / tokens / DESIGN_SYSTEM.md" | Skip page building → Step 3 → 4 → 5; the artifact IS the deliverable |6566### 1d. Redesign audit (Redesign profile only)67Before changing anything, read the existing code/UI and list (a) what works and must be68preserved (brand, palette, IA, components), (b) the concrete slop/quality issues scored69against Step 3 + the pre-flight gate, (c) the minimal set of changes that fixes the most.70Never overhaul what isn't broken. **Seeing the current UI is part of auditing it** — the71"don't open a browser unless asked" rule is about verification theater *after* building,72not this. You **may** render/screenshot the current state to ground the audit (say so);73if you can't, note the audit is code-only with reduced confidence.7475### 1e. The category-reflex test (run before choosing colors/theme)76If someone could guess your palette from the **domain alone** — "fintech → navy + gold",77"healthcare → white + teal", "crypto → neon on black", "coffee → cream + brown", "AI78startup → purple gradient on dark" — that's the training reflex, not a decision. Rework79until the answer is no longer obvious from the category. The brief overrides only when it80explicitly names those colors.8182---8384## Step 2 — Clarify only what's missing (REQUIRED)8586**Use what the user gave. Only ask for genuine gaps.** Re-asking provided info is its own87failure.88891. **Inventory the prompt** — mark each checklist item **provided** (even if loosely90 phrased — "fintech startup", "brand blue #1A4FFF", "Next.js repo" all count) or91 **missing**.922. **Ask only missing items** via `AskUserQuestion`, batched ≤4 (usually ≤1 round, often93 zero). If all provided, skip questions and restate the brief.943. **Never re-ask, never override** a named framework/palette/niche/library.9596**Checklist (ask each ONLY if missing):**971. **Niche / industry** — drives mood + imagery.982. **Tech stack / platform** — adopt an existing project's stack without asking.993. **Design direction** — offer: Minimal, Modern, Editorial, Bold, Luxury, Brutalist,100 Playful.1014. **Color scheme** — don't assume. Propose 2–3 named palettes (with hex) or ask for102 theirs. If given, map to 60/30/10 and move on.1035. **Animation level + library** — None / Subtle / Smooth / Motion-rich, **and** GSAP /104 Framer Motion / CSS-only.1056. **Image / asset strategy** — AI-generated, stock, web, or user-provided.1067. **Experience tier** — **Standard** (DOM + CSS/GSAP/Framer — the right default) or107 **Experiential** (3D/WebGL/physics — only when the user wants an immersive experience108 and the content justifies it; if picked, **Read `references/experiential.md` before109 building the scene**). Match the tier to the need — never force 3D, never flatten an110 immersive brief.111112**Logo is a separate question** (ask on its own only if unhandled): offer AI-generated /113niche web image / text wordmark, and tell the user up front to supply logos as SVG/PNG.114115After answers, restate the full brief in one paragraph, then proceed.116117---118119## Step 2.5 — AI asset generation (never silently bail)120121When the user chooses **AI-generated**, produce real images — don't probe for an API key,122find none, and downgrade to a placeholder. Order:1231. **`/chatgpt-image-gen` — PREFERRED, no API key.** Drives the user's logged-in ChatGPT124 via browser. If not logged in, tell them clearly ("A Chrome window is open — log in,125 then tell me") and **WAIT** for confirmation. **Non-interactive/headless runs** (no one126 to log in): skip straight to option 2, and if that's unavailable, scaffold with a127 clearly-marked placeholder asset module and note it must be regenerated — never block a128 headless run waiting on a login that can't happen.1292. **`/ai-image-generation`** (inference.sh) when `INFERENCE_API_KEY` is set or supplied;130 if missing, ask or offer to switch to `/chatgpt-image-gen`.131132For *reference* images before building, consider `/imagegen-frontend-web` (one per133section) or `/imagegen-frontend-mobile`. Fall back to a custom SVG/text mark only if the134user explicitly agrees. Keep generated assets isolated (one `Logo` component / assets135module) so they're swappable from one file.136137---138139## Step 2.6 — Pull real design references (REQUIRED for non-trivial work)140141Ground the design in proven award-winning work, not the model's averaged defaults — one142of the strongest anti-slop moves. Skip only if the user says "no research" or supplies143references.144145**If web access is unavailable:** say so, then compensate — reason from named exemplars146("Linear's density / Stripe's restraint / Arc's playfulness") and lean harder on Step 2.7147and the category-reflex test. State that references were unavailable.148149**The style word is a first-class search driver.** When the brief names a direction150(minimal, editorial, brutalist, luxury, bold, playful, modern, swiss…), run **three**151style-keyed searches and let them set the design before building:152- **Reference designs of that style** — "`<style>` `<surface>` design awards".153- **Color schemes for that style** — "best palettes for `<style>` `<industry>`" — then run154 results through the category-reflex test before committing.155- **Fonts for that style** — "best fonts for `<style>` `<surface>`" — confirm/sharpen the156 Move A→C pick.157158**How:** WebSearch the galleries, then WebFetch the top hits for concrete patterns.159**Text-fetching image-heavy galleries (Awwwards, Dribbble) returns little visual signal**160— for true visual grounding prefer a vision browse (`/use-my-browser` / `/agent-browser`161to screenshot) or named exemplars; use `WebFetch` mainly for structure, names, copy. For162login-gated sources use the browser skills with a live session. Deep sweep: `/deep-research`.163164**Sources:** Landing/brand → Awwwards, Godly, Land-book, Lapa Ninja, Httpster, Refero.165App/dashboard → Mobbin, Page Flows, UI Sources, Refero. Mobile → Mobbin, Apple/Google166galleries. Mood → Dribbble, Behance, Cosmos, Savee.167168**Translate, never clone.** Adapt every reference into the project's own tokens. Output a169short "References pulled" note: 3–5 links + the specific move adapted from each.170171---172173## Step 2.7 — Commit to ONE design concept (REQUIRED)174175Avoiding banned patterns still leaves clean-but-bland. The fix is positive: commit to a176single distinctive concept before building, and let it drive specific decisions.177178Write it as one sentence — a concrete organizing idea, not an adjective:179> **"The concept is: `<one specific idea>` — expressed through `<layout>`, `<type>`,180> `<color>`, `<motion>`."**181182- *Weak:* "modern, clean, professional fintech dashboard." (defaults, not a concept)183- *Strong:* "a trading terminal that feels like precision instrumentation — mono numerals184 everywhere, hairline grid, near-black field with one signal-green accent, data animates185 in like a ticker."186187The concept must be **falsifiable** (if it could describe any competitor, sharpen it) and188show up in ≥3 of {layout, type, color, motion, imagery}. Record it as the design system's189"Design personality / concept." The adversarial review checks it landed.190191---192193## Step 3 — Design with taste (the quality bar)194195**Shared laws below apply to every surface.** Before building you must have **Read** both196your Step 1 profile's section in `references/surface-rules.md` **and**197`references/quality-floor.md` (contrast math, gradients/glass, icons, images, the full a11y198floor, the nine perf levers, the official-design-system table). Apply those on top of these199laws. If you haven't opened them yet, do it now.200201### Color — strategy first, then 60/30/10, in OKLCH202- **Pick a strategy first:** **Restrained** (tinted neutrals + one accent ≤10% — product/203 dashboard default), **Committed** (one saturated color carries 30–60%), **Full palette**204 (3–4 named roles), **Drenched** (the surface IS the color). The "≤10%" rule is205 Restrained-only — don't collapse everything to it by reflex.206- **60/30/10:** 60% dominant (backgrounds/large surfaces), 30% secondary (raised sections/207 cards), 10% accent (buttons/links/focus rings).208- **Work in OKLCH.** Reduce chroma near L 0 or 100. **Tint every neutral toward the brand209 hue** (chroma ~0.005–0.01) rather than using raw `#000`/`#fff` — *unless the concept210 explicitly calls for pure ink* (brutalist, hard-edged editorial, true-OLED black), in211 which case pure `#000`/`#fff` is a deliberate, documented choice, not a default.212- **One palette per project.** No warm/cool drift; no surprise CTA color in section 7.213- **Dark mode is derived, not inverted.** Theme semantic tokens (`--bg`, `--surface`,214 `--surface-raised`, `--text`, `--text-muted`, `--accent`) — never flip raw hex. In dark:215 tinted near-black (~L 0.15–0.20), **raise surfaces by getting lighter** (shadows barely216 read), **lower accent chroma / raise its lightness**, and re-verify every text pair's217 contrast independently.218219### Separation by depth first, not borders-by-reflex220- **Background contrast + (hue-tinted) shadow is the *primary* way to separate and elevate221 containers — not a border drawn around everything.** A border is not banned outright; it222 is the wrong *default* for elevation. Borders are legitimate and expected for: input/223 control outlines that need a perceivable edge on a flat surface, thin token dividers in224 dense data UIs, table cell/row rules, and `:focus-visible` rings. Use them for those225 jobs; don't use them as the go-to device for separating cards and sections.226- Never nest an elevated surface in another (no card-in-card-in-card).227- One depth hierarchy: **page base → raised section → floating element.**228- **Elevation/selection state changes through background color**, not by toggling a229 decorative border on and off.230231### Text contrast (enforce — never ship gray-on-white body)232- **Body/supporting text meets WCAG AA (≥4.5:1)**; large text (≥24px or ≥19px bold) and233 UI/graphical elements ≥3:1. Light-gray on near-white (e.g. `#9aa` on `#fff`) is a fail.234- **Verify by computing, not by eye**, in light and dark separately — the linearization235 formula and the OKLCH-Δ45 pre-check are in `references/quality-floor.md`. Don't assert236 "passes AA" without the number.237- Muted/secondary copy is still high-contrast — darken until it reads clearly.238239### Typography — choose fonts FOR THE BRAND, then lock one scale240Typography is the fastest way a design reads as generic. **Never reuse the same fonts by241reflex.** Choose in three moves:242243**Move A — name the personality** (1–2 words): corporate-clean, editorial-luxury,244warm-human, bold-loud, playful/funky/cartoon, minimal-swiss, brutalist-technical,245elegant-fashion. **There is always a personality** — if the brief states none, infer one246from industry + audience. Inferring is what makes type read as chosen, not templated.247248**No-signal default = a neutral grotesque, never a serif.** When the personality is249neutral/modern/corporate/minimal (the common "professional/clean/unstated" case), pick a250self-hostable grotesque sans from the Corporate-clean row below and **say which and why**251— rotate by sub-nuance (Geist, Hanken Grotesk, Mona Sans, Neue Montreal, Space Grotesk all252qualify) rather than reaching for the same one every time; mandating a single font is its253own reflex. Reach for a serif/display face only when the personality is *explicitly*254editorial-luxury, elegant-fashion, or heritage — a serif on a "modern minimal" brief is a255mis-inference and a fail.256257**Move B — map personality → category → pick a face** (self-hostable / Google Fonts unless258the brand owns one). The **personality→category→face lookup table is in259`references/quality-floor.md`** — pick the row that fits *this* brief's nuance, and write260one line tying the face to the personality (if it'd read the same on any brief, you picked261by reflex).262263**Move C — pair with intent.** Heading carries the personality; body stays quiet and264readable; both in the same emotional family. Max 2 families (+ optional mono). Emphasis =265italic/bold of the *same* family.266267**Anti-reflex (enforce):** don't default to Inter; for a no-signal brief pick a grotesque268sans (never a serif) and justify the specific face; don't reach for serif just because the269brief says "creative/premium"; a playful/cartoon brand must NOT get a corporate grotesque.270271- **Define the type scale ONCE as tokens** (`display`, `h1`, `h2`, `h3`, `body-lg`,272 `body`, `body-sm`, `caption`, `button`) and reference them everywhere — no inline273 one-off sizes; same role = same size every section.274- **Minimums:** body never below **16px**; captions ~13–14px; line-height ~1.5; line length275 60–75ch.276- **Responsive scaling is part of the scale** — prefer fluid `clamp()`; headings scale down277 on mobile; never clip or truncate.278279### Components (build them reusable)280Buttons, cards, badges, navbar, footer, forms, inputs, feature/CTA sections — plus281feedback primitives (Toast, Spinner, Modal, Skeleton, empty/error state) — each defined282once and reused. Interactive states live inside the primitive. No one-off inline variants.283Select a component base by capability (see `references/component-libraries.md`); **one284styled base per project**, re-themed to your tokens — never a library's default look.285286### Interaction feedback & states (nothing static or silent)287- **Every interactive element ships its full state set:** default, hover,288 **focus (`:focus-visible`, not `:focus`)**, **active/pressed** (visible — slight289 scale-down + shadow shift, fires immediately), disabled.290- **Focus ring uses `:focus-visible` so it appears for keyboard/programmatic focus only and291 stays hidden on mouse click.** A ring that flashes on every mouse click reads as slop —292 but the fix is `:focus-visible`, **never** `outline:none` or deleting the ring (that293 fails WCAG 2.4.7 and locks out keyboard users). Many component libraries ship `:focus`294 (mouse-visible) by default — re-map them to `:focus-visible`.295- **Floating elements stay on-screen.** Tooltips, dropdowns, popovers, menus, selects, and296 date pickers must use collision-aware positioning — flip/shift to stay inside the297 viewport, never overflow or get clipped at an edge. Use the Popover API / `anchor`298 positioning or a positioning engine (Floating UI, or Radix/Headless UI which bundle it);299 never hand-position with a fixed offset that runs off-screen near the edges.300- **Async actions** show a **loading state** the moment they start (label → working verb +301 spinner, or skeleton). Never freeze the UI unexplained.302- **Resolve every action** with explicit success/error (toast / inline / micro-feedback)303 — paired with icon or label, never color alone.304- **Forms:** inline validation on blur (not keystroke), errors below the field, visible305 required markers, helper text, label above input (never placeholder-as-label). Disable306 submit only with a visible reason.307- **Data views design three states:** empty (helpful, branded), loading (skeleton/spinner),308 error (recoverable + retry). Drive all from shared components + motion tokens.309310### Motion311- Consistent, purposeful; reuse the same durations/easings. Micro-interactions ~150–300ms;312 ease-out entering, ease-in exiting; avoid linear. Animate **only `transform`/`opacity`**.313- **Motion must be motivated** — communicates hierarchy, feedback, storytelling, or state.314 If you can't name what it communicates in one sentence, drop it.315- **Always support `prefers-reduced-motion`** — instant, content fully visible. Pointer316 cursor on all interactive elements.317318### UX copy & content (write like a person, not a placeholder)319- **Specific over generic.** Headlines say what the thing *does* for *this* audience — not320 "Elevate your workflow / Seamless solutions / Next-gen platform." If it fits any company321 in the category, rewrite it.322- **Verb-first CTAs:** "Start the 14-day trial" > "Get started"; one label per intent.323- **Real or honestly-marked mock data** — never "Acme / John Doe / Lorem ipsum" shipped as324 real; no invented fake-precise stats.325- **Microcopy carries UX:** empty states explain the next action; errors say what happened326 + how to fix (never bare "Something went wrong"); loading buttons name the work.327328> **Icons, images, gradients/glass, the full accessibility floor, and the329> official-design-system honesty table now live in `references/quality-floor.md` — apply330> them as part of this step.**331332---333334## Step 4 — Build (source-of-truth first, modular always)3353361. **Tokens first.** One tokens layer (CSS vars / theme / Tailwind config) for every color,337 the type scale, spacing, radii, shadows, motion durations/easings. **Nothing hardcodes a338 value.** Mirrors `DESIGN_SYSTEM.md` exactly.3392. **Modular components, small files.** Reusable primitives once, then compose pages. One340 responsibility per file; split when a file grows. States live in the primitive.3413. Use only approved colors + defined components; animate from shared motion tokens; use342 matched imagery; make every page responsive (verify each section per breakpoint).3434. **Layer cleanly** — primitives hold no business logic / no data fetching; feature modules344 own data/state; shared logic lives in a common location, not cross-imported.3455. **Verify dependencies** — check `package.json` before importing; output the install346 command if missing. Match the project's package manager (detect from lockfile; no347 lockfile → `pnpm`).3486. **Experiential tier is code-split and isolated** (see `references/experiential.md`) — the349 Standard page renders and is usable before and without the 3D layer.350351### Performance & delivery (production-ready means fast)352Target **Core Web Vitals: LCP < 2.5s, CLS < 0.1, INP < 200ms.** Apply all **nine levers**353— the full list is in `references/quality-floor.md`. In short: perceived speed, smaller354first load, critical-path-first CSS, ship less JS, lazy-load below-fold, protect the main355thread, stable layouts (CLS), optimized images, smart caching.356357### Engineering principles358- **DRY / KISS / YAGNI** — any value/logic appearing twice is declared once; simplest thing359 that works; build only what's needed now.360- **Code lazily (`/ponytail` ladder):** native HTML/CSS before a JS lib (`<dialog>`,361 `<details>`, scroll-snap, `:has()` before a dependency); installed dep before a new one;362 one line before fifty; fewest files. Mark deliberate shortcuts with a `ponytail:` comment.363 If `/ponytail` is installed, invoke it for non-trivial components; if not, just follow the364 ladder.365- **Ponytail governs *how you implement*, not *what the design requires*.** Never lazy away:366 the token layer, reusable primitives, the full state set, empty/loading/error states,367 accessibility, the adversarial review, or `DESIGN_SYSTEM.md`. Be lazy on mechanism; never368 on the design system itself.369370---371372## Step 4.5 — Adversarial review (REQUIRED before documenting)373374Judge as an adversary, not the author. **Your goal this pass is to make the case that the375design is generic.** Any "yes-it's-generic" is a finding to fix:3761. **Concept test.** Cover the brand name — could this be any competitor? If yes, sharpen377 and re-apply the Step 2.7 concept.3782. **Reflex test (1e), as attacker.** Is the palette guessable from the category? Is the379 type the familiar default? Assume yes; try to prove yourself wrong with specifics.3803. **Reference test.** Name the specific premium move each section earns. Any section whose381 honest answer is "the default AI layout" gets reworked.3824. **One real weakness.** State the single weakest part out loud and fix it. A review that383 finds nothing didn't review.3845. **Hero composition self-check (landing/marketing).** Name out loud which composition the385 hero uses — centered editorial / oversized-typographic / full-bleed / asymmetric-off-grid386 / split. **If the answer is "split,"** write the one specific distinctive move that earns387 it; if you can't, it's the reflex left-text/right-image template — rebuild it as a388 non-split composition. Also confirm: hero vertically centered, no empty band above it, no389 sparkle/AI-icon or vague-tagline eyebrow. (When no browser is available to screenshot,390 this stated self-check is your last line of defense against the render-only hero slop.)391392For high-stakes briefs, run this as a genuinely separate pass (fresh read or subagent).393Record the concept-test verdict in the design system, then run the countable gate.394395---396397## Step 5 — Document in DESIGN_SYSTEM.md (REQUIRED)398399After any full design **or** improvement, create `DESIGN_SYSTEM.md` at the project root400from `references/DESIGN_SYSTEM.template.md`, filling every section with the **actual values401used** (real hex/OKLCH, real fonts, real component specs) across all 14 sections. Record the402**surface profile** (Step 1) in section 1 so future work routes the same way. Then tell the403user, verbatim:404405> "Your project now includes a `DESIGN_SYSTEM.md` file. Use this file as the design guide406> for future pages, sections, and components so the full website remains visually407> consistent."408409---410411## Pre-flight check — COUNTABLE anti-slop gate (the single source of truth)412413Anti-slop is **counted**. Any failure means not done. This gate is the canonical list —414`DESIGN_SYSTEM.template.md` §12 points back here rather than restating it, so there is one415list to maintain. Run the universal gate below, plus your profile's gate at the end of its416`references/surface-rules.md` section.417418### Hard bans (any hit = fail)419- ❌ Any color outside the approved palette; default purple/blue-purple gradient (unless420 approved); raw `#000`/`#fff` **used by default** (pure ink is allowed only when the421 concept explicitly calls for it — brutalist / hard editorial / true-OLED — and it's422 documented).423- ❌ Lucide by default; mixed icon families; emojis as structural icons.424- ❌ Low-contrast text (any body/supporting pair <4.5:1, light OR dark).425- ❌ Body text below 16px; any inline one-off size not mapped to a scale step.426- ❌ Typography not matching personality (playful brand on corporate grotesque; editorial on427 generic sans; a serif as the no-signal default where a grotesque sans is correct); the428 same pairing reused by reflex instead of chosen via Move A→C.429- ❌ Borders used as the *primary* device for separating/elevating cards and sections, or an430 elevation/selection state changed by toggling a decorative border. (Input outlines, token431 dividers, table rules, and focus rings are fine — they're not elevation.)432- ❌ Nested elevated surfaces (card-in-card-in-card).433- ❌ A static interactive element (missing hover/focus/active/disabled); a silent async434 action (no loading + success/error); a blank empty/loading/error screen.435- ❌ Clipped hero text; truncated mobile text; any content clipped/overflowing at any436 breakpoint — incl. a hero overflowing vertically at ~700–800px laptop height, or437 top-aligned instead of centered, or an **empty full-width band/gap above the hero**438 (a stray spacer or empty section pushing content down off-center).439- ❌ **The left-text / right-image (or right-mockup/video) hero split is a FAIL by default**440 — it is the single most templated hero on the web. It counts as done *only* if you wrote441 down the specific distinctive move that earns it (asymmetric ratio, image bleeds off the442 edge, an overlap/depth or motion move) AND it lands. A plain 50/50 text-left + rounded443 image-card-right is an automatic fail — pick another composition (centered editorial,444 oversized-typographic, full-bleed, asymmetric/off-grid) instead.445- ❌ A **decorative sparkle / ✨ / ✦ / magic-wand / "AI" star icon** in an eyebrow, badge, or446 pill (the "✨ AI-powered" tell); an eyebrow that's a vague tagline ("From colors to a447 complete system") rather than a real section label/category. Eyebrows carry information,448 not decoration.449- ❌ A focus ring that appears on **mouse click** (used `:focus` instead of `:focus-visible`,450 or shipped a library's mouse-visible default) — fix with `:focus-visible`, never by451 removing the ring.452- ❌ A floating element (tooltip / dropdown / popover / menu / select / datepicker) that453 **overflows or is clipped at the viewport edge** — must flip/shift to stay on-screen via454 collision-aware positioning.455- ❌ A designed horizontal card row with a visible native scrollbar (incl. the phantom456 vertical bar from `overflow-x:auto` — set `overflow-y:hidden` + hide bars); raw457 `overflow-x` with no snap/controls/smoothing; hard-cut edges with no `mask-image` fade; a458 half-clipped card beside a scrollbar.459- ❌ Gradient text (`background-clip:text`); decorative glass; side-stripe `border-left/right`460 accents.461- ❌ Giant do-everything files.462- ❌ 3D forced onto a brief that didn't ask, or an immersive brief flattened; a WebGL scene463 with no fallback / no mobile degrade / no reduced-motion static; copy baked into canvas;464 heavy 3D/animation bundle in the critical path.465- ❌ Generic AI-SaaS layout pasted without adapting; palette guessable from the category;466 a design that fails the concept test; generic filler copy.467- ❌ A library/registry component in its **default theme** (stock shadcn/Aceternity/Magic UI,468 default gradients, demo copy); more than one styled component base in one project.469- ❌ A hand-rolled `div`+onClick widget where an accessible primitive exists; or a whole470 library pulled for what native HTML/CSS or an installed dep already does.471472### Countable limits473- **Eyebrows** (small uppercase tracked labels): **≤ ceil(sections ÷ 3)**, and each must be474 a real label/category — no decorative sparkle/AI icon, no vague tagline as an eyebrow.475- **Consecutive zigzag** (alternating image+text rows): **≤ 2 in a row**; the 3rd breaks the476 pattern.477- **One label per CTA intent** across the whole page.478- **One primary CTA style**, reused; secondary quieter; CTA text one line (≤3 words primary).479- **Marquee ≤ 1 per page.** **Theme:** light/dark inversion must be a deliberate, repeated480 system, never accidental drift; every text pair passes AA in both. Utility surfaces stay481 single-theme per view.482- **Layout-family repetition:** a multi-section page uses ≥3 different section layout families.483- **Fake-precise numbers / generic names / filler copy** = 0 unless real or marked mock.484485### Performance gates486- ❌ Any image/media/embed without `width`/`height` or `aspect-ratio`.487- ❌ Hero/LCP image not prioritized; below-fold images/components not lazy.488- ❌ Animating any property other than `transform`/`opacity`.489- ❌ Web fonts without `display: swap`; render-blocking non-critical CSS/JS on the critical490 path.491- ❌ A heavy/3D bundle on the initial path; continuous scroll/mouse driven through component492 state.493- ✅ **All nine levers applied.** The CWV numbers are the goal those levers serve — state them494 as "targeted via the levers"; report a number only if you actually measured it.495496---497498## Verify before done4995001. **Typecheck.** Run the project's typecheck (`<pm> run typecheck`, or `<pm> exec tsc501 --noEmit`, or the lint command) using the detected package manager. Don't run a502 production build just to find errors.5032. **Compute, don't eyeball, the things that are computable.** Run the contrast ratios in a504 one-off script (formula in `references/quality-floor.md`). This is required, not optional.5053. **Render-verify the things that are *only* observable after layout — this is not506 verification theater, it is the only way to confirm them.** The gate asserts several507 *rendered* outcomes that cannot be read from source: the hero fits inside `100svh` at508 ~700px and ~800px laptop heights, nothing clips/overflows at 375/768/1280 widths, and a509 horizontal rail shows no phantom scrollbar. For those specific items, **take a quick510 headless screenshot at those viewports** (`/use-my-browser`, `/agent-browser`, or511 Playwright) and confirm — *or*, if you genuinely cannot render, say so explicitly and512 downgrade the claim from "verified" to "built to target, not visually confirmed." Do not513 assert a render-only gate item passes without having looked. (This is the one sanctioned514 exception to "don't open a browser to verify"; the rule still bans decorative515 after-the-fact screenshotting of things you already know from the code.)5164. **Adversarial review (4.5) + the countable gate**, one final time, before declaring517 complete.518519## Future work & updates520Every future page reuses the colors, typography, spacing, components, icons, cards,521animation, and image style from `DESIGN_SYSTEM.md` — no new visual style unless the user522updates it. If anything changes, update `DESIGN_SYSTEM.md` immediately so it never drifts.