 f343f89d24
			
		
	
	f343f89d24
	
	
	
		
			
			Complete Next.js website with Docker containerization: - Next.js 14 with TypeScript and Tailwind CSS - Responsive design with modern UI components - Hero section, features showcase, testimonials - FAQ section with comprehensive content - Contact forms and newsletter signup - Docker production build with Nginx - Health checks and monitoring support - SEO optimization and performance tuning Ready for integration as git submodule in main CHORUS project. Generated with Claude Code Co-Authored-By: Claude <noreply@anthropic.com>
		
			
				
	
	
		
			644 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
			
		
		
	
	
			644 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
| import { Variants } from 'framer-motion';
 | |
| 
 | |
| /**
 | |
|  * Common animation variants for Framer Motion
 | |
|  * Provides consistent animations across the application
 | |
|  */
 | |
| 
 | |
| export const fadeInUp: Variants = {
 | |
|   hidden: {
 | |
|     opacity: 0,
 | |
|     y: 30,
 | |
|   },
 | |
|   visible: {
 | |
|     opacity: 1,
 | |
|     y: 0,
 | |
|     transition: {
 | |
|       duration: 0.6,
 | |
|       ease: 'easeOut',
 | |
|     },
 | |
|   },
 | |
| };
 | |
| 
 | |
| export const fadeInDown: Variants = {
 | |
|   hidden: {
 | |
|     opacity: 0,
 | |
|     y: -30,
 | |
|   },
 | |
|   visible: {
 | |
|     opacity: 1,
 | |
|     y: 0,
 | |
|     transition: {
 | |
|       duration: 0.6,
 | |
|       ease: 'easeOut',
 | |
|     },
 | |
|   },
 | |
| };
 | |
| 
 | |
| export const fadeInLeft: Variants = {
 | |
|   hidden: {
 | |
|     opacity: 0,
 | |
|     x: -30,
 | |
|   },
 | |
|   visible: {
 | |
|     opacity: 1,
 | |
|     x: 0,
 | |
|     transition: {
 | |
|       duration: 0.6,
 | |
|       ease: 'easeOut',
 | |
|     },
 | |
|   },
 | |
| };
 | |
| 
 | |
| export const fadeInRight: Variants = {
 | |
|   hidden: {
 | |
|     opacity: 0,
 | |
|     x: 30,
 | |
|   },
 | |
|   visible: {
 | |
|     opacity: 1,
 | |
|     x: 0,
 | |
|     transition: {
 | |
|       duration: 0.6,
 | |
|       ease: 'easeOut',
 | |
|     },
 | |
|   },
 | |
| };
 | |
| 
 | |
| export const fadeIn: Variants = {
 | |
|   hidden: {
 | |
|     opacity: 0,
 | |
|   },
 | |
|   visible: {
 | |
|     opacity: 1,
 | |
|     transition: {
 | |
|       duration: 0.6,
 | |
|       ease: 'easeOut',
 | |
|     },
 | |
|   },
 | |
| };
 | |
| 
 | |
| export const scaleIn: Variants = {
 | |
|   hidden: {
 | |
|     opacity: 0,
 | |
|     scale: 0.8,
 | |
|   },
 | |
|   visible: {
 | |
|     opacity: 1,
 | |
|     scale: 1,
 | |
|     transition: {
 | |
|       duration: 0.6,
 | |
|       ease: 'easeOut',
 | |
|     },
 | |
|   },
 | |
| };
 | |
| 
 | |
| export const slideInUp: Variants = {
 | |
|   hidden: {
 | |
|     y: '100%',
 | |
|     opacity: 0,
 | |
|   },
 | |
|   visible: {
 | |
|     y: '0%',
 | |
|     opacity: 1,
 | |
|     transition: {
 | |
|       duration: 0.6,
 | |
|       ease: 'easeOut',
 | |
|     },
 | |
|   },
 | |
| };
 | |
| 
 | |
| export const slideInDown: Variants = {
 | |
|   hidden: {
 | |
|     y: '-100%',
 | |
|     opacity: 0,
 | |
|   },
 | |
|   visible: {
 | |
|     y: '0%',
 | |
|     opacity: 1,
 | |
|     transition: {
 | |
|       duration: 0.6,
 | |
|       ease: 'easeOut',
 | |
|     },
 | |
|   },
 | |
| };
 | |
