Shrink header
A fixed header that condenses from full-height and transparent into a compact solid bar on scroll.
API reference
Components
<ShrinkHeader />
The fixed header root. Owns the page useScroll, turns scroll depth into a spring-smoothed condense progress and the derived fill scale / row recentre offset, and publishes them to its parts via context. Its <header> is fixed to the top of the viewport at a constant tallHeight - the height NEVER animates; the fill layer inside it scales instead.
children?
The header contents: a ShrinkHeaderFill and a ShrinkHeaderRow (which wraps your wordmark, nav and CTA).
condenseDistance?
Scroll distance (px) over which the header condenses from transparent and full-height to solid and compact. Defaults to 220.
tallHeight?
The header's constant height (px) at the top of the page. Defaults to 104. Never animates - the fill layer scales instead.
compactHeight?
The fill's visual height (px) once fully condensed. Defaults to 54.
className?
Merged onto the <header> element, last. The header is fixed to the top at full width; use this for a font base, extra z-index, etc.
<ShrinkHeaderFill />
The background-only fill layer. It is aria-hidden (pure chrome, no text), pinned to the header bounds, and scales vertically from its TOP edge (scaleY, origin-top) while fading its opacity in as the header condenses - so the bar visually shrinks from full-height-transparent to compact-solid and its border/shadow/blur "fade in" as one with the fill's own opacity. Both are compositor-only transforms. Must be rendered inside a <ShrinkHeader>.
className?
Merged onto the fill element, last - override the surface, border, shadow or blur here. The defaults (a hairline bottom border, a soft shadow, a backdrop blur and the translucent card tone) are the condensed-bar chrome; pass classes to tune them.
style?
Merged onto the fill element's inline style, last, so a consumer can override the default translucent tone.
<ShrinkHeaderRow />
The content row. Rides a translateY (derived from the same condense progress) so its contents stay vertically centred against the visually-smaller fill as the header condenses. Sits above the fill (z-10) and fills the header height. Must be rendered inside a <ShrinkHeader>.
children?
The row contents: your wordmark, nav and CTA. Scale them yourself off useCondenseProgress so they condense with the bar.
className?
Merged onto the row element, last. Use it for the row's layout - measure, centring, horizontal padding, flex distribution.
Hooks
useCondenseProgress
Returns the enclosing ShrinkHeader's raw condense progress MotionValue (0 at the top of the page, 1 once fully condensed). Scale your own clusters off it - useTransform(condense, [0, 1], [1, 0.82]) for a wordmark that shrinks to 82%, say - or derive any other condense-linked transform. Throws if called outside a ShrinkHeader.
useCondenseProgress(): MotionValue<number>