Renewal of Header Component
ARCHITECTURE •
Situation
The existing header was a conventional sticky navigation bar—functional but unremarkable. Three links (About, Blog, Playground) in a NavigationMenu with responsive drawer for mobile. It worked, but it didn't belong in a project calling itself an "Architectural Playground." The design communicated utility, not experimentation.
Wanted a header that could be three things: an immersive landing experience on home, a compact navigation bar elsewhere, and a transition mask that buys time during route changes. Not three components composed together—one component in different states. The implementation should be invisible; users shouldn't know whether they're seeing scroll-driven or button-triggered animation.
Task
- Design one component with three distinct roles driven by state transitions
- Implement scroll-as-narrative on homepage where interaction IS the experience
- Create seamless deception: identical appearance regardless of activation mechanism (scroll vs. button)
- Use animation timing strategically as loading choreography during route transitions
- Expose structural elements (grid lines as visible layout system)
- Apply minimal affordance: elements exist only when needed
Action
1. Built Working, Then Broke It
Started with intent, not knowledge. Knew the destination—didn't know the library.
Initial implementation functioned on homepage with scroll-driven animation. Direct navigation to /blog exposed the initialization bug: header assumed scroll context always existed. Scroll-vs-button race condition surfaced when rapidly toggling states.
Fixed at the right layer:
- State initialization: Properly handle undefined → collapsed → expanded transitions regardless of entry point
- Scroll lock: Prevent scroll interference during button-triggered transitions
2. Refactored After Understanding
First version worked. Second version was organized.
- Renamed by meaning:
motionStyles.link.bloginstead of generic identifiers - Consolidated animation effects into
useHeaderMotionhook - Internalized triggers: Component owns its state transitions
3. Added Choreography Depth
Single-phase animation became staged narrative: