| name | design-tailwind-shadcn |
| description | Styling for the build-capable SPA stacks (react-express, vue-fastapi): Tailwind CSS (+ shadcn/ui on React) themed per-run through CSS-variable design tokens. Invoke on these stacks to give each lab a distinctive, coherent, believable-product look that is different every run.
|
design-tailwind-shadcn skill
Applies to react-express and vue-fastapi — they have a real Node build, so
Tailwind (and, on React, the vendored shadcn/ui components) compile cleanly.
Goal: each generated lab should look like a real, polished product with a
genuinely different look every run — not the same default blue, not the same
layout, not generic AI slop.
Commit to ONE bold direction first (before coding)
Before writing any UI, pick one aesthetic direction and execute it with
intentionality. Bold maximalism and refined minimalism both win — the point is a
clear point-of-view, not intensity. Options (full token/font/texture recipes in
references/aesthetic-directions.md):
refined/luxury · brutally minimal · brutalist/raw · retro-futuristic ·
organic/natural · editorial/magazine · playful/toy · industrial/utilitarian ·
soft/pastel · art-deco/geometric · glassmorphism · claymorphism ·
dark academia · memphis/80s-pop · signal (deep-navy & gold)
Decide up front: light or dark, the dominant color + one sharp accent,
the radius scale, and a font pairing (display + body). Then translate
those decisions into the token block.
Never converge on the same choices across generations. Vary light/dark,
fonts, and direction every run. The fastest way to make labs feel distinct is to
change the direction, not just the hue.
How it's wired (already in the template — don't re-create)
- Tailwind + PostCSS configs ship in the frontend template;
index.css (React)
/ style.css (Vue) import Tailwind and define the token block.
- React ships a broad shadcn-style set in
src/components/ui/ and a cn()
helper: button, card, input(+Label), badge, table, alert,
select, textarea, separator, skeleton, avatar, tabs, dialog.
Build UI from these primitives; add any others (checkbox, dropdown-menu,
tooltip, …) by hand in the same pattern — see
references/adding-shadcn-components.md.
- Deps already installed:
class-variance-authority, clsx, tailwind-merge,
lucide-react. The build runs npm install only — no network, so
npx shadcn add is unavailable; vendor new components by hand.
Theme per-run via tokens (the only thing you edit to re-skin)
Edit only the :root { … } token block in the frontend's CSS. Every
component reads these, so one edit re-skins the whole app. Tokens are H S% L%
triplets (consumed via hsl(var(--token))):
--font-sans: …
--radius: 0.6rem;
--background --foreground --card --card-foreground
--primary --primary-foreground
--secondary --accent --muted --muted-foreground
--destructive --destructive-foreground
--border --input --ring
Vue's token set is smaller (no --secondary/--accent in its Tailwind
config). On Vue stick to primary, background, foreground, card,
muted, destructive, border, ring.
Also set the product BRAND constant in App.jsx / App.vue to an invented,
domain-appropriate name (not the spec's lab id).
Allowed creative edits, beyond the colors: a single web-font @import at the
top of the CSS file + an optional --font-display token; a .dark token block
for dark mode (React); and optional decorative tokens like --app-bg referenced
once on the app shell (see references/layout-recipes.md). Reach for atmosphere
(gradient mesh, grain, grid pattern, dramatic/offset shadows) instead of flat
fills.
Vary the composition, not just the color
Same data, different shape. Pick different hero/header, card-grid-vs-list,
stat-tile, form, and nav-shell treatments per run — copy-pasteable JSX in
references/layout-recipes.md. Do one orchestrated staggered page-load
reveal rather than scattered micro-interactions, plus a couple of tasteful hover
states.
Photos & imagery
Real photos make a lab read like a product. lucide-react covers icons; for
content-matched photos — product catalogs, article covers, profile/team
faces — invoke the arena-spawner:stock-images skill, which builds keyword-
matched, browser-loaded image URLs seeded by row id (so a coffee catalog shows
coffee, not random scenery). Plain picsum.photos/i.pravatar.cc seeds are for
subject-agnostic filler or avatars only; feed an avatar URL into the vendored
Avatar/AvatarImage with an AvatarFallback. Always set width/height (or an
aspect-[…] class) so layout doesn't shift, and a real alt — imagery layered
over the token-colored atmosphere, not decorative noise.
Decorative shapes must never block clicks. Squiggles, blobs, dots, zigzags,
confetti, gradient orbs — any purely-decorative absolutely-positioned element —
MUST carry both pointer-events-none and aria-hidden. An absolute shape with
a negative offset (e.g. -top-6) overflows its box and silently sits on top of
the nav or buttons beneath it, swallowing their clicks (a real, hard-to-spot bug).
Keep them behind content (-z-10 or a low z-) and non-interactive.
Per-domain starting point (then push it)
A nudge, not a cage — combine with a direction above:
- ecommerce / social / blog / creative / media → bolder: vivid
--primary,
larger --radius, a display/serif headline.
- banking / fintech / insurance / legal / gov → refined & trustworthy: deep
navy/green/ink
--primary, small --radius, clean sans.
- healthcare / wellness / education → soft/pastel or calm organic.
- devops / developer tools / analytics / infra → dense industrial, often
dark, mono accent for figures.
- hospitality / food / travel / events → warm, editorial or playful.
- Never ship the default palette unchanged — always a deliberate direction.
Anti-"AI slop" checklist (every run)
Pitfalls / guardrails
- Theme through the token block + brand + font ONLY — never inline hex or
per-component color overrides. Color always comes from a token-backed class
(
bg-primary, text-muted-foreground, border, rounded-lg); referencing a
token via style={{ background: 'var(--app-bg)' }} is fine, a literal hex is
not.
- Don't fight Tailwind with inline
style= colors.
- No
npx shadcn add — extend the vendored components by hand in the same
pattern (references/adding-shadcn-components.md).