Files
chorus-services/modules/teaser/components/ScrollReveal.tsx
tony c8fb816775 feat: Add CHORUS teaser website with mobile-responsive design
- Created complete Next.js 15 teaser website with CHORUS brand styling
- Implemented mobile-responsive 3D logo (128px mobile, 512px desktop)
- Added proper Exo font loading via Next.js Google Fonts for iOS/Chrome compatibility
- Built comprehensive early access form with GDPR compliance and rate limiting
- Integrated PostgreSQL database with complete schema for lead capture
- Added scroll indicators that auto-hide when scrolling begins
- Optimized mobile modal forms with proper scrolling and submit button access
- Deployed via Docker Swarm with Traefik SSL termination at chorus.services
- Includes database migrations, consent tracking, and email notifications

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-08-26 13:57:30 +10:00

62 lines
1.5 KiB
TypeScript

'use client';
import React from 'react';
import { useIntersectionObserver } from '@/hooks/useIntersectionObserver';
interface ScrollRevealProps {
children: React.ReactNode;
delay?: number;
duration?: number;
direction?: 'up' | 'down' | 'left' | 'right';
distance?: number;
className?: string;
}
export default function ScrollReveal({
children,
delay = 0,
duration = 600,
direction = 'up',
distance = 24,
className = '',
}: ScrollRevealProps) {
const { elementRef, isVisible } = useIntersectionObserver({
threshold: 0.1,
rootMargin: '0px 0px -100px 0px',
triggerOnce: true,
});
const getTransform = (visible: boolean) => {
if (visible) return 'translate3d(0, 0, 0)';
switch (direction) {
case 'up':
return `translate3d(0, ${distance}px, 0)`;
case 'down':
return `translate3d(0, -${distance}px, 0)`;
case 'left':
return `translate3d(${distance}px, 0, 0)`;
case 'right':
return `translate3d(-${distance}px, 0, 0)`;
default:
return `translate3d(0, ${distance}px, 0)`;
}
};
const revealStyle = {
opacity: isVisible ? 1 : 0,
transform: getTransform(isVisible),
transition: `opacity ${duration}ms ease-out ${delay}ms, transform ${duration}ms ease-out ${delay}ms`,
willChange: 'opacity, transform',
};
return (
<div
ref={elementRef}
style={revealStyle}
className={`scroll-reveal ${className}`}
>
{children}
</div>
);
}