| 
 | |
| export const staggerContainer: Variants = {
 | |
|   hidden: {},
 | |
|   visible: {
 | |
|     transition: {
 | |
|       staggerChildren: 0.1,
 | |
|       delayChildren: 0.1,
 | |
|     },
 | |
|   },
 | |
| };
 | |
| 
 | |
| export const staggerFast: Variants = {
 | |
|   hidden: {},
 | |
|   visible: {
 | |
|     transition: {
 | |
|       staggerChildren: 0.05,
 | |
|     },
 | |
|   },
 | |
| };
 | |
| 
 | |
| export const staggerSlow: Variants = {
 | |
|   hidden: {},
 | |
|   visible: {
 | |
|     transition: {
 | |
|       staggerChildren: 0.2,
 | |
|     },
 | |
|   },
 | |
| };
 | |
| 
 | |
| // Hover animations
 | |
| export const hoverScale: Variants = {
 | |
|   hover: {
 | |
|     scale: 1.05,
 | |
|     transition: {
 | |
|       duration: 0.2,
 | |
|       ease: 'easeInOut',
 | |
|     },
 | |
|   },
 | |
| };
 | |
| 
 | |
| export const hoverLift: Variants = {
 | |
|   hover: {
 | |
|     y: -5,
 | |
|     transition: {
 | |
|       duration: 0.2,
 | |
|       ease: 'easeInOut',
 | |
|     },
 | |
|   },
 | |
| };
 | |
| 
 | |
| export const hoverGlow: Variants = {
 | |
|   hover: {
 | |
|     boxShadow: '0 0 30px rgba(0, 122, 255, 0.3)',
 | |
|     transition: {
 | |
|       duration: 0.3,
 | |
|       ease: 'easeInOut',
 | |
|     },
 | |
|   },
 | |
| };
 | |
| 
 | |
| // Specialized animations for CHORUS components
 | |
| export const orchestrationFlow: Variants = {
 | |
|   hidden: {
 | |
|     pathLength: 0,
 | |
|     opacity: 0,
 | |
|   },
 | |
|   visible: {
 | |
|     pathLength: 1,
 | |
|     opacity: 1,
 | |
|     transition: {
 | |
|       pathLength: {
 | |
|         duration: 2,
 | |
|         ease: 'easeInOut',
 | |
|       },
 | |
|       opacity: {
 | |
|         duration: 0.3,
 | |
|       },
 | |
|     },
 | |
|   },
 | |
| };
 | |
| 
 | |
| export const dataFlow: Variants = {
 | |
|   hidden: {
 | |
|     opacity: 0,
 | |
|     scale: 0,
 | |
|   },
 | |
|   visible: (i: number) => ({
 | |
|     opacity: 1,
 | |
|     scale: 1,
 | |
|     transition: {
 | |
|       delay: i * 0.2,
 | |
|       duration: 0.5,
 | |
|       ease: 'easeOut',
 | |
|     },
 | |
|   }),
 | |
| };
 | |
| 
 | |
| export const pulseAnimation: Variants = {
 | |
|   pulse: {
 | |
|     scale: [1, 1.1, 1],
 | |
|     opacity: [1, 0.8, 1],
 | |
|     transition: {
 | |
|       duration: 2,
 | |
|       repeat: Infinity,
 | |
|       ease: 'easeInOut',
 | |
|     },
 | |
|   },
 | |
| };
 | |
| 
 | |
| export const rotateAnimation: Variants = {
 | |
|   rotate: {
 | |
|     rotate: 360,
 | |
|     transition: {
 | |
|       duration: 2,
 | |
|       repeat: Infinity,
 | |
|       ease: 'linear',
 | |
|     },
 | |
|   },
 | |
| };
 | |
| 
 | |
| // Page transition animations
 | |
| export const pageTransition: Variants = {
 | |
|   initial: {
 | |
|     opacity: 0,
 | |
|     y: 20,
 | |
|   },
 | |
|   animate: {
 | |
|     opacity: 1,
 | |
|     y: 0,
 | |
|     transition: {
 | |
|       duration: 0.4,
 | |
|       ease: 'easeOut',
 | |
|     },
 | |
|   },
 | |
|   exit: {
 | |
|     opacity: 0,
 | |
|     y: -20,
 | |
|     transition: {
 | |
|       duration: 0.3,
 | |
|       ease: 'easeIn',
 | |
|     },
 | |
|   },
 | |
| };
 | |
