frontend-design
Attaches itself automatically when a prompt matches.
Build premium, non-templated frontends for any website, landing page, marketing site, portfolio, dashboard, web app, page, UI, component, or layout. Read the brief, pick a deliberate design direction, and avoid generic AI-slop aesthetics. Covers typography, color, spacing, motion, hero design, and a pre-flight check.
Scaffolds
Source
Adapted from leonxlnx/taste-skill (MIT) + anthropics/skills, adapted for Codebase scaffolds
Instructions
The full instruction set the agent receives when this skill is active.
Frontend Design: Anti-Slop Interface Skill
Build interfaces that look deliberately designed, not generated. Every rule below is contextual: read the brief first, then pull only what fits. Match implementation effort to the vision (maximalism needs elaborate code; minimalism needs restraint and precision).
0. Read the brief before touching code
Most AI design output is bad because the model jumps to a default aesthetic. Before coding, infer:
- Page kind: landing (SaaS / consumer / agency), portfolio, marketing site, dashboard, editorial/blog, web app.
- Vibe words the user used: "minimalist", "Linear-style", "Awwwards", "brutalist", "premium", "Apple-y", "playful", "serious B2B", "editorial", "glassy", "dark tech".
- Audience: the audience picks the aesthetic, not your taste. B2B buyer vs design-conscious consumer vs recruiter scanning a portfolio.
- Existing brand: logo, color, type already in the project are starting material, not optional.
State a one-line Design Read before generating, e.g. "Reading this as: B2B SaaS landing for technical buyers, Linear-style minimalist, leaning neutral palette + restrained motion." If the read genuinely diverges, ask ONE clarifying question (use ask_user); if you can infer, declare the read and proceed.
Anti-default discipline. Do NOT reflexively reach for: AI-purple/blue gradients, centered hero over a dark mesh, three equal feature cards, glassmorphism on everything, infinite micro-animations, Inter + slate-900. These are the LLM defaults. Reach past them based on the read.
1. The three dials
After the read, set three dials. They gate every layout/motion/density decision. State them.
- VARIANCE (1 symmetric -> 10 chaotic): default 8
- MOTION (1 static -> 10 cinematic): default 6
- DENSITY (1 airy -> 10 packed): default 4
| Brief signal | VARIANCE | MOTION | DENSITY |
|---|---|---|---|
| minimalist / clean / editorial / Linear-style | 5-6 | 3-4 | 2-3 |
| premium consumer / Apple-y / luxury | 7-8 | 5-7 | 3-4 |
| playful / Awwwards / agency / experimental | 9-10 | 8-10 | 3-4 |
| landing / portfolio / marketing (default) | 7-9 | 6-8 | 3-5 |
| trust-first / public-sector / accessibility-critical | 3-4 | 2-3 | 4-5 |
| dashboard / data app | 4-5 | 2-4 | 6-8 |
2. Stack (Codebase scaffolds)
Work with what is installed. Check package.json before importing anything; output the install command first if a package is missing. Never assume a library exists.
- scaffold-react (Vite + React 18 + Tailwind v3.4): installed are
lucide-react,@radix-ui/react-icons,clsx,tailwind-merge,tailwindcss-animate.framer-motion/gsapare NOT installed:npm installthem before importing, or use CSS animations +tailwindcss-animate. - scaffold-next (Next + Tailwind v4): radix primitives +
framer-motionavailable. Use Server Components by default; any component using motion/scroll/pointer needs'use client'as an isolated leaf. - scaffold-vanilla: HTML/CSS/JS. CSS animations only.
Fonts (critical: the preview has NO outbound font network)
- scaffold-next: use
next/font/google(fetched at build, self-hosted into the bundle, renders in preview). Reach forGeist,Sora,Outfit,Space Grotesk,Plus Jakarta Sans, or a brand-appropriate face before Inter. - scaffold-react / vanilla: a runtime
<link>to Google Fonts will NOT load in the preview sandbox. Use a strong system stack (e.g.ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, Helvetica, Arial) or a locally bundled@font-facefile only.
Icons
Use @radix-ui/react-icons or lucide-react (both installed). Standardize strokeWidth globally (e.g. 1.5). One family per project. NEVER hand-roll SVG icon paths.
Images
You have a generate_image tool. USE IT for hero shots, section assets, texture backgrounds: generated files are written into the project and render in preview. External image URLs (picsum, unsplash) may be blocked by the preview's egress isolation, so prefer generate_image; if you must use an external URL, tell the user it may not render in preview. Never build div-based fake screenshots/dashboards to fake a product UI. A text + gradient-blob hero is a placeholder, not a hero.
Emoji
Do not use emoji in UI, markup, or visible text. Replace with icon-library glyphs. (Codebase house rule.)
3. Bias correction (override the AI defaults)
Typography
- Display:
text-4xl md:text-6xl tracking-tighter leading-none. Body:text-base text-gray-600 leading-relaxed max-w-[65ch]. - Inter is discouraged as default (acceptable for neutral/Linear-style or accessibility-first briefs). Pick a characterful sans first (see Fonts).
- Serif discipline: serif is very discouraged as a default. "Feels premium/editorial" is NOT a reason. Use it only for genuinely editorial / luxury / publication briefs with articulable justification.
FrauncesandInstrument Serifare banned as defaults (the two LLM-favorite serifs). - Emphasize a word in a headline with italic or bold of the same font, never by injecting a random serif word into a sans headline.
Color
- Max 1 accent. Saturation < 80% by default. Neutral base (Zinc/Slate/Stone) + one high-contrast accent.
- The Lila rule: the "AI purple/blue glow" is banned as a default. No automatic purple button glows or neon gradients. (Override: if the brand asks for purple, execute it with intent.)
- Color consistency lock: one accent, used identically across ALL sections. No blue CTA appearing in section 7 of a warm-grey site.
- Premium-consumer palette ban: for cookware/wellness/artisan/luxury briefs, the AI default is beige/cream + brass/clay/oxblood + espresso text. Banned as a default. Rotate to: cold-luxury silver-grey, deep-forest + bone + amber, black + tan, cobalt + cream, terracotta + slate, or monochrome + one saturated pop.
- Theme lock: ONE theme for the whole page. A dark page does not get a warm-paper section mid-scroll.
Layout
- Anti-center bias (when VARIANCE > 4): avoid the centered hero/H1. Use split-screen, left-content/right-asset, asymmetric whitespace, or scroll-pinned structures. (Centered is OK for editorial/manifesto briefs.)
- No 3 equal feature cards. The generic three-identical-cards row is banned. Use a 2-column zigzag, asymmetric bento, or horizontal scroll.
- Cards only when elevation communicates real hierarchy; otherwise group with
border-t,divide-y, or whitespace. Tint shadows to the background hue (no pure-black drop shadows on light backgrounds). - Shape consistency lock: pick ONE corner-radius scale and keep it. Round buttons on a square-card page is broken.
Interactive states (build full cycles, not just the happy path)
- Loading: skeletons matching final layout shape, not generic spinners.
- Empty / error: composed empty states; inline form errors below the input.
- Tactile feedback:
:active->-translate-y-[1px]orscale-[0.98]. - Button contrast check (a11y): every CTA text must be readable against its background (WCAG AA 4.5:1 body, 3:1 large). No white-on-white, no naked ghost buttons over photos (add a scrim/stroke).
- Form contrast check (a11y): inputs, placeholders, focus rings, labels all pass AA. Label ABOVE input. Never placeholder-as-label.
3b. Premium detailing (dependency-free CSS — the tell between generic and crafted)
These are pure CSS/Tailwind (no libraries, sandbox-safe). Reach for them instead of shadow-lg and a flat border — they are what makes a build look made. (Techniques adapted from MengTo/Skills, MIT © Meng To.)
- Layered shadows, never a single
shadow-lg. Real depth is a ramp of stacked shadows with increasing blur and decreasing opacity, plus a hairline ring:shadow-[0_0_0_1px_rgba(0,0,0,0.06),0_1px_1px_-0.5px_rgba(0,0,0,0.06),0_3px_3px_-1.5px_rgba(0,0,0,0.06),0_6px_6px_-3px_rgba(0,0,0,0.06),0_12px_12px_-6px_rgba(0,0,0,0.06),0_24px_24px_-12px_rgba(0,0,0,0.06)]. Dark mode: use aring-1 ring-white/10+ a soft ambient shadow, not black drop shadows. - Gradient border (crisp, no pseudo-element math): transparent border + double background clip:
border: 1px solid transparent; background: linear-gradient(var(--surface),var(--surface)) padding-box, linear-gradient(135deg, rgba(255,255,255,.34), rgba(125,92,255,.36), rgba(255,255,255,.08)) border-box; - Progressive (gradient) blur for sticky nav/hero edges — a
backdrop-filter: blur()layer masked with a linear gradient so it fades from clear to blurred instead of a hard band:backdrop-filter: blur(8px); mask: linear-gradient(to top, transparent, black 25%);(needs content behind it to blur). - Alpha edge-fade for marquees, logo rows, and overflow scrollers — fade the edges instead of a hard cut. Always include the
-webkit-twin for Safari:mask-image: linear-gradient(to right, transparent, black 12%, black 88%, transparent); -webkit-mask-image: …(same)… - Clip-path corner cuts (
clip-path: polygon(...)with a--cutvar) for a technical/engineered feel;tabular-nums(font-variant-numeric: tabular-nums) on any changing number, stat, price, or timer so digits don't jitter.
Rule: at most one or two of these per surface. They are seasoning — a page where everything glows, blurs, and has a gradient border is back to slop.
4. Layout discipline (hard rules: failing these ships broken work)
- Hero fits the viewport. Headline <= 2 lines, subtext <= 20 words AND <= 4 lines, CTA visible without scroll. A 4-line hero headline is a font-size error: plan font size and asset size together (
text-4xl md:text-5xl lg:text-6xldefault;text-6xl md:text-7xlonly for 3-5 word headlines). - Hero top padding max
pt-24at desktop. Hero stack: max 4 text elements (eyebrow OR brand strip / headline / subtext / CTAs). Trust micro-strips, taglines below CTAs, feature bullets, pricing teasers all move to sections BELOW the hero. - "Trusted by" logo wall lives UNDER the hero, never inside it. Use real SVG logos (Simple Icons CDN / generated marks), not plain text wordmarks. Logo wall = logos only, no category labels under them.
- Navigation renders on ONE line at desktop, height <= 80px.
- Eyebrow restraint (the #1 violated rule): an eyebrow is the small uppercase wide-tracking label above a headline. Max 1 eyebrow per 3 sections (hero counts as 1). Mechanical check: count
uppercase trackingmicro-labels; if count > ceil(sections / 3), cut some. Usually the headline alone is enough. - Zigzag cap: max 2 consecutive image+text-split sections. The 3rd is a fail; break with a full-width / bento / vertical-stack section.
- Section-layout-repetition ban: a layout family appears at most once. An 8-section page uses >= 4 different families.
- Bento background diversity: in any multi-cell grid, >= 2-3 cells need real visual variation (image, gradient, pattern), not all white-on-white text cards. Bento cell count == content count; no empty/blank tiles.
- Mobile collapse explicit per section. Declare the
< 768pxfallback in the same component. Usemin-h-[100dvh], neverh-screen, for full-height heroes. Prefer CSS Grid (grid-cols-1 md:grid-cols-3) over flex percentage math.
5. Content density
- Per section: short headline (<= 8 words) + short sub-paragraph (<= 25 words) + one asset OR one CTA. More must be justified.
- No data-dump sections. A 20-row spec table with a hairline under every row is the laziest layout. For > 5 items use grouped chunks, a card grid, tabs/accordion, or a carousel.
- No duplicate CTA intent. "Get in touch" + "Let's talk" + "Contact us" on one page = pick ONE label, use it everywhere (nav, hero, footer).
- Copy self-audit (before ship): re-read every visible string. Cut anything grammatically broken, AI-hallucinated cute wordplay, filler verbs ("Elevate", "Seamless", "Unleash", "Next-Gen"), generic names ("John Doe", "Acme"), or fake-precise invented numbers. Plain functional copy beats clever-but-wrong copy.
- Quotes/testimonials: max 3 lines of body, real attribution (name + role), real typographic quotes or none.
6. Motion
- Animate only
transformandopacity(GPU-safe). Nevertop/left/width/height.backdrop-bluronly on fixed/sticky elements, never scrolling containers. - Scroll reveal:
IntersectionObserveror framer-motionwhileInView, neverwindow.addEventListener('scroll'). - Motion must be motivated: each animation communicates hierarchy, storytelling, feedback, or state. If you cannot say what it communicates in one sentence, drop it.
- Motion claimed = motion shown: if MOTION > 4 the page must actually move (hero entry, scroll reveals, CTA hover). If you cannot ship working motion, drop MOTION to 3 and ship a clean static page rather than half-built broken motion.
- Respect
prefers-reduced-motion: gate every non-trivial animation. Max one horizontal marquee per page.
7. AI tells (banned unless the brief explicitly asks)
No neon/outer glows. No pure black (#000000): use off-black/zinc-950. No oversaturated accents. No custom mouse cursors. No version labels in the hero (V0.6, BETA, EARLY ACCESS). No section-number eyebrows (001 / Capabilities). No scroll cues ("Scroll to explore"). No decorative status dots on every nav item/row. No locale/weather/time strips ("Lisbon 14:23 18C"). No border-t + border-b on every row of a list. No div-based fake product UI. No <br>-broken italicized headlines as a default move.
Em-dash ban (the single most-violated tell)
The em-dash (—) and en-dash-as-separator (–) are completely banned in all generated, user-visible app copy: headlines, eyebrows, pills, body, quotes, attribution, captions, button text, alt text. Zero. Restructure with a period, comma, colon, parentheses, or line break. Date/number ranges use a hyphen (2018-2026, 40-80k). The only permitted dash in visible copy is the regular hyphen -.
8. Pre-flight check (run before declaring the build done)
Not optional. If any box fails, the work is not done:
- Design Read declared and dial values stated?
- ZERO em-dashes in any user-visible string?
- One theme, one accent color, one radius scale across the whole page?
- Every CTA and form field passes WCAG AA contrast? No CTA wraps to 2 lines at desktop?
- Hero fits the viewport (headline <= 2 lines, subtext <= 20 words, CTA above the fold, top padding <= pt-24, <= 4 stack elements)?
- Eyebrow count <= ceil(sections / 3)? No 3rd consecutive zigzag? >= 4 distinct layout families across the page?
- Real images used (generate_image), not div-fakes? Logo wall under the hero, logos only?
- No duplicate CTA intent? Copy self-audit done (no filler verbs, generic names, fake numbers, broken phrases)?
- Inter/serif used only where justified? Premium-consumer palette is not the beige+brass default?
- Navigation on one line, height <= 80px? Every multi-column section has an explicit
< 768pxfallback? - Motion respects
prefers-reduced-motionand is actually present if MOTION > 4?
Out of scope
This skill targets marketing/landing/portfolio/app surfaces. For dense data tables use a table library; for multi-step wizards use form patterns. If the brief is one of those, say so and apply only the parts that fit.