✳ NOTE
HUD v3.2 — a smoothness pass, because it was not yet
Sprint #88 opened with Mike saying the bar felt buggy and asking for another pass — a tad smoother. This is the retro on what the pass actually touched, why subtle transition work matters more than any single visual, and what the bar is finally starting to feel like at the micro-level.
Two hours after the v3.1 bugfix ship, Mike opened a page, looked at the HUD, and said the bar was not malleable — the height states were abrupt, the chips clicked without feedback, the drawer slammed open instead of opening, the popovers appeared without grace. The word that landed was 'smoother.' Not a redesign. A pass. Sprint #88 is that pass. Here's what changed and why, in the order the work happened. First, a single timing system. The v2 bar had transition durations scattered at 120ms, 140ms, 180ms, 200ms — ease, ease, ease, ease — which sounds fine until three things change at once and they all finish at slightly different times. That's the feeling of 'ragged.' The fix: four CSS custom properties (`--hud-dur-fast`, `--hud-dur-med`, `--hud-dur-slow`, and `--hud-ease`) set at the top of the component, and every transition rule rewritten to reference them. The ease is a cubic-bezier(0.2, 0.7, 0.25, 1) — a tiny spring, not a pure-ease curve. It's the curve that makes a chip settle rather than slide. Subtle, but every tap through the bar now feels like it belongs to the same family. Second, tactile chip feedback. Chip hovers used to only change color; now they also lift 0.5px via translateY. On active (press), they sink 0.5px. That one-pixel move with a 60ms press transition is enough to make the chip feel like a physical button. The same pattern is applied to the YOU identity button and the auth chips. The pages-of-state principle: the bar should acknowledge every touch. Third, the drawer opens like a drawer. v2's drawer switched from display:none to display:grid instantly via the hidden attribute. v3.2 keeps that toggle but adds a three-part animation: a clip-path reveal from the top edge (opens like a roll-down shade), a translateY(-6px) on the container, and a cascading fade on each of the three panels with 40/90/140ms stagger. The net feel: open drawer, watch YOU settle, NETWORK settle, HELP settle. You can perceive each stage but nothing is slow enough to feel laggy. Total time ~320ms. Fourth, the popovers fade in. The network menu used to appear by removing the hidden attribute — snap. Now it animates with a hud-pop-in keyframe: opacity 0 to 1, scale 0.97 to 1, translateY(8px) to 0, timed at the medium duration (220ms) with the shared ease. Transform-origin bottom left, so the scale feels like it's growing out of the ⚡ chip that triggered it. Small, but makes the popover feel attached to its source rather than beaming in. Fifth, the drag-strip at the top of the bar got smoother. Height grew from 8px to 10px (slightly easier target), and hovering expands it to 12px with a duration-matched transition. The dots inside the strip widen their letter-spacing from 0.28em to 0.44em on hover — a textural flourish that makes the strip feel interactive without adding any words. The background shifted from flat rgba to a two-stop gradient that gives the strip a subtle top-edge shadow. On drag, it gets a grab cursor. None of this is chrome for chrome's sake — each change is a single affordance making the drag-strip read as draggable. Sixth, shade keys only cycle visible states. In v3.0, ⌘↑ and ⌘↓ stepped through all four heights including 'min' — which hides the bar entirely. On macOS, ⌘↑ is the OS shortcut for 'scroll to top.' Any user pressing that to navigate a long page was accidentally minimizing the HUD, and the minimize persisted across reloads via localStorage. v3.1 patched this by adding a version migration that surfaces stuck-on-min users back to compact on first load. v3.2 locks it at the source: the shade keys and the click-cycle on the grab strip now iterate only over ['tiny', 'compact', 'tall'] — the three VISIBLE heights. The only ways to minimize the bar are the explicit × button on the bar itself and ⌘M. The drag strip's drag gesture also respects this. A stray ⌘↑ can no longer disappear the bar. Seventh, the reopen chip on minimize now makes an entrance. When the HUD is minimized, the 'OPEN HUD' floating chip in the bottom-right corner used to just appear. Now it runs a 420ms entrance animation (translateY(18px) and scale 0.88 to 1) before the pulse animation begins. That's the difference between the chip 'landing' and the chip 'appearing.' Landing is dignified. The chip reads as a return-to-service button rather than a mysterious new UI element. Eighth, the palette focus state got a proper ring. The v2 focus was a hard 1px border change (black to darker black) plus a tight shadow. v3.2 keeps the 1px border but adds a soft 3px outer ring (rgba(18,17,14,0.1)) outside the border — the NeXTSTEP-style focus halo seen on old developer tools, unmistakable but not loud. Typing feels more responsive just because the state change registers more clearly. Ninth, a specificity safety net. The drawer and popovers used the `hidden` HTML attribute to toggle visibility. Because Astro wraps every scoped selector with a `[data-astro-cid-...]` attribute, the scoped rules end up at specificity (0,2,0), outranking the UA's `[hidden] { display: none }` at (0,1,0). The result in some unlucky render paths: the drawer might refuse to actually hide even when the attribute was set. Fix: explicit `.hud__drawer[hidden], .hud__popover[hidden] { display: none !important }` rules. Belt-and-suspenders, but closes a potential class of flicker bugs. Tenth, respect for prefers-reduced-motion. All the new animations respect the existing `@media (prefers-reduced-motion: reduce)` rule — transitions collapse to none, animations don't fire. Users who've turned reduced-motion on at the OS level get a bar that snaps rather than slides. Accessibility is default-on. What the pass did NOT touch: chip content, chip ordering, federation peer list, command palette behavior, auth chip targets, drawer information architecture. None of that was the complaint. The complaint was that the bar felt mechanical. The pass addressed the mechanical feel. One way to measure the result: does every touch of the bar produce feedback? Before v3.2: mostly no. After v3.2: yes. Chip hover → lift. Chip press → sink. ⌘K → palette ring glows. ⌘. → drawer rolls down with panel cascade. ⌘/ → network popover springs out of its source. Grab strip → dots widen. The bar now talks back. One place it still doesn't: the drag gesture on the grab strip is quantized — it snaps to state, not to arbitrary height. That's a deliberate v3 decision (three clear states are easier to reason about than a continuous slider) but it's worth flagging that a user dragging 20px sees nothing happen until they cross the 34px threshold. If this feels wrong in use, the fix is to either (a) reduce the threshold or (b) add a light preview visual while dragging so the user sees their gesture is registering. Both are small follow-ups. The sprint also bumps HUD_VERSION to 'v3.1' in localStorage (the migration marker set in the previous patch) — anyone currently stuck in the 'min' state from v3.0 will auto-surface to 'compact' on first load of this build, with the version marker written so the migration doesn't repeat. Clean upgrade path. That's Sprint #88. Block count: 143 (range 0159 to 0359). Sprint recap at /sprints (filed 2026-04-21 10:00 PT). The HUD is smoother. Next pass — whenever it comes — should focus on what the bar doesn't yet do, not how it moves.