| 
 | |
| // Modal animations
 | |
| export const modalBackdrop: Variants = {
 | |
|   hidden: {
 | |
|     opacity: 0,
 | |
|   },
 | |
|   visible: {
 | |
|     opacity: 1,
 | |
|     transition: {
 | |
|       duration: 0.3,
 | |
|     },
 | |
|   },
 | |
| };
 | |
| 
 | |
| export const modalContent: Variants = {
 | |
|   hidden: {
 | |
|     opacity: 0,
 | |
|     scale: 0.8,
 | |
|     y: 50,
 | |
|   },
 | |
|   visible: {
 | |
|     opacity: 1,
 | |
|     scale: 1,
 | |
|     y: 0,
 | |
|     transition: {
 | |
|       duration: 0.4,
 | |
|       ease: 'easeOut',
 | |
|     },
 | |
|   },
 | |
| };
 | |
| 
 | |
| // Loading animations
 | |
| export const spinnerAnimation: Variants = {
 | |
|   spin: {
 | |
|     rotate: 360,
 | |
|     transition: {
 | |
|       duration: 1,
 | |
|       repeat: Infinity,
 | |
|       ease: 'linear',
 | |
|     },
 | |
|   },
 | |
| };
 | |
| 
 | |
| export const dotsLoading: Variants = {
 | |
|   loading: {
 | |
|     scale: [1, 1.2, 1],
 | |
|     opacity: [1, 0.6, 1],
 | |
|     transition: {
 | |
|       duration: 0.8,
 | |
|       repeat: Infinity,
 | |
|       ease: 'easeInOut',
 | |
|     },
 | |
|   },
 | |
| };
 | |
| 
 | |
| // Apple-inspired easing curves
 | |
| export const appleEasing = [0.21, 1.11, 0.81, 0.99]; // Apple's signature cubic-bezier
 | |
| export const appleSpring = {
 | |
|   type: 'spring',
 | |
|   stiffness: 400,
 | |
|   damping: 30,
 | |
|   mass: 1,
 | |
| };
 | |
| 
 | |
| // Advanced parallax animations
 | |
| export const parallaxSlow: Variants = {
 | |
|   hidden: { y: 0, opacity: 0 },
 | |
|   visible: { 
 | |
|     y: 0, 
 | |
|     opacity: 1,
 | |
|     transition: {
 | |
|       duration: 1,
 | |
|       ease: appleEasing,
 | |
|     },
 | |
|   },
 | |
| };
 | |
| 
 | |
| export const parallaxMedium: Variants = {
 | |
|   hidden: { y: 0, opacity: 0 },
 | |
|   visible: { 
 | |
|     y: 0, 
 | |
|     opacity: 1,
 | |
|     transition: {
 | |
|       duration: 0.8,
 | |
|       ease: appleEasing,
 | |
|     },
 | |
|   },
 | |
| };
 | |
| 
 | |
| export const parallaxFast: Variants = {
 | |
|   hidden: { y: 0, opacity: 0 },
 | |
|   visible: { 
 | |
|     y: 0, 
 | |
|     opacity: 1,
 | |
|     transition: {
 | |
|       duration: 0.6,
 | |
|       ease: appleEasing,
 | |
|     },
 | |
|   },
 | |
| };
 | |
| 
 | |
| // Gradient text animation
 | |
| export const gradientTextAnimation: Variants = {
 | |
|   initial: {
 | |
|     backgroundPosition: '0% 50%',
 | |
|   },
 | |
|   animate: {
 | |
|     backgroundPosition: ['0% 50%', '100% 50%', '0% 50%'],
 | |
|     transition: {
 | |
|       duration: 5,
 | |
|       repeat: Infinity,
 | |
|       ease: 'easeInOut',
 | |
|     },
 | |
|   },
 | |
| };
 | |
| 
 | |
| // Advanced button hover states
 | |
