Gabriel's banner
Gabriel's profile picture

Gabriel

@gabriell_lab8,724 subscribers

designer ex. @Porsche & @Audi

Shorts

Since Opus 4.8 is out and more and more designers are getting into Design Engineering, I thought I’d share some of the interaction patterns I use most often: Use proximity, not just hover. When the cursor gets close, nearby elements can subtly scale and darken based on distance. It makes interfaces feel more responsive, less binary, and way more alive onpointermove = e => document.querySelectorAll(".dock>*").forEach(el => { const r = el.getBoundingClientRect(); const t = Math.max(0, 1 - Math.abs(e.clientX - r.x - r.width/2) / 120); el. style.scale = 1 + t * .5; });

Since Opus 4.8 is out and more and more designers are getting into Design Engineering, I thought I’d share some of the interaction patterns I use most often: Use proximity, not just hover. When the cursor gets close, nearby elements can subtly scale and darken based on distance. It makes interfaces feel more responsive, less binary, and way more alive onpointermove = e => document.querySelectorAll(".dock>*").forEach(el => { const r = el.getBoundingClientRect(); const t = Math.max(0, 1 - Math.abs(e.clientX - r.x - r.width/2) / 120); el. style.scale = 1 + t * .5; });

667,783 просмотров

If you struggle to describe UI transitions in Claude or Codex, these commonly used transition terms can help. Save this for later.

If you struggle to describe UI transitions in Claude or Codex, these commonly used transition terms can help. Save this for later.

269,347 просмотров

Design Engineering Tip: One CSS property is responsible for most ugly expand animations. It’s height: auto. Replace it with: grid-template-rows: 0fr → 1fr;

Design Engineering Tip: One CSS property is responsible for most ugly expand animations. It’s height: auto. Replace it with: grid-template-rows: 0fr → 1fr;

110,225 просмотров

I’ve been using 60% Apple-style corner smoothing all the time. But whenever I explain it to Codex or Claude Code, they often miss the point. So I made a skill that anyone can use with their AI agents: npx skills add gabrielobholz/corner-smoothing-skill Now I can simply say: “Create a rectangle with radius: 32 and smoothing: 60” and get the shape I actually mean.

I’ve been using 60% Apple-style corner smoothing all the time. But whenever I explain it to Codex or Claude Code, they often miss the point. So I made a skill that anyone can use with their AI agents: npx skills add gabrielobholz/corner-smoothing-skill Now I can simply say: “Create a rectangle with radius: 32 and smoothing: 60” and get the shape I actually mean.

95,841 просмотров

Design Engineering Tip: Most UI animations are built for a single uninterrupted transition. Real users might reverse direction before the animation finishes. Use a spring transition that preserves the element’s current velocity instead of restarting from zero. This keeps rapid hover, press, and state changes smooth and responsive. transition={{ type: "spring", stiffness: 520, damping: 38, }}

Design Engineering Tip: Most UI animations are built for a single uninterrupted transition. Real users might reverse direction before the animation finishes. Use a spring transition that preserves the element’s current velocity instead of restarting from zero. This keeps rapid hover, press, and state changes smooth and responsive. transition={{ type: "spring", stiffness: 520, damping: 38, }}

66,427 просмотров

Design Engineering Tip: If your whole page shifts 15px the moment a modal opens, it isn't the modal. It's the scrollbar disappearing, because the library sets overflow: hidden on the body to lock scrolling. Reserve the space before you ever need it: html { scrollbar-gutter: stable; }

Design Engineering Tip: If your whole page shifts 15px the moment a modal opens, it isn't the modal. It's the scrollbar disappearing, because the library sets overflow: hidden on the body to lock scrolling. Reserve the space before you ever need it: html { scrollbar-gutter: stable; }

31,246 просмотров

Design Engineering Tip: Don’t move objects at a constant shape. As speed increases, stretch them in the direction of travel. The faster they move, the more they deform. Combined with easing and subtle motion blur, even simple animations can feel significantly more dynamic. const x = useMotionValue(0) const v = useVelocity(x) const scaleX = useTransform(v, [-1200, 0, 1200], [1.8, 1, 1.8]) const blur = useTransform(v, [-1200, 0, 1200], [3, 0, 3]) `blur(${b}px)`), }} />

Design Engineering Tip: Don’t move objects at a constant shape. As speed increases, stretch them in the direction of travel. The faster they move, the more they deform. Combined with easing and subtle motion blur, even simple animations can feel significantly more dynamic. const x = useMotionValue(0) const v = useVelocity(x) const scaleX = useTransform(v, [-1200, 0, 1200], [1.8, 1, 1.8]) const blur = useTransform(v, [-1200, 0, 1200], [3, 0, 3]) `blur(${b}px)`), }} />

89,615 просмотров

Design Engineering Tip: Don’t reveal a grid all at once. Use stagger() to give every item a tiny delay. You can add an extra motion detail to give the reveal more character, like this tiny swing. import { stagger } from "motion" animateView(update) .add(".item") .enter( { opacity: [0, 1], y: [12, 0], rotate: [-2, 0] }, { delay: stagger(0.05, { from: "center" }) } )

Design Engineering Tip: Don’t reveal a grid all at once. Use stagger() to give every item a tiny delay. You can add an extra motion detail to give the reveal more character, like this tiny swing. import { stagger } from "motion" animateView(update) .add(".item") .enter( { opacity: [0, 1], y: [12, 0], rotate: [-2, 0] }, { delay: stagger(0.05, { from: "center" }) } )

61,602 просмотров

Design Engineering Tip: If you struggle to describe button or card hover states in Claude or Codex, these commonly used hover effect terms can help.

Design Engineering Tip: If you struggle to describe button or card hover states in Claude or Codex, these commonly used hover effect terms can help.

