Loft
2026-08-04Study 03Interactive study

Two springs, stated — and the flat line danger gets instead.

The bench

Background work sits here. While the drawer is open this whole region is inert — unreachable by pointer, keyboard, and screen reader alike.

Why it feels right

  • The drawer is stiffer and better damped than the toast. Furniture settles with authority; news may carry one visible degree of bounce. Both springs are stated as constants and pinned by the suite.
  • While the drawer is open the background is inert — unreachable by pointer, keyboard, and screen reader. A scrim without inert is theater: it dims the page and leaves every trap in it armed.
  • The destructive confirm mounts with no motion at all. Danger should not bounce; a spring on a delete reads as charm, and charm is the wrong voice for consequence.
  • Toasts cap at three, first in first out. News that has queued behind three newer items is no longer news — a stack that grows without limit is a log wearing a toast's clothes.

Source

/* Two springs, stated and pinned. The drawer is stiffer and better
   damped than the toast: furniture should settle with authority, while
   a toast may carry one visible degree of bounce because it is news. */
export const SPRINGS = {
  drawer: { stiffness: 380, damping: 34 },
  toast: { stiffness: 300, damping: 26 },
} as const;

export type Toast = { id: string; label: string };

export const MAX_VISIBLE = 3;

/* Three toasts, first in first out. A fourth arrival retires the
   oldest: news that has queued behind three newer items is no longer
   news, and a stack that grows without limit is a log, not a toast. */
export function toastQueue(queue: Toast[], next: Toast): Toast[] {
  return [...queue, next].slice(-MAX_VISIBLE);
}
Access
Drawer is a focused dialog; Escape returns focus to its trigger; the background carries the inert attribute while open; each toast is a status output announcing itself.
Reduced motion
Drawer and toasts appear in place; the confirm is unchanged — it never moved.
Budget
300 ms