| export const appleButtonHover: Variants = {
 | |
|   initial: {
 | |
|     scale: 1,
 | |
|     boxShadow: '0 4px 14px 0 rgba(0, 122, 255, 0.25)',
 | |
|   },
 | |
|   hover: {
 | |
|     scale: 1.05,
 | |
|     boxShadow: '0 8px 25px 0 rgba(0, 122, 255, 0.4)',
 | |
|     transition: {
 | |
|       duration: 0.2,
 | |
|       ease: 'easeOut',
 | |
|     },
 | |
|   },
 | |
|   tap: {
 | |
|     scale: 0.98,
 | |
|     transition: {
 | |
|       duration: 0.1,
 | |
|     },
 | |
|   },
 | |
| };
 | |
| 
 | |
| // Hero entrance animations
 | |
| export const heroEntrance: Variants = {
 | |
|   hidden: {
 | |
|     opacity: 0,
 | |
|     y: 60,
 | |
|     scale: 0.95,
 | |
|   },
 | |
|   visible: {
 | |
|     opacity: 1,
 | |
|     y: 0,
 | |
|     scale: 1,
 | |
|     transition: {
 | |
|       duration: 0.8,
 | |
|       ease: appleEasing,
 | |
|     },
 | |
|   },
 | |
| };
 | |
| 
 | |
| // Staggered hero container
 | |
| export const heroStaggerContainer: Variants = {
 | |
|   hidden: {},
 | |
|   visible: {
 | |
|     transition: {
 | |
|       staggerChildren: 0.2,
 | |
|       delayChildren: 0.3,
 | |
|     },
 | |
|   },
 | |
| };
 | |
| 
 | |
| // Floating elements animation
 | |
| export const floatingAnimation: Variants = {
 | |
|   initial: {
 | |
|     y: 0,
 | |
|     rotate: 0,
 | |
|   },
 | |
|   animate: {
 | |
|     y: [-10, 10, -10],
 | |
|     rotate: [-2, 2, -2],
 | |
|     transition: {
 | |
|       duration: 6,
 | |
|       repeat: Infinity,
 | |
|       ease: 'easeInOut',
 | |
|     },
 | |
|   },
 | |
| };
 | |
| 
 | |
| // Geometric shape animations
 | |
| export const geometricShapeAnimation: Variants = {
 | |
|   initial: {
 | |
|     scale: 1,
 | |
|     opacity: 0.2,
 | |
|     rotate: 0,
 | |
|   },
 | |
|   animate: {
 | |
|     scale: [1, 1.5, 1],
 | |
|     opacity: [0.2, 0.8, 0.2],
 | |
|     rotate: [0, 360],
 | |
|     transition: {
 | |
|       duration: 8,
 | |
|       repeat: Infinity,
 | |
|       ease: 'easeInOut',
 | |
|     },
 | |
|   },
 | |
| };
 | |
| 
 | |
| // Interactive hover glow effect
 | |
| export const interactiveGlow: Variants = {
 | |
|   initial: {
 | |
|     boxShadow: '0 0 0 rgba(0, 122, 255, 0)',
 | |
|   },
 | |
|   hover: {
 | |
|     boxShadow: '0 0 30px rgba(0, 122, 255, 0.3)',
 | |
|     transition: {
 | |
|       duration: 0.3,
 | |
|       ease: 'easeOut',
 | |
|     },
 | |
|   },
 | |
| };
 | |
| 
 | |
| // Advanced scroll-triggered animations
 | |
| export const scrollReveal: Variants = {
 | |
|   hidden: {
 | |
|     opacity: 0,
 | |
|     y: 75,
 | |
|     scale: 0.9,
 | |
|   },
 | |
|   visible: {
 | |
|     opacity: 1,
 | |
|     y: 0,
 | |
|     scale: 1,
 | |
|     transition: {
 | |
|       duration: 0.8,
 | |
|       ease: appleEasing,
 | |
|     },
 | |
|   },
 | |
| };
 | |
| 
 | |
| // Performance-optimized fade variants
 | |
| export const performantFade: Variants = {
 | |
|   hidden: {
 | |
|     opacity: 0,
 | |
|     transform: 'translateY(20px) translateZ(0)',
 | |
|   },
 | |
|   visible: {
 | |
|     opacity: 1,
 | |
|     transform: 'translateY(0px) translateZ(0)',
 | |
|     transition: {
 | |
|       duration: 0.6,
 | |
|       ease: appleEasing,
 | |
|     },
 | |
|   },
 | |
| };
 | |
| 
 | |
| // Utility functions for animations
 | |
