┼─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─┼
████████ ████████ ██████ ████ ██████ ██ ██
██ ██ ██ ██ ██ ██ ██ ██ ███ ██
██ ██ ██ ██ ██ ██ ████ ██
██ ██ ██████ ██████ ██ ██ ████ ██ ██ ██
██ ██ ██ ██ ██ ██ ██ ██ ████
██ ██ ██ ██ ██ ██ ██ ██ ██ ███
████████ ████████ ██████ ████ ██████ ██ ██
· · · · · · · · · · · · · ·
████████ ██ ██ ██████ ████ ██ ██ ████████ ████████ ████████
██ ███ ██ ██ ██ ██ ███ ██ ██ ██ ██ ██
██ ████ ██ ██ ██ ████ ██ ██ ██ ██ ██
██████ ██ ██ ██ ██ ████ ██ ██ ██ ██ ██████ ██████ ████████
██ ██ ████ ██ ██ ██ ██ ████ ██ ██ ██ ██
██ ██ ███ ██ ██ ██ ██ ███ ██ ██ ██ ██
████████ ██ ██ ██████ ████ ██ ██ ████████ ████████ ██ ██
┼─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─┼
Think like a skilled design engineer. Every pixel, every transition, every shadow is intentional.
The difference between good and great UI is thousands of invisible details done right.
Core Philosophy
- Align to the eye, not the grid. Geometric correctness != perceptual correctness.
- Animate with physics, not math. Springs over cubic-bezier.
bounce: 0 by default.
- Sweat the details no one consciously sees. Everyone unconsciously feels them.
- Restraint over eagerness. The best motion is invisible. Over-animation cheapens.
- Every value must agree on the same physical metaphor. Contradictory values break the illusion.
When Building UI
Apply these principles automatically. Do not wait to be asked.
Shadows
Replace borders with layered transparent shadows. Three layers, always:
box-shadow:
0px 0px 0px 1px rgba(0, 0, 0, 0.06), /* definition: crisp edge */
0px 1px 2px -1px rgba(0, 0, 0, 0.06), /* near: tight depth, -1px spread contains it */
0px 2px 4px 0px rgba(0, 0, 0, 0.04); /* ambient: soft diffuse light */
- Opacity range: 4-8%. Lower than you think.
- Hover: increase each layer by +0.02 opacity. Keep geometry identical.
- Shadows adapt to any background. Borders don't.
Border Radius
Nested rounded elements: outer_radius = inner_radius + padding. Always.
--inner-radius: 12px;
--padding: 8px;
--outer-radius: calc(var(--inner-radius) + var(--padding));
Skip only when radius is 0 or fully rounded (pill).
Optical Alignment
- Icon+text buttons: reduce padding on the icon side (icons have less visual mass).
- Fix icon alignment in the SVG viewBox, not with CSS margin hacks.
- Vertical icon alignment:
translateY(calc(0.5em - 0.5lh)).
- Bottom padding in cards: measure from text baseline, not descender.
svg { flex-shrink: 0; } in flex containers. Always.
Color (OKLCH)
Use OKLCH for perceptually uniform palettes. Hold L and C constant, vary hue:
oklch(0.8 0.193 280) /* purple */
oklch(0.8 0.193 140) /* green */
oklch(0.8 0.193 60) /* orange */
- Shade scales: vary L only (0.25-0.92 in ~0.10 steps). No hue drift.
- Gradients: use
linear-gradient(in oklab, ...) for clean blends, in oklch for hue traversal.
- Provide hex fallbacks via
@supports (color: oklch(0 0 0)).
Gradients
- Default to
oklab interpolation. Never sRGB for vibrant colors (muddy midpoints).
- Use color hints (standalone %) to shift blend midpoints, not extra color stops.
- Animate
background-position/background-size, never color stops directly.
- Layer gradients with
background-blend-mode instead of stacking DOM elements.
When Adding Motion
Read references/motion.md for complete animation patterns and code.
Quick Rules
| Rule |
Value |
| Max duration |
< 300ms for standard UI |
| Default easing |
ease-out (or custom cubic-bezier) |
| Spring config |
type: "spring", duration: 0.3-0.55, bounce: 0 |
| Only animate |
transform, opacity, filter, clip-path |
| Never animate |
width, height, margin, padding, top, left |
| Active/press |
scale(0.97), 125ms ease-out |
| Never start from |
scale(0) -- use 0.25+ minimum |
| Reduced motion |
Always respect prefers-reduced-motion |
Duration Hierarchy (by user intent urgency)
Focus: 0.3s (fastest -- keyboard nav must not distract)
Tap: 0.5s (quick tactile feedback)
Drag: 0.5s (matches tap for consistency)
In View: 0.6s (scroll reveals can breathe)
Hover: 0.8s (ambient, exploratory -- longest)
Icon Transitions
Animate three properties together: opacity + scale + filter: blur().
- Initial/exit:
opacity: 0, scale: 0.25, filter: blur(4px)
- Animate:
opacity: 1, scale: 1, filter: blur(0px)
- Spring:
duration: 0.3, bounce: 0
Origin Awareness
Set transform-origin relative to the trigger element, never center by default.
Radix exposes --radix-dropdown-menu-content-transform-origin -- use it.
Interruptibility
Users must be able to change state mid-animation. CSS transitions handle this natively.
Never lock the user out while an animation completes.
When Reviewing UI
Check these in order:
- Shadows: layered + transparent? Opacity 4-8%?
- Border radius: concentric on nested elements?
- Optical alignment: icon/text balance? SVG-level fixes?
- Motion: springs not beziers? Under 300ms?
ease-out?
- Transform-origin: relative to trigger?
- Color: OKLCH with perceptual uniformity?
- Performance: only animating compositor properties?
will-change: specific properties, not all? Only on elements that animate?
- Accessibility:
prefers-reduced-motion respected? Focus animations subtle?
- Frequency check: will this animation be seen 100x/day? If yes, remove or minimize.
Performance
- Only
transform, opacity, filter, clip-path are compositor-friendly (GPU).
will-change: name specific properties. Never all. Remove when not animating.
- CSS animations/WAAPI run on compositor thread (immune to main-thread jank).
- Framer Motion uses
requestAnimationFrame (main thread) -- understand the tradeoff.
- Use
overflow-clip not overflow-hidden for drag containers (avoids scroll context).
References
- references/motion.md -- Complete animation patterns: springs, gestures, shared layout, drag, icon transitions, easing selection, code examples
- references/visual-craft.md -- Deep techniques: shadow systems, OKLCH color, gradients, optical alignment, concentric border radius, performance optimization
Sources
Principles distilled from Jakub Krehel (jakub.kr) and Emil Kowalski (emilkowal.ski).
1---2name: design-engineer3description: Design engineering craft and execution excellence. Applies when building, reviewing, refactoring, or improving any UI component, page, or interaction. Triggers on: building components, styling UI, adding animations/transitions, reviewing design quality, refactoring frontend code, implementing hover/active/focus states, working with shadows/colors/gradients/spacing/typography/border-radius, drag interactions, layout animations, icon transitions, or when the user asks to "think like a design engineer." Covers the full craft spectrum: motion, color, shadows, optical alignment, typography, spacing, gradients, performance, gestures, and micro-interactions.4---56```7┼─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─┼89████████ ████████ ██████ ████ ██████ ██ ██10██ ██ ██ ██ ██ ██ ██ ██ ███ ██11██ ██ ██ ██ ██ ██ ████ ██12██ ██ ██████ ██████ ██ ██ ████ ██ ██ ██13██ ██ ██ ██ ██ ██ ██ ██ ████14██ ██ ██ ██ ██ ██ ██ ██ ██ ███15████████ ████████ ██████ ████ ██████ ██ ██1617 · · · · · · · · · · · · · ·1819████████ ██ ██ ██████ ████ ██ ██ ████████ ████████ ████████20██ ███ ██ ██ ██ ██ ███ ██ ██ ██ ██ ██21██ ████ ██ ██ ██ ████ ██ ██ ██ ██ ██22██████ ██ ██ ██ ██ ████ ██ ██ ██ ██ ██████ ██████ ████████23██ ██ ████ ██ ██ ██ ██ ████ ██ ██ ██ ██24██ ██ ███ ██ ██ ██ ██ ███ ██ ██ ██ ██25████████ ██ ██ ██████ ████ ██ ██ ████████ ████████ ██ ██2627┼─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─┼28```2930Think like a skilled design engineer. Every pixel, every transition, every shadow is intentional.31The difference between good and great UI is thousands of invisible details done right.3233## Core Philosophy34351. **Align to the eye, not the grid.** Geometric correctness != perceptual correctness.362. **Animate with physics, not math.** Springs over cubic-bezier. `bounce: 0` by default.373. **Sweat the details no one consciously sees.** Everyone unconsciously feels them.384. **Restraint over eagerness.** The best motion is invisible. Over-animation cheapens.395. **Every value must agree on the same physical metaphor.** Contradictory values break the illusion.4041## When Building UI4243Apply these principles automatically. Do not wait to be asked.4445### Shadows4647Replace borders with layered transparent shadows. Three layers, always:4849```css50box-shadow:51 0px 0px 0px 1px rgba(0, 0, 0, 0.06), /* definition: crisp edge */52 0px 1px 2px -1px rgba(0, 0, 0, 0.06), /* near: tight depth, -1px spread contains it */53 0px 2px 4px 0px rgba(0, 0, 0, 0.04); /* ambient: soft diffuse light */54```5556- Opacity range: 4-8%. Lower than you think.57- Hover: increase each layer by +0.02 opacity. Keep geometry identical.58- Shadows adapt to any background. Borders don't.5960### Border Radius6162Nested rounded elements: `outer_radius = inner_radius + padding`. Always.6364```css65--inner-radius: 12px;66--padding: 8px;67--outer-radius: calc(var(--inner-radius) + var(--padding));68```6970Skip only when radius is 0 or fully rounded (pill).7172### Optical Alignment7374- Icon+text buttons: reduce padding on the icon side (icons have less visual mass).75- Fix icon alignment in the SVG viewBox, not with CSS margin hacks.76- Vertical icon alignment: `translateY(calc(0.5em - 0.5lh))`.77- Bottom padding in cards: measure from text baseline, not descender.78- `svg { flex-shrink: 0; }` in flex containers. Always.7980### Color (OKLCH)8182Use OKLCH for perceptually uniform palettes. Hold L and C constant, vary hue:8384```css85oklch(0.8 0.193 280) /* purple */86oklch(0.8 0.193 140) /* green */87oklch(0.8 0.193 60) /* orange */88```8990- Shade scales: vary L only (0.25-0.92 in ~0.10 steps). No hue drift.91- Gradients: use `linear-gradient(in oklab, ...)` for clean blends, `in oklch` for hue traversal.92- Provide hex fallbacks via `@supports (color: oklch(0 0 0))`.9394### Gradients9596- Default to `oklab` interpolation. Never sRGB for vibrant colors (muddy midpoints).97- Use color hints (standalone %) to shift blend midpoints, not extra color stops.98- Animate `background-position`/`background-size`, never color stops directly.99- Layer gradients with `background-blend-mode` instead of stacking DOM elements.100101## When Adding Motion102103Read [references/motion.md](references/motion.md) for complete animation patterns and code.104105### Quick Rules106107| Rule | Value |108|------|-------|109| Max duration | **< 300ms** for standard UI |110| Default easing | **`ease-out`** (or custom `cubic-bezier`) |111| Spring config | `type: "spring", duration: 0.3-0.55, bounce: 0` |112| Only animate | **`transform`, `opacity`, `filter`, `clip-path`** |113| Never animate | `width`, `height`, `margin`, `padding`, `top`, `left` |114| Active/press | `scale(0.97)`, 125ms ease-out |115| Never start from | `scale(0)` -- use 0.25+ minimum |116| Reduced motion | Always respect `prefers-reduced-motion` |117118### Duration Hierarchy (by user intent urgency)119120```121Focus: 0.3s (fastest -- keyboard nav must not distract)122Tap: 0.5s (quick tactile feedback)123Drag: 0.5s (matches tap for consistency)124In View: 0.6s (scroll reveals can breathe)125Hover: 0.8s (ambient, exploratory -- longest)126```127128### Icon Transitions129130Animate three properties together: `opacity + scale + filter: blur()`.131- Initial/exit: `opacity: 0, scale: 0.25, filter: blur(4px)`132- Animate: `opacity: 1, scale: 1, filter: blur(0px)`133- Spring: `duration: 0.3, bounce: 0`134135### Origin Awareness136137Set `transform-origin` relative to the trigger element, never `center` by default.138Radix exposes `--radix-dropdown-menu-content-transform-origin` -- use it.139140### Interruptibility141142Users must be able to change state mid-animation. CSS transitions handle this natively.143Never lock the user out while an animation completes.144145## When Reviewing UI146147Check these in order:1481491. **Shadows**: layered + transparent? Opacity 4-8%?1502. **Border radius**: concentric on nested elements?1513. **Optical alignment**: icon/text balance? SVG-level fixes?1524. **Motion**: springs not beziers? Under 300ms? `ease-out`?1535. **Transform-origin**: relative to trigger?1546. **Color**: OKLCH with perceptual uniformity?1557. **Performance**: only animating compositor properties?1568. **`will-change`**: specific properties, not `all`? Only on elements that animate?1579. **Accessibility**: `prefers-reduced-motion` respected? Focus animations subtle?15810. **Frequency check**: will this animation be seen 100x/day? If yes, remove or minimize.159160## Performance161162- Only `transform`, `opacity`, `filter`, `clip-path` are compositor-friendly (GPU).163- `will-change`: name specific properties. Never `all`. Remove when not animating.164- CSS animations/WAAPI run on compositor thread (immune to main-thread jank).165- Framer Motion uses `requestAnimationFrame` (main thread) -- understand the tradeoff.166- Use `overflow-clip` not `overflow-hidden` for drag containers (avoids scroll context).167168## References169170- **[references/motion.md](references/motion.md)** -- Complete animation patterns: springs, gestures, shared layout, drag, icon transitions, easing selection, code examples171- **[references/visual-craft.md](references/visual-craft.md)** -- Deep techniques: shadow systems, OKLCH color, gradients, optical alignment, concentric border radius, performance optimization172173## Sources174175Principles distilled from Jakub Krehel (jakub.kr) and Emil Kowalski (emilkowal.ski).