← home

Sidebar Nav Animations

Tap the hamburger menu or use the buttons below.

Before

Overlay snaps · nav items appear instantly

Ren Volume I: Summer SolsticeJun 22
Dear NennyJun 14
Links, June 2026Jun 1
Site UpdatesMay 16
Agent SkillsMay 16
Websites I AppreciateMay 16

After

Overlay fades · ribbon springs · nav staggers

Ren Volume I: Summer SolsticeJun 22
Dear NennyJun 14
Links, June 2026Jun 1
Site UpdatesMay 16
Agent SkillsMay 16
Websites I AppreciateMay 16
About
Bookshelf
Notes
Writing

Tune "After" Parameters

Spring

Stiffness400
Damping28

Ribbon

Delay0.45s

Nav Items

Stagger0.04s
Init delay0.18s
Blur4px

Overlay

// Before — overlay snaps in with no transition
<div className={`fixed inset-0 bg-black/50
  ${isOpen ? "opacity-100" : "opacity-0 pointer-events-none"}`} />

// After — overlay fades in over 300ms
<div className={`fixed inset-0 bg-black/50
  transition-opacity duration-300 ease-in-out
  ${isOpen ? "opacity-100" : "opacity-0 pointer-events-none"}`} />

Nav + Ribbon

// Before — plain nav, items appear instantly
<nav>
  {tabs.map((tab) => <button key={tab}>{tab}</button>)}
</nav>

// After — spring stagger with blur
<motion.nav
  animate={isOpen ? "open" : "closed"}
  variants={{
    open: {
      transition: {
        staggerChildren: 0.04,
        delayChildren: 0.18,
      },
    },
  }}
>
  {tabs.map((tab) => (
    <motion.button
      key={tab}
      variants={{
        open: {
          opacity: 1, filter: "blur(0px)", y: 0,
          transition: { type: "spring", stiffness: 400, damping: 28 },
        },
        closed: { opacity: 0, filter: "blur(4px)", y: -4 },
      }}
    />
  ))}
</motion.nav>

// Ribbon — springs in after drawer settles
<motion.div
  animate={{ scaleY: isOpen ? 1 : 0 }}
  style={{ transformOrigin: "top center" }}
  transition={{ type: "spring", stiffness: 400, damping: 28, delay: 0.45 }}
/>