From e63b9020818a03ba08872033e6a36ccfd07e34c0 Mon Sep 17 00:00:00 2001 From: "diana.dolgolyova" Date: Thu, 19 Mar 2026 14:08:30 +0300 Subject: [PATCH] feat: remove scroll indicator, add auto-scroll from hero to next section - Remove SCROLL chevron button from hero (not needed) - Add wheel/swipe listener that smoothly scrolls to the first section below hero - Works on desktop (wheel) and mobile (touch swipe) Co-Authored-By: Claude Opus 4.6 (1M context) --- src/components/sections/Hero.tsx | 70 ++++++++++++++++++++++++++------ 1 file changed, 58 insertions(+), 12 deletions(-) diff --git a/src/components/sections/Hero.tsx b/src/components/sections/Hero.tsx index 519747b..23e9b76 100644 --- a/src/components/sections/Hero.tsx +++ b/src/components/sections/Hero.tsx @@ -1,9 +1,9 @@ "use client"; +import { useEffect, useRef, useCallback } from "react"; import { Button } from "@/components/ui/Button"; import { FloatingHearts } from "@/components/ui/FloatingHearts"; import { HeroLogo } from "@/components/ui/HeroLogo"; -import { ChevronDown } from "lucide-react"; import type { SiteContent } from "@/types/content"; interface HeroProps { @@ -11,9 +11,65 @@ interface HeroProps { } export function Hero({ data: hero }: HeroProps) { + const sectionRef = useRef(null); + const scrolledRef = useRef(false); + + const scrollToNext = useCallback(() => { + const hero = sectionRef.current; + if (!hero) return; + // Find the next sibling section + let next = hero.nextElementSibling; + while (next && next.tagName !== "SECTION") { + next = next.nextElementSibling; + } + next?.scrollIntoView({ behavior: "smooth" }); + }, []); + + useEffect(() => { + const hero = sectionRef.current; + if (!hero) return; + + function handleWheel(e: WheelEvent) { + // Only trigger when scrolling down and still inside hero + if (e.deltaY <= 0 || scrolledRef.current) return; + if (window.scrollY > 10) return; // already scrolled past hero top + + scrolledRef.current = true; + scrollToNext(); + + // Reset after animation completes + setTimeout(() => { scrolledRef.current = false; }, 1000); + } + + function handleTouchStart(e: TouchEvent) { + (hero as HTMLElement).dataset.touchY = String(e.touches[0].clientY); + } + + function handleTouchEnd(e: TouchEvent) { + const startY = Number((hero as HTMLElement).dataset.touchY); + const endY = e.changedTouches[0].clientY; + const diff = startY - endY; + + // Swipe down (finger moves up) with enough distance + if (diff > 50 && !scrolledRef.current && window.scrollY < 10) { + scrolledRef.current = true; + scrollToNext(); + setTimeout(() => { scrolledRef.current = false; }, 1000); + } + } + + hero.addEventListener("wheel", handleWheel, { passive: true }); + hero.addEventListener("touchstart", handleTouchStart, { passive: true }); + hero.addEventListener("touchend", handleTouchEnd, { passive: true }); + return () => { + hero.removeEventListener("wheel", handleWheel); + hero.removeEventListener("touchstart", handleTouchStart); + hero.removeEventListener("touchend", handleTouchEnd); + }; + }, [scrollToNext]); return ( -
+
{/* Animated gradient background */}
@@ -72,16 +128,6 @@ export function Hero({ data: hero }: HeroProps) {
- {/* Scroll indicator */} -
); }