All checks were successful
Deploy to Production / deploy (push) Successful in 1m0s
Three coordinated tweaks to the landing-page above-the-fold: 1. **Hero padding restored to py-14/sm:py-20/md:py-28** (was py-12/14/16). Compressing it for the scroll-cue position fight made the hero feel cramped and gave the ParticleHero background less room to breathe. With the cue moved out (see #3), there's no reason to shrink the hero. 2. **Step rotator switches to carousel-style horizontal slide.** The AnimatePresence transition was a fade+y-shift cross-fade — clean but sequential. Now the leaving card slides left out (x:-220) while the entering card slides right in (x:220→0), both coexisting in the same 3D-space and inheriting the same mouse-tilt. The container gets `min-h-[240px]` so the absolutely-positioned cards have layout to anchor to (claude_desktop_config.json is the tallest at 7 lines). Reduced-motion still gets the opacity-only cross-fade — sliding content sideways is exactly the kind of motion that preference is meant to suppress. 3. **`<ScrollCue>` extracted into its own client component**, fixed- positioned at viewport bottom (bottom-5) with a frosted pill style. Fades to opacity:0 once `window.scrollY > 80`, so it doesn't shadow the rest of the page. Lives next to `<section>` in page.tsx rather than inside the hero — that way it anchors to the loadscreen's natural bottom edge whether the hero is short or tall. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
44 lines
1.6 KiB
TypeScript
44 lines
1.6 KiB
TypeScript
'use client';
|
|
|
|
import { ChevronDown } from 'lucide-react';
|
|
import { useEffect, useState } from 'react';
|
|
|
|
/**
|
|
* Scroll cue — a fixed pill anchored to the bottom of the viewport that
|
|
* points the visitor down to the flow video below the hero. Fades out
|
|
* once the user has scrolled past the loadscreen so it doesn't follow
|
|
* them around the page.
|
|
*
|
|
* Lives at z-30 so it sits above the hero content but below modals.
|
|
* The frosted pill (backdrop-blur + border) reads clearly against the
|
|
* particle background without stealing focus from the H1.
|
|
*/
|
|
export function ScrollCue({ targetId }: { targetId: string }) {
|
|
const [visible, setVisible] = useState(true);
|
|
|
|
useEffect(() => {
|
|
function onScroll() {
|
|
setVisible(window.scrollY < 80);
|
|
}
|
|
onScroll();
|
|
window.addEventListener('scroll', onScroll, { passive: true });
|
|
return () => window.removeEventListener('scroll', onScroll);
|
|
}, []);
|
|
|
|
return (
|
|
<a
|
|
href={`#${targetId}`}
|
|
aria-label="See the flow in action"
|
|
className={`fixed inset-x-0 bottom-5 z-30 mx-auto flex w-fit items-center gap-1.5 rounded-full border border-[--color-border] px-3 py-1.5 text-[10.5px] uppercase tracking-[0.18em] text-[--color-fg-subtle] backdrop-blur transition-opacity duration-500 hover:text-[--color-fg] ${
|
|
visible ? 'opacity-100' : 'pointer-events-none opacity-0'
|
|
}`}
|
|
style={{
|
|
backgroundColor: 'color-mix(in oklab, var(--color-bg-elevated) 75%, transparent)',
|
|
}}
|
|
>
|
|
<span>see it run</span>
|
|
<ChevronDown size={12} className="animate-bounce" />
|
|
</a>
|
|
);
|
|
}
|