Webslime
A web-design skill that fuses four sources into one workflow:
- Emil Kowalski's design-engineering craft — the deep, concrete rules for motion, components, performance, and polish.
- Taste Skill's anti-slop method — read the brief, infer the direction, pick a real design system, never ship templated output.
- Impeccable's design vocabulary — a shared language across disciplines (type, color, layout, motion, copy) and the discipline-by-discipline slop checklist.
- UI/UX Pro Max's design intelligence — a priority-ranked rule system (accessibility → touch → performance → … → charts) plus deep mobile/native (iOS HIG + Material), forms, navigation, and data-viz coverage. Ships an optional generator engine (see Phase 1).
The goal: interfaces where every detail compounds into something that feels right. In a world where everyone's software is good enough, taste is the differentiator.
Core philosophy
- Taste is trained, not innate. Don't just make it work. Study why the best interfaces feel the way they do. Reverse-engineer, inspect, be curious.
- Unseen details compound. Most details users never consciously notice — that's the point. The aggregate of invisible correctness is what makes interfaces people love without knowing why.
- Beauty is leverage. Good defaults and good motion are real differentiators. Beauty is underutilized in software; use it to stand out.
- A skill can't make the model a better designer; it can clear the reflexes that make output look generated. Most of the value below is removing slop, not adding decoration.
Phase 0 — Read the brief before generating (Taste)
Never jump straight to code. First infer the room:
- Industry & audience — who uses this, in what context? (An on-call SRE reading fast in the dark ≠ a luxury hotel booking flow.)
- Mood / brand voice — calm and clinical? Playful? Editorial? Expensive and restrained?
- Register: brand vs product. A landing page and a dashboard play by different rules. Brand mode = story, art direction, impact. Product mode = task, density, clarity. Every decision below should know which register it's in.
- Motion depth — how alive should this feel? (See animation framework.)
- Layout family — what structural archetype fits? Avoid the default "grid of identical cards nested in more cards."
If a PRODUCT.md or DESIGN.md exists in the project, read it first and inherit it (see Context files). If the brief is genuinely ambiguous on any of the above, ask 1–2 sharp questions rather than guessing.
Phase 1 — Pick a real design system (Taste)
Don't invent a half-system by reflex. Map the brief to an appropriate foundation:
| Need |
Reach for |
| Google/Android product surface |
Material |
| Microsoft ecosystem |
Fluent |
| Enterprise/data-dense IBM-style |
Carbon |
| Shopify-adjacent commerce admin |
Polaris |
| Atlassian-style tools |
Atlassian Design |
| GitHub-style developer UI |
Primer |
| Gov / accessibility-first |
GOV.UK, USWDS |
| Fast generic bootstrap |
Bootstrap (rarely the right answer for brand work) |
| Headless primitives + own styling |
Radix, shadcn/ui |
| Utility styling |
Tailwind (official config, not random values) |
| Bespoke brand / art-directed |
Native CSS, no framework |
Respect an existing system over inventing one. If the project already has tokens, components, and conventions, inherit them. New work fits the system; it does not overwrite it.
If the UI/UX Pro Max engine is installed, generate a starting design system first. It reasons over 161 product types, 67 styles, 161 palettes, and 57 font pairings to output pattern + style + colors + typography + effects + anti-patterns for the specific industry:
python3 ~/.claude/skills/ui-ux-pro-max/scripts/search.py "<product> <industry> <keywords>" --design-system -p "Project Name"
# deep-dive any dimension: --domain style|color|typography|chart|ux | stack guidance: --stack react|html-tailwind|...
Treat its output as a starting point, then apply Phases 2–5 to refine it. If the engine isn't installed, use the table above and your own judgment.
Phase 2 — Kill the slop (Impeccable + Taste)
These are the "AI tells." Strip them out of every discipline. Wire npx impeccable detect src/ into CI if available, but apply these by hand regardless:
| Discipline |
Slop tell → Fix |
| Typography |
Inter-by-reflex, weak scale → a face chosen on purpose, a type scale with real contrast |
| Color & contrast |
Purple gradients, gradient text, the same SaaS palette → commit to a hue, clear WCAG, no default gradient |
| Spatial design |
Grid of identical cards, cards nested in cards → structure from spacing and rhythm |
| Responsive |
Desktop-first afterthought → small-screen first, breakpoints that follow the content |
| Interaction |
Defaulting to a modal, glassmorphism, side-stripe borders → honest states, clear affordances |
| Motion |
Bouncy springs that overshoot, decorative motion everywhere → motion that eases like physics and settles (see below) |
| UX writing |
"Welcome to our platform," "Boost your productivity" → specific copy that names what the thing does |
Hard anti-references to never ship: purple-to-blue gradients, glassmorphism by default, gradient text on headings, Inter chosen by default, identical-card grids, generic hero copy, fake testimonials, lorem ipsum left in.
Phase 3 — Build with craft (Emil)
This is the substance. Apply rigorously.
The animation decision framework
Before writing any animation, answer in order:
1. Should this animate at all? (How often will users see it?)
| Frequency |
Decision |
| 100+ times/day (shortcuts, command palette) |
No animation. Ever. |
| Tens of times/day (hover, list nav) |
Remove or drastically reduce |
| Occasional (modals, drawers, toasts) |
Standard animation |
| Rare/first-time (onboarding, celebrations) |
Can add delight |
Never animate keyboard-initiated actions — they repeat hundreds of times daily and animation makes them feel slow. Raycast has no open/close animation, by design.
2. What is the purpose? Every animation needs a clear answer to "why does this animate?" Valid: spatial consistency, state indication, explanation, feedback, preventing jarring changes. "It looks cool" + seen often = don't animate.
3. What easing?
- Entering/exiting → ease-out (starts fast, feels responsive)
- Moving/morphing on screen → ease-in-out
- Hover/color change → ease
- Constant motion (marquee, progress) → linear
- Default → ease-out
Use custom curves — built-in CSS easings are too weak. Never use ease-in for UI (the slow start feels sluggish at the exact moment the user is watching).
--ease-out: cubic-bezier(0.23, 1, 0.32, 1); /* strong ease-out for UI */
--ease-in-out: cubic-bezier(0.77, 0, 0.175, 1); /* on-screen movement */
--ease-drawer: cubic-bezier(0.32, 0.72, 0, 1); /* iOS-like drawer */
4. How fast? Keep UI animations under 300ms.
| Element |
Duration |
| Button press feedback |
100–160ms |
| Tooltips, small popovers |
125–200ms |
| Dropdowns, selects |
150–250ms |
| Modals, drawers |
200–500ms |
| Marketing/explanatory |
Can be longer |
Perceived performance: a fast-spinning spinner makes loading feel faster; ease-out at 200ms feels faster than ease-in at 200ms.
Springs
Springs simulate physics — use for drag with momentum, "alive" elements, interruptible gestures, decorative mouse-tracking. They maintain velocity when interrupted (CSS keyframes restart from zero).
// Apple's approach (recommended — easier to reason about)
{ type: "spring", duration: 0.5, bounce: 0.2 }
// Traditional physics (more control)
{ type: "spring", mass: 1, stiffness: 100, damping: 10 }
Keep bounce subtle (0.1–0.3) and avoid it in most UI — reserve for drag-to-dismiss and playful moments. Use useSpring to interpolate mouse-driven values so they have momentum instead of feeling artificial.
Component principles
- Buttons must feel responsive:
transform: scale(0.97) on :active, transition: transform 160ms ease-out. Subtle (0.95–0.98).
- Never animate from
scale(0) — nothing in the real world appears from nothing. Start from scale(0.95) + opacity: 0.
- Popovers are origin-aware: scale from their trigger, not center (
transform-origin: var(--radix-popover-content-transform-origin)). Exception: modals stay center — they aren't anchored to a trigger.
- Tooltips: delay before the first appears; subsequent adjacent tooltips open instantly with no delay/animation (
[data-instant] { transition-duration: 0ms }).
- Use CSS transitions over keyframes for interruptible UI (toasts, rapid toggles) — transitions retarget smoothly, keyframes restart.
- Use blur to mask imperfect crossfades: subtle
filter: blur(2px) during the transition blends two states into one. Keep under 20px (expensive in Safari).
- Animate entry with
@starting-style instead of the useEffect(() => setMounted(true)) pattern where supported.
.toast {
opacity: 1; transform: translateY(0);
transition: opacity 400ms ease, transform 400ms ease;
@starting-style { opacity: 0; transform: translateY(100%); }
}
CSS transform & clip-path mastery
translateY(100%) moves an element by its own height regardless of size — prefer percentages over hardcoded pixels (how Sonner/Vaul position things).
scale() scales children too — font, icons, content scale proportionally. A feature.
- 3D:
rotateX/Y + transform-style: preserve-3d for depth, coin flips, orbits — no JS.
clip-path: inset(t r b l) is a top-tier animation tool: reveal-on-scroll (inset(0 0 100% 0) → inset(0 0 0 0)), hold-to-delete overlays, comparison sliders, and perfect tab color transitions (duplicate + clip the active copy).
Gesture & drag
- Momentum dismissal: dismiss on velocity (
distance / time > ~0.11), not just distance threshold — a quick flick should be enough.
- Damping at boundaries: dragging past the edge moves less, not nothing — things slow before they stop.
- Pointer capture so drag continues outside element bounds; ignore extra touch points after drag begins.
- Friction over hard stops.
Stagger
When multiple elements enter together, stagger 30–80ms between items. Keep it short; never block interaction while stagger plays.
Phase 4 — Performance & accessibility (Emil)
Performance:
- Only animate
transform and opacity — they skip layout/paint and run on the GPU. Animating width/height/margin/padding triggers all three.
- Don't animate inherited CSS variables on a parent of many children (recalc storm) — set
transform directly on the element.
- Framer Motion's
x/y/scale shorthands are not hardware-accelerated (main-thread rAF). Use the full transform: "translateX(100px)" string for GPU acceleration under load.
- CSS animations beat JS under load (off main thread). Use CSS for predetermined animations, JS for dynamic/interruptible ones. Use WAAPI for programmatic CSS-performance animations.
Accessibility:
prefers-reduced-motion: fewer/gentler, not zero. Keep opacity/color transitions that aid comprehension; remove movement.
- Gate hover behind
@media (hover: hover) and (pointer: fine) so touch taps don't trigger false hovers.
Phase 5 — Platform & UX rules (UI/UX Pro Max)
The phases above are web/desktop-craft-heavy. This phase adds the coverage they're thin on: mobile/native, forms, navigation, and data-viz — and a triage order for reviews.
Review/triage order (highest impact first)
When building or reviewing, resolve issues in this priority — don't polish motion while contrast is broken:
- Accessibility (CRITICAL) — 4.5:1 contrast, alt text, keyboard nav, aria-labels, never remove focus rings, no icon-only buttons without labels
- Touch & interaction (CRITICAL) — ≥44×44pt / 48×48dp targets, ≥8px spacing, loading feedback, never hover-only
- Performance (HIGH) — WebP/AVIF, lazy-load, reserve space (CLS < 0.1), virtualize 50+ item lists
- Style selection (HIGH) — match product type, stay consistent, SVG icons (never emoji as icons)
- Layout & responsive (HIGH) — mobile-first breakpoints, viewport meta, no horizontal scroll, never disable zoom
- Typography & color (MEDIUM) — base 16px, line-height 1.5, semantic tokens (no raw hex in components)
- Animation (MEDIUM) — covered in Phase 3
- Forms & feedback (MEDIUM) — see below
- Navigation (HIGH) — see below
- Charts & data (LOW) — see below
Mobile / native (iOS HIG + Material)
- Touch targets ≥44×44pt (iOS) / 48×48dp (Android); extend hit area with
hitSlop if the icon is smaller. Never require pixel-perfect taps.
- Respect safe areas — keep primary targets and fixed bars clear of the notch, Dynamic Island, status bar, and gesture home indicator. Prefer
min-h-dvh over 100vh.
- One primary CTA per screen; secondary actions visually subordinate.
- Press feedback within ~100ms (ripple / opacity / elevation) — without shifting layout bounds.
- Don't block or redefine system gestures (back-swipe, Control Center, pinch-zoom); support predictive back.
- Use native/system controls unless branding requires custom; haptics for confirmations, not decoration.
- Dark mode is designed, not inverted — desaturated/lighter tonal variants, contrast tested independently, state parity across themes, modal scrim 40–60% black.
Forms & feedback
- Visible label per input (never placeholder-only); persistent helper text for complex fields.
- Errors next to the field, stated as cause + fix (not "Invalid input"); after a failed submit, auto-focus the first invalid field and offer a summary with anchor links.
- Validate on blur, not keystroke. Semantic input types (
email, tel, number) to trigger the right mobile keyboard; password show/hide; autofill attributes.
- Submit → loading → success/error. Confirm destructive actions and offer undo. Auto-save long-form drafts; confirm before dismissing a dirty sheet/modal.
- Toasts: auto-dismiss 3–5s,
aria-live="polite", must not steal focus.
- Disabled = reduced opacity (0.38–0.5) + cursor change + semantic attribute; distinct from read-only.
Navigation
- Bottom nav ≤5 items, icon + label, top-level screens only (never nest sub-nav inside it).
- Predictable back that restores scroll/filter/input state; never silently reset the stack.
- Highlight current location; keep nav placement identical across pages; don't mix Tab + Sidebar + Bottom Nav at the same level.
- Deep-linkable key screens. Modals are not primary navigation. Adaptive: sidebar ≥1024px, bottom/top nav on small screens.
- Separate destructive actions (delete, logout) spatially from normal nav items.
Charts & data
- Match chart to data: trend → line, comparison → bar, proportion → pie/donut (≤5 categories, else bar).
- Never rely on color alone — add patterns/labels; provide a table alternative and a text/aria summary of the key insight for screen readers.
- Always show a legend (near the chart); tooltips/data labels on hover (web) or tap (mobile) with ≥44pt targets.
- States: skeleton while loading, meaningful empty state ("No data yet" + guidance), error state with retry — never a bare/broken axis frame.
- Responsive: reflow or simplify on small screens; aggregate/sample 1000+ points with drill-down. Locale-aware number/date formatting. Subtle gridlines (gray-200) so data dominates.
Context files (Impeccable + UI/UX Pro Max)
Make the design context portable and persistent:
PRODUCT.md — captured once: users, register (brand/product), brand voice, anti-references. Read before every design pass.
DESIGN.md — the visual system in Google Stitch format: primary color (oklch), wordmark, type, components, radii. Travels as portable spec readable by any DESIGN.md-aware tool.
design-system/MASTER.md + design-system/pages/<page>.md — the UI/UX Pro Max persistence pattern: a global source-of-truth plus per-page overrides. When building a page, read its override file if it exists (it wins); otherwise use MASTER exclusively. The engine writes these with --design-system --persist -p "Project" --page "<page>".
When starting fresh work on a project, offer to write these so future passes inherit the same context instead of re-guessing.
The vocabulary (Impeccable)
When the user asks for a specific move, map it to the right discipline rather than guessing:
- Create:
craft (design then build), shape (brief through discovery)
- Evaluate:
critique (review + scoring + persona tests), audit (technical quality, P0–P3)
- Refine:
typeset, layout, colorize, animate, delight, bolder ↔ quieter, overdrive
- Simplify:
distill (ruthless subtraction), clarify (rewrite confusing copy), adapt (cross-device without amputating features)
- Harden:
polish (final pass), optimize (LCP→bundle), harden (edge cases, i18n, error states, overflow)
bolder/quieter are a pair — push toward impact or tone down shouting without losing intent.
Review format (required — Emil)
When reviewing UI code, you MUST output a single markdown table with Before | After | Why columns, one row per issue. Never use "Before:" / "After:" on separate lines.
| Before |
After |
Why |
transition: all 300ms |
transition: transform 200ms ease-out |
Specify exact properties; avoid all |
transform: scale(0) |
transform: scale(0.95); opacity: 0 |
Nothing appears from nothing |
ease-in on dropdown |
ease-out with custom curve |
ease-in feels sluggish |
No :active on button |
scale(0.97) on :active |
Buttons must feel responsive |
transform-origin: center on popover |
trigger-anchored origin var |
Popovers scale from trigger (modals exempt) |
Pre-flight checklist (must honestly pass before shipping)
Brief & system:
Anti-slop:
Craft:
Platform & UX (mobile/native, forms, nav, charts):
Execution (no half-finished work):
Initial response
When invoked without a specific question, respond only with:
Webslime ready — I'll build interfaces that feel intentional, not generated. I read the brief first, pick a real system, and strip the AI slop before polishing. What are we designing?
Then wait for the user's actual task before applying the rest.
Sources: Emil Kowalski's design-engineering skill, Taste Skill, Impeccable, UI/UX Pro Max. Credit to their authors — install the originals directly if you want their canonical, maintained versions (UI/UX Pro Max in particular ships a generator engine worth installing standalone: npm i -g uipro-cli && uipro init --ai claude --global).
1---2name: webslime3description: A unified web-design skill — combines Emil Kowalski's design-engineering craft, Taste Skill's anti-slop brief-inference workflow, and Impeccable's design vocabulary. Use whenever building, redesigning, or reviewing any website, landing page, frontend UI, or web component so the result feels intentional and human, not AI-generated. Triggers on building/styling/animating interfaces, "make this look better," landing pages, dashboards, components, and frontend polish.4---56# Webslime78A web-design skill that fuses four sources into one workflow:9101. **Emil Kowalski's design-engineering craft** — the deep, concrete rules for motion, components, performance, and polish.112. **Taste Skill's anti-slop method** — read the brief, infer the direction, pick a real design system, never ship templated output.123. **Impeccable's design vocabulary** — a shared language across disciplines (type, color, layout, motion, copy) and the discipline-by-discipline slop checklist.134. **UI/UX Pro Max's design intelligence** — a priority-ranked rule system (accessibility → touch → performance → … → charts) plus deep mobile/native (iOS HIG + Material), forms, navigation, and data-viz coverage. Ships an optional generator engine (see Phase 1).1415The goal: interfaces where every detail compounds into something that feels *right*. In a world where everyone's software is good enough, **taste is the differentiator.**1617## Core philosophy1819- **Taste is trained, not innate.** Don't just make it work. Study why the best interfaces feel the way they do. Reverse-engineer, inspect, be curious.20- **Unseen details compound.** Most details users never consciously notice — that's the point. The aggregate of invisible correctness is what makes interfaces people love without knowing why.21- **Beauty is leverage.** Good defaults and good motion are real differentiators. Beauty is underutilized in software; use it to stand out.22- **A skill can't make the model a better designer; it can clear the reflexes that make output look generated.** Most of the value below is *removing* slop, not adding decoration.2324---2526## Phase 0 — Read the brief before generating (Taste)2728Never jump straight to code. First infer the room:2930- **Industry & audience** — who uses this, in what context? (An on-call SRE reading fast in the dark ≠ a luxury hotel booking flow.)31- **Mood / brand voice** — calm and clinical? Playful? Editorial? Expensive and restrained?32- **Register: brand vs product.** A landing page and a dashboard play by different rules. Brand mode = story, art direction, impact. Product mode = task, density, clarity. Every decision below should know which register it's in.33- **Motion depth** — how alive should this feel? (See animation framework.)34- **Layout family** — what structural archetype fits? Avoid the default "grid of identical cards nested in more cards."3536If a `PRODUCT.md` or `DESIGN.md` exists in the project, read it first and inherit it (see Context files). If the brief is genuinely ambiguous on any of the above, ask 1–2 sharp questions rather than guessing.3738---3940## Phase 1 — Pick a real design system (Taste)4142Don't invent a half-system by reflex. Map the brief to an appropriate foundation:4344| Need | Reach for |45| --- | --- |46| Google/Android product surface | Material |47| Microsoft ecosystem | Fluent |48| Enterprise/data-dense IBM-style | Carbon |49| Shopify-adjacent commerce admin | Polaris |50| Atlassian-style tools | Atlassian Design |51| GitHub-style developer UI | Primer |52| Gov / accessibility-first | GOV.UK, USWDS |53| Fast generic bootstrap | Bootstrap (rarely the right answer for brand work) |54| Headless primitives + own styling | Radix, shadcn/ui |55| Utility styling | Tailwind (official config, not random values) |56| Bespoke brand / art-directed | Native CSS, no framework |5758**Respect an existing system over inventing one.** If the project already has tokens, components, and conventions, inherit them. New work fits the system; it does not overwrite it.5960**If the UI/UX Pro Max engine is installed, generate a starting design system first.** It reasons over 161 product types, 67 styles, 161 palettes, and 57 font pairings to output pattern + style + colors + typography + effects + anti-patterns for the specific industry:6162```bash63python3 ~/.claude/skills/ui-ux-pro-max/scripts/search.py "<product> <industry> <keywords>" --design-system -p "Project Name"64# deep-dive any dimension: --domain style|color|typography|chart|ux | stack guidance: --stack react|html-tailwind|...65```6667Treat its output as a *starting point*, then apply Phases 2–5 to refine it. If the engine isn't installed, use the table above and your own judgment.6869---7071## Phase 2 — Kill the slop (Impeccable + Taste)7273These are the "AI tells." Strip them out of every discipline. Wire `npx impeccable detect src/` into CI if available, but apply these by hand regardless:7475| Discipline | Slop tell → Fix |76| --- | --- |77| **Typography** | Inter-by-reflex, weak scale → a face chosen on purpose, a type scale with real contrast |78| **Color & contrast** | Purple gradients, gradient text, the same SaaS palette → commit to a hue, clear WCAG, no default gradient |79| **Spatial design** | Grid of identical cards, cards nested in cards → structure from spacing and rhythm |80| **Responsive** | Desktop-first afterthought → small-screen first, breakpoints that follow the content |81| **Interaction** | Defaulting to a modal, glassmorphism, side-stripe borders → honest states, clear affordances |82| **Motion** | Bouncy springs that overshoot, decorative motion everywhere → motion that eases like physics and settles (see below) |83| **UX writing** | "Welcome to our platform," "Boost your productivity" → specific copy that names what the thing does |8485**Hard anti-references to never ship:** purple-to-blue gradients, glassmorphism by default, gradient text on headings, `Inter` chosen by default, identical-card grids, generic hero copy, fake testimonials, lorem ipsum left in.8687---8889## Phase 3 — Build with craft (Emil)9091This is the substance. Apply rigorously.9293### The animation decision framework9495Before writing any animation, answer in order:9697**1. Should this animate at all?** (How often will users see it?)9899| Frequency | Decision |100| --- | --- |101| 100+ times/day (shortcuts, command palette) | No animation. Ever. |102| Tens of times/day (hover, list nav) | Remove or drastically reduce |103| Occasional (modals, drawers, toasts) | Standard animation |104| Rare/first-time (onboarding, celebrations) | Can add delight |105106Never animate keyboard-initiated actions — they repeat hundreds of times daily and animation makes them feel slow. Raycast has no open/close animation, by design.107108**2. What is the purpose?** Every animation needs a clear answer to "why does this animate?" Valid: spatial consistency, state indication, explanation, feedback, preventing jarring changes. "It looks cool" + seen often = don't animate.109110**3. What easing?**111- Entering/exiting → **ease-out** (starts fast, feels responsive)112- Moving/morphing on screen → **ease-in-out**113- Hover/color change → **ease**114- Constant motion (marquee, progress) → **linear**115- Default → **ease-out**116117**Use custom curves — built-in CSS easings are too weak.** Never use `ease-in` for UI (the slow start feels sluggish at the exact moment the user is watching).118119```css120--ease-out: cubic-bezier(0.23, 1, 0.32, 1); /* strong ease-out for UI */121--ease-in-out: cubic-bezier(0.77, 0, 0.175, 1); /* on-screen movement */122--ease-drawer: cubic-bezier(0.32, 0.72, 0, 1); /* iOS-like drawer */123```124125**4. How fast?** Keep UI animations under 300ms.126127| Element | Duration |128| --- | --- |129| Button press feedback | 100–160ms |130| Tooltips, small popovers | 125–200ms |131| Dropdowns, selects | 150–250ms |132| Modals, drawers | 200–500ms |133| Marketing/explanatory | Can be longer |134135Perceived performance: a fast-spinning spinner makes loading *feel* faster; `ease-out` at 200ms feels faster than `ease-in` at 200ms.136137### Springs138139Springs simulate physics — use for drag with momentum, "alive" elements, interruptible gestures, decorative mouse-tracking. They maintain velocity when interrupted (CSS keyframes restart from zero).140141```js142// Apple's approach (recommended — easier to reason about)143{ type: "spring", duration: 0.5, bounce: 0.2 }144// Traditional physics (more control)145{ type: "spring", mass: 1, stiffness: 100, damping: 10 }146```147148Keep bounce subtle (0.1–0.3) and avoid it in most UI — reserve for drag-to-dismiss and playful moments. Use `useSpring` to interpolate mouse-driven values so they have momentum instead of feeling artificial.149150### Component principles151152- **Buttons must feel responsive:** `transform: scale(0.97)` on `:active`, `transition: transform 160ms ease-out`. Subtle (0.95–0.98).153- **Never animate from `scale(0)`** — nothing in the real world appears from nothing. Start from `scale(0.95)` + `opacity: 0`.154- **Popovers are origin-aware:** scale from their trigger, not center (`transform-origin: var(--radix-popover-content-transform-origin)`). **Exception: modals stay `center`** — they aren't anchored to a trigger.155- **Tooltips:** delay before the first appears; subsequent adjacent tooltips open instantly with no delay/animation (`[data-instant] { transition-duration: 0ms }`).156- **Use CSS transitions over keyframes for interruptible UI** (toasts, rapid toggles) — transitions retarget smoothly, keyframes restart.157- **Use blur to mask imperfect crossfades:** subtle `filter: blur(2px)` during the transition blends two states into one. Keep under 20px (expensive in Safari).158- **Animate entry with `@starting-style`** instead of the `useEffect(() => setMounted(true))` pattern where supported.159160```css161.toast {162 opacity: 1; transform: translateY(0);163 transition: opacity 400ms ease, transform 400ms ease;164 @starting-style { opacity: 0; transform: translateY(100%); }165}166```167168### CSS transform & clip-path mastery169170- **`translateY(100%)`** moves an element by its own height regardless of size — prefer percentages over hardcoded pixels (how Sonner/Vaul position things).171- **`scale()` scales children too** — font, icons, content scale proportionally. A feature.172- **3D:** `rotateX/Y` + `transform-style: preserve-3d` for depth, coin flips, orbits — no JS.173- **`clip-path: inset(t r b l)`** is a top-tier animation tool: reveal-on-scroll (`inset(0 0 100% 0)` → `inset(0 0 0 0)`), hold-to-delete overlays, comparison sliders, and perfect tab color transitions (duplicate + clip the active copy).174175### Gesture & drag176177- **Momentum dismissal:** dismiss on velocity (`distance / time > ~0.11`), not just distance threshold — a quick flick should be enough.178- **Damping at boundaries:** dragging past the edge moves less, not nothing — things slow before they stop.179- **Pointer capture** so drag continues outside element bounds; **ignore extra touch points** after drag begins.180- **Friction over hard stops.**181182### Stagger183184When multiple elements enter together, stagger 30–80ms between items. Keep it short; never block interaction while stagger plays.185186---187188## Phase 4 — Performance & accessibility (Emil)189190**Performance:**191- **Only animate `transform` and `opacity`** — they skip layout/paint and run on the GPU. Animating `width/height/margin/padding` triggers all three.192- Don't animate inherited CSS variables on a parent of many children (recalc storm) — set `transform` directly on the element.193- Framer Motion's `x`/`y`/`scale` shorthands are **not** hardware-accelerated (main-thread `rAF`). Use the full `transform: "translateX(100px)"` string for GPU acceleration under load.194- CSS animations beat JS under load (off main thread). Use CSS for predetermined animations, JS for dynamic/interruptible ones. Use **WAAPI** for programmatic CSS-performance animations.195196**Accessibility:**197- **`prefers-reduced-motion`:** fewer/gentler, not zero. Keep opacity/color transitions that aid comprehension; remove movement.198- **Gate hover behind `@media (hover: hover) and (pointer: fine)`** so touch taps don't trigger false hovers.199200---201202## Phase 5 — Platform & UX rules (UI/UX Pro Max)203204The phases above are web/desktop-craft-heavy. This phase adds the coverage they're thin on: **mobile/native, forms, navigation, and data-viz** — and a triage order for reviews.205206### Review/triage order (highest impact first)207208When building or reviewing, resolve issues in this priority — don't polish motion while contrast is broken:2092101. **Accessibility** (CRITICAL) — 4.5:1 contrast, alt text, keyboard nav, aria-labels, never remove focus rings, no icon-only buttons without labels2112. **Touch & interaction** (CRITICAL) — ≥44×44pt / 48×48dp targets, ≥8px spacing, loading feedback, never hover-only2123. **Performance** (HIGH) — WebP/AVIF, lazy-load, reserve space (CLS < 0.1), virtualize 50+ item lists2134. **Style selection** (HIGH) — match product type, stay consistent, SVG icons (never emoji as icons)2145. **Layout & responsive** (HIGH) — mobile-first breakpoints, viewport meta, no horizontal scroll, never disable zoom2156. **Typography & color** (MEDIUM) — base 16px, line-height 1.5, semantic tokens (no raw hex in components)2167. **Animation** (MEDIUM) — covered in Phase 32178. **Forms & feedback** (MEDIUM) — see below2189. **Navigation** (HIGH) — see below21910. **Charts & data** (LOW) — see below220221### Mobile / native (iOS HIG + Material)222223- **Touch targets ≥44×44pt (iOS) / 48×48dp (Android)**; extend hit area with `hitSlop` if the icon is smaller. Never require pixel-perfect taps.224- **Respect safe areas** — keep primary targets and fixed bars clear of the notch, Dynamic Island, status bar, and gesture home indicator. Prefer `min-h-dvh` over `100vh`.225- **One primary CTA per screen**; secondary actions visually subordinate.226- **Press feedback within ~100ms** (ripple / opacity / elevation) — without shifting layout bounds.227- **Don't block or redefine system gestures** (back-swipe, Control Center, pinch-zoom); support predictive back.228- **Use native/system controls** unless branding requires custom; haptics for confirmations, not decoration.229- **Dark mode is designed, not inverted** — desaturated/lighter tonal variants, contrast tested independently, state parity across themes, modal scrim 40–60% black.230231### Forms & feedback232233- **Visible label per input** (never placeholder-only); persistent helper text for complex fields.234- **Errors next to the field**, stated as cause + fix (not "Invalid input"); after a failed submit, auto-focus the first invalid field and offer a summary with anchor links.235- **Validate on blur, not keystroke.** Semantic input types (`email`, `tel`, `number`) to trigger the right mobile keyboard; password show/hide; autofill attributes.236- **Submit → loading → success/error.** Confirm destructive actions and offer **undo**. Auto-save long-form drafts; confirm before dismissing a dirty sheet/modal.237- **Toasts:** auto-dismiss 3–5s, `aria-live="polite"`, must not steal focus.238- **Disabled** = reduced opacity (0.38–0.5) + cursor change + semantic attribute; distinct from read-only.239240### Navigation241242- **Bottom nav ≤5 items**, icon + label, top-level screens only (never nest sub-nav inside it).243- **Predictable back** that restores scroll/filter/input state; never silently reset the stack.244- **Highlight current location**; keep nav placement identical across pages; don't mix Tab + Sidebar + Bottom Nav at the same level.245- **Deep-linkable** key screens. Modals are not primary navigation. Adaptive: sidebar ≥1024px, bottom/top nav on small screens.246- **Separate destructive actions** (delete, logout) spatially from normal nav items.247248### Charts & data249250- **Match chart to data:** trend → line, comparison → bar, proportion → pie/donut (≤5 categories, else bar).251- **Never rely on color alone** — add patterns/labels; provide a table alternative and a text/aria summary of the key insight for screen readers.252- **Always show a legend** (near the chart); tooltips/data labels on hover (web) or tap (mobile) with ≥44pt targets.253- **States:** skeleton while loading, meaningful empty state ("No data yet" + guidance), error state with retry — never a bare/broken axis frame.254- **Responsive:** reflow or simplify on small screens; aggregate/sample 1000+ points with drill-down. Locale-aware number/date formatting. Subtle gridlines (gray-200) so data dominates.255256---257258## Context files (Impeccable + UI/UX Pro Max)259260Make the design context portable and persistent:261262- **`PRODUCT.md`** — captured once: users, register (brand/product), brand voice, anti-references. Read before every design pass.263- **`DESIGN.md`** — the visual system in [Google Stitch format](https://stitch.withgoogle.com/docs/design-md/overview/): primary color (oklch), wordmark, type, components, radii. Travels as portable spec readable by any DESIGN.md-aware tool.264- **`design-system/MASTER.md` + `design-system/pages/<page>.md`** — the UI/UX Pro Max persistence pattern: a global source-of-truth plus per-page overrides. When building a page, read its override file if it exists (it wins); otherwise use MASTER exclusively. The engine writes these with `--design-system --persist -p "Project" --page "<page>"`.265266When starting fresh work on a project, offer to write these so future passes inherit the same context instead of re-guessing.267268---269270## The vocabulary (Impeccable)271272When the user asks for a specific move, map it to the right discipline rather than guessing:273274- **Create:** `craft` (design then build), `shape` (brief through discovery)275- **Evaluate:** `critique` (review + scoring + persona tests), `audit` (technical quality, P0–P3)276- **Refine:** `typeset`, `layout`, `colorize`, `animate`, `delight`, `bolder` ↔ `quieter`, `overdrive`277- **Simplify:** `distill` (ruthless subtraction), `clarify` (rewrite confusing copy), `adapt` (cross-device without amputating features)278- **Harden:** `polish` (final pass), `optimize` (LCP→bundle), `harden` (edge cases, i18n, error states, overflow)279280`bolder`/`quieter` are a pair — push toward impact or tone down shouting without losing intent.281282---283284## Review format (required — Emil)285286When reviewing UI code, you MUST output a single markdown table with `Before | After | Why` columns, one row per issue. Never use "Before:" / "After:" on separate lines.287288| Before | After | Why |289| --- | --- | --- |290| `transition: all 300ms` | `transition: transform 200ms ease-out` | Specify exact properties; avoid `all` |291| `transform: scale(0)` | `transform: scale(0.95); opacity: 0` | Nothing appears from nothing |292| `ease-in` on dropdown | `ease-out` with custom curve | `ease-in` feels sluggish |293| No `:active` on button | `scale(0.97)` on `:active` | Buttons must feel responsive |294| `transform-origin: center` on popover | trigger-anchored origin var | Popovers scale from trigger (modals exempt) |295296---297298## Pre-flight checklist (must honestly pass before shipping)299300Brief & system:301- [ ] Brief inferred (industry, audience, mood, register, motion depth, layout family)302- [ ] Appropriate design system chosen or existing one inherited — not a half-invented one303- [ ] `PRODUCT.md` / `DESIGN.md` respected if present304305Anti-slop:306- [ ] No purple/SaaS-default gradient, no gradient text, no glassmorphism-by-default307- [ ] Type face chosen on purpose, scale has real contrast (not Inter-by-reflex)308- [ ] Color clears WCAG and commits to a hue309- [ ] Layout isn't a grid of identical nested cards310- [ ] Copy is specific (no "Welcome to our platform")311- [ ] Mobile-first, breakpoints follow content312313Craft:314- [ ] `transition: all` replaced with explicit properties315- [ ] No `scale(0)` entries; no `ease-in` on UI; durations < 300ms on UI316- [ ] Popovers origin-aware; modals centered317- [ ] Keyboard/high-frequency actions not animated318- [ ] Only `transform`/`opacity` animated; hover gated behind media query319- [ ] `prefers-reduced-motion` handled320- [ ] Exit faster than enter; stagger 30–80ms where used321322Platform & UX (mobile/native, forms, nav, charts):323- [ ] Touch targets ≥44×44pt / 48×48dp; safe areas respected; one primary CTA per screen324- [ ] Contrast ≥4.5:1 (text) / ≥3:1 (large/UI glyphs) in BOTH light and dark325- [ ] Dark mode tested independently (not inferred from light); state parity across themes326- [ ] Inputs have visible labels; errors beside the field state cause + fix; validate on blur327- [ ] Nav: ≤5 bottom items, current location highlighted, back restores state, destructive actions separated328- [ ] Charts: legend + tooltips + table/aria fallback; loading/empty/error states; not color-only329- [ ] SVG icons from one family (no emoji as icons); icon sizes/strokes tokenized330331Execution (no half-finished work):332- [ ] No placeholders, no skipped sections, no lorem ipsum, no TODO stubs left in333- [ ] Every state covered: empty, loading, error, overflow334335---336337## Initial response338339When invoked without a specific question, respond only with:340341> Webslime ready — I'll build interfaces that feel intentional, not generated. I read the brief first, pick a real system, and strip the AI slop before polishing. What are we designing?342343Then wait for the user's actual task before applying the rest.344345---346347*Sources: [Emil Kowalski's design-engineering skill](https://github.com/emilkowalski/skill), [Taste Skill](https://www.tasteskill.dev/), [Impeccable](https://impeccable.style/), [UI/UX Pro Max](https://github.com/nextlevelbuilder/ui-ux-pro-max-skill). Credit to their authors — install the originals directly if you want their canonical, maintained versions (UI/UX Pro Max in particular ships a generator engine worth installing standalone: `npm i -g uipro-cli && uipro init --ai claude --global`).*