- Shipped
- August 19, 2026 at 8:58 PM UTC
- Author
- Kamo
- Commit
- 6d01ff1
Step C. Neither GSAP nor Framer Motion is on the homepage any more, and the `home` message namespace is no longer sent to the browser at all. JS 241,999 -> 214,135 gzip (15 chunks -> 13) document 53,877 -> 51,797 gzip GSAP was back, and worth naming precisely because nothing about it was visible: 70,712 bytes, pulled in by four decorative wrappers nested inside the sections Step B had just made server components. Two of them did not need a library at all — HoverTransform tweened scale/rotate/y/boxShadow on mouseenter, which is a `:hover` rule, and GradientBorder's GSAP call was a *no-op*: it animated `backgroundPosition` on the flat `#0a0a0a` element that masks the middle of the border, while the gradient anyone can see sits on a different div and was never touched. Its travelling hairline is implemented here for the first time. The other two read pointer coordinates, so they genuinely cannot become CSS — but they also cannot do anything without a pointer, and a phone was downloading 27 KB to run a tilt no touchscreen can trigger. Both now check `(hover: hover) and (pointer: fine)` and `import()` GSAP inside the effect, so it is a lazy chunk on a desktop and absent everywhere else. The desktop effect is unchanged. THE HERO. 657 lines in which nine pieces of state, four effects and three refs sat in the same component as the words, so React hydrated the headline, the lede, the stat rule and the calls to action along with the video player. The state moved to the two places that own it — HeroBackdrop for the photography and its rotation, HeroStage for the reel and its download gating — and the hero itself is a server component. Both islands still server-render their markup, so the LCP element is in the HTML exactly as before and still paints from HTML and CSS alone. Nothing about first paint changed; what changed is what has to be hydrated after it. The background image also lost its translated "Background N" alt in favour of `alt="" aria-hidden`. It is a decorative backdrop — that string described the markup rather than anything a reader needs, and it was the last thing making the element a translation concern. THE NAMESPACE. `home` is 341 keys and 22 KB, and it was serialised into the document for every visitor because a handful of client components read it. FAQ and SignupSection are server components now with their interactive parts split out — an accordion item and a single email field, neither of which needs a word of copy — and ShippedStrip, HeroStage and HeroOfferBanner take their few labels as props. With nothing left on the client reading it, the provider is gone from the route entirely and the strings are resolved once, in the render that produces the HTML. It saves less than the raw figure suggests (~2 KB gzip): the same strings are in the HTML beside it, so the copy compressed well. It is still the right shape — nothing should be sending a page's entire dictionary to a browser that has already been sent the page. Every analytics event still fires: seven names, all verified in the built markup, with the hero's two now `data-track` alongside the rest.