Design Range
Left to its defaults, Claude designs every product the same way: Inter or Geist, an indigo/violet gradient, a centered hero with two buttons, three feature cards with icons in tinted circles, rounded-2xl everything, soft gray shadows. It looks fine, and it looks like every other AI-made site. This skill exists to break that pattern on purpose.
The core move is simple: don't pick the style yourself, roll it. A model asked to "choose a style" lands on the same few choices every time, so the choice is handed to a script that samples from a library of coherent directions and steers away from whatever this project used recently. Your job is to then commit to that direction fully and execute it with craft.
Workflow
1. Read the situation
- What's being built? Map it to one product type:
marketing(landing pages, sites, portfolios count here too if you prefer),saas(app screens people work in),dashboard(analytics, admin, monitoring),ecommerce(stores, product and category pages),mobile(native or mobile-first app screens),portfolio. - Is there an existing brand or design system? If the project already has established tokens, a
design-direction.md, or the user is asking for a feature inside an existing app, keep its direction. Variety is for new projects, redesigns, and when the user asks for something different. Consistency within one product is a feature; sameness across products is the bug. - Did the user name a vibe? ("luxurious", "playful", "dark and techy"). Translate that into filters (
--energy,--mode) or a specific--show <id>, but still show alternatives unless they were specific. - Taste file. If
references/taste.mdhas content, read it. It holds the user's personal loves and hates and overrides the library when they conflict. Itsexclude:andfavor:lines are applied by the roll script automatically; the rest (favorite fonts, colors, moves they loved) is for you to carry into whichever direction gets built.
2. Roll directions
python3 <skill-dir>/scripts/roll.py --product <type> [--count 3] [--mode light|dark] [--energy quiet|medium|loud]
Run it from the project root. It reads two histories, the project's .design-history.json and a shared ~/.claude/design-range-history.json covering every project, and steers away from both, so the next product doesn't get the same look as the last one. It also spreads accent colors: each option's palette is chosen so its accent hue sits far from the other options and from recently used accents, which keeps "variety" from collapsing into one color family in different fonts. It prints 3 contrasting options, each a complete brief: mood, fonts with ready CSS URLs, a named palette, a layout archetype, shape language, motion, signature moves, things to avoid, and a Tailwind v4 @theme block.
Other commands: --list (all directions), --show <id> --product <type> (one direction in full, optionally --font N --palette N --layout <id>).
3. Let the user choose (when they're around)
Present the options compactly, one short block each: name, one-line mood, the font pair, the palette as hex values, the layout idea. Ask which one, and mention they can mix ("option 2's fonts with option 3's palette") or reroll.
If the user said "just build it", or you're running without a human in the loop, choose for them, and choose for fit. Randomness is there to break your habits, not to put a nightclub aesthetic on a dinner planner. For each option ask: would this brand's customers recognize themselves in it? Does the mood suit what the product does (calm for wellness and money, energetic for sport and nightlife, precise for data, warm for food and home)? Pick the option that fits best. If none fits, reroll once (--count 4, or filter with --energy/--mode) and pick from the new set. A surprising choice is good when you can say in one sentence why it suits the product; say that sentence when you report which direction you used. Don't stall the build waiting on a choice nobody will make.
4. Record it and write a direction file
python3 <skill-dir>/scripts/roll.py --record <id> --font N --palette N --layout <layout-id> --product <type>
This writes both the project and the shared history. Then save the chosen brief as design-direction.md in the project root. Future sessions (and you, in an hour) read it to stay consistent inside this product, and the shared history keeps the next product from getting the same look.
5. Build it
Read the matching platform reference before building, because each product type has its own craft rules:
| Product | Read |
|---|---|
| marketing, portfolio | references/marketing.md |
| saas | references/saas.md |
| dashboard | references/dashboard.md |
| ecommerce | references/ecommerce.md |
| mobile | references/mobile.md |
Stack: React + Tailwind by default (see "Stack setup" below). Then:
-
Wire the tokens first. Load the fonts, paste the
@themeblock, and style with the semantic names (bg-bg,bg-surface,text-text,text-muted,border-border,bg-accent,font-display). The script has already checked contrast: usetext-accent-inkwhenever accent-colored text sits on bg or surface (it equals the accent when the accent is already readable), andtext-on-accentfor labels on accent-filled buttons and badges. If the brief shows a Contrast line, it tells you what was adjusted. Raw Tailwind palette classes likeindigo-500orslate-100are how the default look leaks back in, so keep them out of components. -
Commit to the direction. Use at least two of its signature moves visibly, and treat the "avoid" list as hard constraints. A direction applied timidly (correct fonts, default everything else) collapses back into the generic look. If the brief says radius 0, nothing is rounded. If it says hard offset shadows, there are no blurry ones.
-
Let the layout archetype shape the page. The rolled layout (e.g.
sticky-scroll-story,three-pane,hub-and-sheet) is there to break the centered-hero + three-cards skeleton. Build around it. -
Extend the palette, don't replace it. You'll need hover, active, and subtle tints. Derive them from the given colors (
color-mix(in oklch, var(--color-accent) 85%, black), or opacity modifiers likebg-accent/10) rather than reaching for new hues. -
Real content. Write plausible, specific copy for the product. Lorem ipsum and "Feature One" hide whether the design actually works.
-
Make it move. Static pages feel like templates, and the user's taste file asks for motion in every build. Each build gets all four of these, expressed in the direction's own
motionpersonality (snappy for brutalist and sport, springy for toybox, slow and filmic for cinematic, gentle for organic, stepped for retro OS):- Entrance choreography on load: the hero's pieces arrive in a short staggered sequence (headline, then copy, then actions, 60-120ms apart), not all at once and not one slow fade.
- Hover and press feedback on everything clickable, in the direction's style: a hard-shadow press, a springy scale, an underline slide, a glow, a wobble.
- One signature animation taken from the brief's
motionorsignaturefields (shimmer, spinning glyph, morphing blob, Ken Burns, typewriter, marquee, rotating shapes). It's the moment people remember, so give it a visible place. - Scroll reveals for sections below the fold where they fit (IntersectionObserver or CSS
animation-timeline: view()with a fallback).
Animate
transformandopacityrather than layout properties so it stays smooth, keep UI feedback under ~300ms, and put everything decorative behind@media (prefers-reduced-motion: no-preference)(or switch it off underreduce) so people who turn motion off get a calm, complete page.
6. Sameness check before you finish
Look at what you built and fix any of these unless the direction explicitly calls for them:
- Inter, Roboto, Arial, or system-ui as the visible display font
- Purple/indigo/blue-to-violet gradient anywhere
- Centered hero, headline + subhead + two buttons, then a 3-up icon-card grid
- Every container
rounded-xl/2xlwithshadow-md/lg - Icons sitting in pastel-tinted circles
- Gray-50 page with white cards as the whole visual idea
- All text the same few sizes; no typographic contrast
- Gradient text on the headline (unless Y2K Chrome or Glass Aurora)
Then a quick craft pass: text contrast meets WCAG AA (4.5:1 body, 3:1 large text; adjust muted if a palette fails on its bg), every interactive element has hover, focus-visible and disabled states, it works at 375px wide, and animations respect prefers-reduced-motion.
Stack setup
Tailwind v4 (default): put the font <link>s in index.html (or next/font / @import url(...) at the top of the CSS), then the rolled @theme block in the main CSS file after @import "tailwindcss";. Classes like bg-accent, font-display, text-muted work automatically.
Tailwind v3: put the same values under theme.extend.colors and theme.extend.fontFamily in tailwind.config.js with the same names.
Next.js: prefer next/font/google for Google fonts (same names, underscores for spaces) and map them to the CSS variables. Fontshare fonts load through the CSS URL.
React Native / Expo (for mobile): use NativeWind with the palette in tailwind.config.js, and load fonts with @expo-google-fonts/<font-name> or expo-font. Fontshare fonts need the font files downloaded into assets/fonts. If the user just wants a visual mockup, a mobile-sized React web page (390x844 frame) is fine and much faster; ask if unclear.
Single-file previews: if there's no project yet and the user just wants to see it, a single HTML file with the Tailwind CDN (<script src="https://cdn.tailwindcss.com"></script> for v3 config, or @tailwindcss/browser@4 with an inline <style type="text/tailwindcss">@theme {...}</style>) plus React via ESM is acceptable.
When the user wants even more range
- Reroll: run the script again; it already avoids recent picks.
- Remix: take one direction's type with another's palette. Check the result still feels coherent (a pixel font with a luxury palette is a joke, which is fine only if that's the point).
- New direction: if the user describes a look the library doesn't have, add it to
assets/directions.jsonin the same shape so it joins future rolls. Check its fonts exist on Google Fonts or Fontshare. - Taste: when the user says what they love or hate ("never use serif", "I love brutalism"), offer to add it to
references/taste.mdso it applies every time.