Building a PWA and the bottom sheet is the make-or-break interaction. The generated versions animated height (janky), had no drag affordance, and snapped instantly instead of easing, so it felt like a web page, not an app.
I rewrote the prompt to demand transform: translateY for the open/close (never height), a spring-ish easing, a visible grab handle, safe-area insets for the notch, and a reduced-motion path that just toggles visibility. I'm doing the drag-to-dismiss with a tiny bit of JS but the resting animation is all CSS.
Still 0 answers, but posting the prompt because the translate-not-height rule alone fixed the jank.
Create a mobile bottom-sheet component (HTML + CSS, minimal JS only for open/close toggling). Requirements:
- Open/close animates `transform: translateY(100%) -> translateY(0)`, NEVER `height`, `top`, or `bottom`. Backdrop fades via `opacity`.
- Easing: `cubic-bezier(0.32, 0.72, 0, 1)` (feels like an iOS spring settle), duration 320ms open / 260ms close.
- Visible drag affordance: a 36x4px rounded grab handle centered at the top with adequate padding as a 44px touch target.
- Respect the notch: `padding-bottom: max(16px, env(safe-area-inset-bottom))`.
- Rounded top corners only, subtle top shadow, `max-height: 90dvh`, internal content scrolls with `overscroll-behavior: contain`.
- Trap nothing you don't have to, but move focus to the sheet on open and restore it on close.
- `@media (prefers-reduced-motion: reduce)`: no slide, just toggle `display`/opacity.
Output HTML, CSS, and the ~15 lines of JS for the open/close toggle. Comment why translateY beats animating height here.