37,427 просмотров

Design Engineering Tip Consider letting textareas grow with the content instead of introducing nested scrolling. It often creates a smoother writing experience and keeps forms easier to scan. CSS: textarea { field-sizing: content; }

Design Engineering Tip Consider letting textareas grow with the content instead of introducing nested scrolling. It often creates a smoother writing experience and keeps forms easier to scan. CSS: textarea { field-sizing: content; }

86,969 просмотров

Design Engineering Tip: Reduce backdrop blur while the user scrolls fast. Heavy blur during motion destroys perceived smoothness and increases GPU workload. Lowering blur dynamically keeps interfaces crisp while also improving performance. let t; const nav = document.querySelector(".navbar"); window.addEventListener("scroll", () => { nav. style.backdropFilter = "blur(8px)"; clearTimeout(t); t = setTimeout(() => { nav. style.backdropFilter = "blur(24px)"; }, 120); });

Design Engineering Tip: Reduce backdrop blur while the user scrolls fast. Heavy blur during motion destroys perceived smoothness and increases GPU workload. Lowering blur dynamically keeps interfaces crisp while also improving performance. let t; const nav = document.querySelector(".navbar"); window.addEventListener("scroll", () => { nav. style.backdropFilter = "blur(8px)"; clearTimeout(t); t = setTimeout(() => { nav. style.backdropFilter = "blur(24px)"; }, 120); });

88,250 просмотров

Design Engineering Tip If your modal scrolls like this, you’re probably missing one CSS property: overscroll-behavior: contain; It prevents the page behind the modal from scrolling when users reach the top or bottom.

Design Engineering Tip If your modal scrolls like this, you’re probably missing one CSS property: overscroll-behavior: contain; It prevents the page behind the modal from scrolling when users reach the top or bottom.

29,144 просмотров

Design Engineering Tip Make hover interactions respond to where the cursor actually comes from. Instead of revealing content with the same animation every time, detect the cursor entry direction and move the image + content accordingly. It makes a simple card feel much more spatial and responsive. const direction = getDirection(event, ref.current); const variants = { top: { y: 20 }, bottom: { y: -20 }, left: { x: 20 }, right: { x: -20 }, };

Design Engineering Tip Make hover interactions respond to where the cursor actually comes from. Instead of revealing content with the same animation every time, detect the cursor entry direction and move the image + content accordingly. It makes a simple card feel much more spatial and responsive. const direction = getDirection(event, ref.current); const variants = { top: { y: 20 }, bottom: { y: -20 }, left: { x: 20 }, right: { x: -20 }, };

17,606 просмотров

With Claude Fable 5 making software creation more accessible, interaction design is becoming an even bigger differentiator. So here is a Design Engineering Tip: Most interfaces wait for users to act. Better interfaces prepare for what users are about to do. This pattern is called Input Anticipation. By reacting to intent before an interaction happens, products feel faster, smarter, and easier to use. JS const box = document.querySelector(".input") const ring = document.querySelector(".focus-ring") addEventListener("pointermove", (e) => { const r = box.getBoundingClientRect() const dx = Math.max(r.left - e.clientX, 0, e.clientX - r.right) const dy = Math.max(r. top - e.clientY, 0, e.clientY - r.bottom) const distance = Math.hypot(dx, dy) const intent = Math.max(0, 1 - distance / 180) ** 2 ring. style.opacity = intent }) Save this for later.

With Claude Fable 5 making software creation more accessible, interaction design is becoming an even bigger differentiator. So here is a Design Engineering Tip: Most interfaces wait for users to act. Better interfaces prepare for what users are about to do. This pattern is called Input Anticipation. By reacting to intent before an interaction happens, products feel faster, smarter, and easier to use. JS const box = document.querySelector(".input") const ring = document.querySelector(".focus-ring") addEventListener("pointermove", (e) => { const r = box.getBoundingClientRect() const dx = Math.max(r.left - e.clientX, 0, e.clientX - r.right) const dy = Math.max(r. top - e.clientY, 0, e.clientY - r.bottom) const distance = Math.hypot(dx, dy) const intent = Math.max(0, 1 - distance / 180) ** 2 ring. style.opacity = intent }) Save this for later.

39,344 просмотров

Design Engineering Tip: Add friction at the end of a scroll interaction. When users reach the edge of a scrollable area, the movement should not just stop instantly. A subtle resistance, bounce, or slowdown can make the interface feel more physical and less mechanical. It helps users understand that they reached a boundary without needing extra labels or visual indicators. Used carefully, this can make scrolling feel more natural and closer to how objects behave in the real world.

Design Engineering Tip: Add friction at the end of a scroll interaction. When users reach the edge of a scrollable area, the movement should not just stop instantly. A subtle resistance, bounce, or slowdown can make the interface feel more physical and less mechanical. It helps users understand that they reached a boundary without needing extra labels or visual indicators. Used carefully, this can make scrolling feel more natural and closer to how objects behave in the real world.

25,730 просмотров

Design Engineering Tip: If you’re using the same corner radius across your entire UI, try scaling it with the component size: 12px → XS (buttons, tags) 16px → S (cards, inputs) 24px → M (modals, panels) As components get larger, increasing the radius can help preserve the same visual softness and balance.

Design Engineering Tip: If you’re using the same corner radius across your entire UI, try scaling it with the component size: 12px → XS (buttons, tags) 16px → S (cards, inputs) 24px → M (modals, panels) As components get larger, increasing the radius can help preserve the same visual softness and balance.

28,199 просмотров

Kind of crazy that you can just use Codex or Claude and vibe code things like this into existence

Kind of crazy that you can just use Codex or Claude and vibe code things like this into existence

28,018 просмотров

Videos

Больше нет контента для загрузки