1+ // ==============================================
2+ // MOBILE MENU TOGGLE
3+ // ==============================================
4+ const menuToggle = document . getElementById ( 'menuToggle' ) ;
5+ const navMenu = document . getElementById ( 'navMenu' ) ;
6+
7+ menuToggle . addEventListener ( 'click' , ( ) => {
8+ navMenu . classList . toggle ( 'active' ) ;
9+
10+ const icon = menuToggle . querySelector ( 'i' ) ;
11+ if ( navMenu . classList . contains ( 'active' ) ) {
12+ icon . classList . remove ( 'bi-list' ) ;
13+ icon . classList . add ( 'bi-x' ) ;
14+ } else {
15+ icon . classList . remove ( 'bi-x' ) ;
16+ icon . classList . add ( 'bi-list' ) ;
17+ }
18+ } ) ;
19+
20+ // Close menu when clicking on a link
21+ document . querySelectorAll ( '.nav-link' ) . forEach ( link => {
22+ link . addEventListener ( 'click' , ( ) => {
23+ navMenu . classList . remove ( 'active' ) ;
24+ const icon = menuToggle . querySelector ( 'i' ) ;
25+ icon . classList . remove ( 'bi-x' ) ;
26+ icon . classList . add ( 'bi-list' ) ;
27+ } ) ;
28+ } ) ;
29+
30+ // ==============================================
31+ // GSAP SCROLL ANIMATIONS
32+ // ==============================================
33+ gsap . registerPlugin ( ScrollTrigger ) ;
34+
35+ // Animate all elements with 'reveal-up' class
36+ const revealElements = document . querySelectorAll ( '.reveal-up' ) ;
37+
38+ revealElements . forEach ( ( element ) => {
39+ gsap . to ( element , {
40+ scrollTrigger : {
41+ trigger : element ,
42+ start : 'top 85%' ,
43+ end : 'bottom 20%' ,
44+ toggleClass : 'active' ,
45+ once : true
46+ }
47+ } ) ;
48+ } ) ;
49+
50+ // ==============================================
51+ // SMOOTH SCROLL FOR ANCHOR LINKS
52+ // ==============================================
53+ document . querySelectorAll ( 'a[href^="#"]' ) . forEach ( anchor => {
54+ anchor . addEventListener ( 'click' , function ( e ) {
55+ e . preventDefault ( ) ;
56+ const target = document . querySelector ( this . getAttribute ( 'href' ) ) ;
57+
58+ if ( target ) {
59+ const offsetTop = target . offsetTop - 70 ; // Account for fixed header
60+
61+ window . scrollTo ( {
62+ top : offsetTop ,
63+ behavior : 'smooth'
64+ } ) ;
65+ }
66+ } ) ;
67+ } ) ;
68+
69+ // ==============================================
70+ // HEADER BACKGROUND ON SCROLL
71+ // ==============================================
72+ const header = document . querySelector ( '.main-header' ) ;
73+ let lastScrollY = window . scrollY ;
74+
75+ window . addEventListener ( 'scroll' , ( ) => {
76+ const currentScrollY = window . scrollY ;
77+
78+ if ( currentScrollY > lastScrollY && currentScrollY > header . offsetHeight ) {
79+ // Scrolling down
80+ header . classList . add ( 'hidden' ) ;
81+ } else {
82+ // Scrolling up
83+ header . classList . remove ( 'hidden' ) ;
84+ }
85+
86+ if ( currentScrollY > 50 ) {
87+ header . style . background = 'rgba(18, 18, 18, 0.95)' ;
88+ } else {
89+ header . style . background = 'rgba(18, 18, 18, 0.8)' ;
90+ }
91+
92+ lastScrollY = currentScrollY <= 0 ? 0 : currentScrollY ; // For Mobile or negative scrolling
93+ } ) ;
94+
95+ // ==============================================
96+ // FEATURE CARD HOVER EFFECT
97+ // ==============================================
98+
99+ // ==============================================
100+ // CTA SPOTLIGHT EFFECT
101+ // ==============================================
102+ const ctaSection = document . getElementById ( 'cta-section' ) ;
103+
104+ if ( ctaSection ) {
105+ ctaSection . addEventListener ( 'mousemove' , ( e ) => {
106+ const rect = ctaSection . getBoundingClientRect ( ) ;
107+ ctaSection . style . setProperty ( '--x' , `${ e . clientX - rect . left } px` ) ;
108+ ctaSection . style . setProperty ( '--y' , `${ e . clientY - rect . top } px` ) ;
109+ } ) ;
110+ }
111+
112+ // ==============================================
113+ // FAQ ACCORDION
114+ // ==============================================
115+ const faqItems = document . querySelectorAll ( '.faq-item' ) ;
116+
117+ faqItems . forEach ( item => {
118+ const question = item . querySelector ( '.faq-question' ) ;
119+ const answer = item . querySelector ( '.faq-answer' ) ;
120+ const icon = question . querySelector ( 'i' ) ;
121+
122+ question . addEventListener ( 'click' , ( ) => {
123+ const isActive = item . classList . contains ( 'active' ) ;
124+
125+ item . classList . toggle ( 'active' ) ;
126+ icon . classList . toggle ( 'bi-plus-circle' ) ;
127+ icon . classList . toggle ( 'bi-dash-circle' ) ;
128+
129+ if ( item . classList . contains ( 'active' ) ) {
130+ answer . style . maxHeight = answer . scrollHeight + 'px' ;
131+ } else {
132+ answer . style . maxHeight = '0px' ;
133+ }
134+ } ) ;
135+ } ) ;
0 commit comments