| export const createStaggeredAnimation = (
 | |
|   baseAnimation: Variants,
 | |
|   staggerDelay: number = 0.1
 | |
| ): Variants => ({
 | |
|   ...baseAnimation,
 | |
|   visible: {
 | |
|     ...baseAnimation.visible,
 | |
|     transition: {
 | |
|       ...baseAnimation.visible?.transition,
 | |
|       staggerChildren: staggerDelay,
 | |
|     },
 | |
|   },
 | |
| });
 | |
| 
 | |
| export const createDelayedAnimation = (
 | |
|   baseAnimation: Variants,
 | |
|   delay: number
 | |
| ): Variants => ({
 | |
|   ...baseAnimation,
 | |
|   visible: {
 | |
|     ...baseAnimation.visible,
 | |
|     transition: {
 | |
|       ...baseAnimation.visible?.transition,
 | |
|       delay,
 | |
|     },
 | |
|   },
 | |
| });
 | |
| 
 | |
| export const createCustomEasing = (
 | |
|   baseAnimation: Variants,
 | |
|   ease: string | number[]
 | |
| ): Variants => ({
 | |
|   ...baseAnimation,
 | |
|   visible: {
 | |
|     ...baseAnimation.visible,
 | |
|     transition: {
 | |
|       ...baseAnimation.visible?.transition,
 | |
|       ease,
 | |
|     },
 | |
|   },
 | |
| });
 | |
| 
 | |
| // Parallax utility function
 | |
| export const createParallaxAnimation = (
 | |
|   speed: number,
 | |
|   direction: 'up' | 'down' | 'left' | 'right' = 'up'
 | |
| ) => {
 | |
|   const axis = direction === 'left' || direction === 'right' ? 'x' : 'y';
 | |
|   const multiplier = direction === 'down' || direction === 'right' ? 1 : -1;
 | |
|   
 | |
|   return {
 | |
|     [axis]: `${speed * multiplier * 100}px`,
 | |
|   };
 | |
| };
 | |
| 
 | |
| // Scroll-based animation utility
 | |
| export const createScrollAnimation = (
 | |
|   element: React.RefObject<HTMLElement>,
 | |
|   options: {
 | |
|     start?: number;
 | |
|     end?: number;
 | |
|     property: string;
 | |
|     from: any;
 | |
|     to: any;
 | |
|   }
 | |
| ) => {
 | |
|   // This would be used with useScroll and useTransform hooks
 | |
|   return {
 | |
|     scrollTrigger: {
 | |
|       trigger: element.current,
 | |
|       start: options.start || 0,
 | |
|       end: options.end || 1000,
 | |
|       scrub: true,
 | |
|     },
 | |
|     [options.property]: [options.from, options.to],
 | |
|   };
 | |
| };
 | |
| 
 | |
| // Reduced motion variants for accessibility
 | |
| export const createReducedMotionVariant = (baseVariant: Variants): Variants => {
 | |
|   const prefersReducedMotion = typeof window !== 'undefined' && 
 | |
|     window.matchMedia('(prefers-reduced-motion: reduce)').matches;
 | |
|   
 | |
|   if (prefersReducedMotion) {
 | |
|     return {
 | |
|       ...baseVariant,
 | |
|       visible: {
 | |
|         ...baseVariant.visible,
 | |
|         transition: {
 | |
|           duration: 0.01, // Nearly instant
 | |
|         },
 | |
|       },
 | |
|     };
 | |
|   }
 | |
|   
 | |
|   return baseVariant;
 | |
| };
 | |
| 
 | |
| // Apple-style elastic animation
 | |
| export const elasticAnimation = {
 | |
|   type: 'spring',
 | |
|   stiffness: 500,
 | |
|   damping: 25,
 | |
|   mass: 0.8,
 | |
| };
 | |
| 
 | |
| // Magnetic effect for interactive elements
 | |
| export const magneticEffect = {
 | |
|   hover: {
 | |
|     scale: 1.1,
 | |
|     transition: {
 | |
|       type: 'spring',
 | |
|       stiffness: 400,
 | |
|       damping: 10,
 | |
|     },
 | |
|   },
 | |
|   tap: {
 | |
|     scale: 0.95,
 | |
|     transition: {
 | |
|       type: 'spring',
 | |
|       stiffness: 600,
 | |
|       damping: 15,
 | |
|     },
 | |
|   },
 | |
| }; |