11document . addEventListener ( 'DOMContentLoaded' , function ( ) {
2- // Elementos DOM
2+ // DOM Elements
33 const navbar = document . querySelector ( '.navbar' ) ;
44 const menuToggle = document . querySelector ( '.menu-toggle' ) ;
55 const navLinksContainer = document . querySelector ( '.nav-links' ) ;
6- const navLinks = document . querySelectorAll ( '.nav-links a:not([data-target=""])' ) ; // Exclui links sem data-target
6+ const navLinks = document . querySelectorAll ( '.nav-links a:not([data-target=""])' ) ; // Excludes links without data-target
77 const contentSections = document . querySelectorAll ( '.content-section' ) ;
88 const heroSection = document . querySelector ( '.hero' ) ;
9-
10- // 1. Efeito de Scroll na Navbar
9+
10+ // 1. Navbar Scroll Effect
11+ // Adds or removes the 'scrolled' class to the navbar depending on scroll position
1112 window . addEventListener ( 'scroll' , function ( ) {
1213 if ( window . scrollY > 50 ) {
1314 navbar . classList . add ( 'scrolled' ) ;
@@ -16,84 +17,85 @@ document.addEventListener('DOMContentLoaded', function() {
1617 }
1718 } ) ;
1819
19- // 2. Menu Mobile
20+ // 2. Mobile Menu Toggle
21+ // Toggles menu visibility on smaller screens
2022 menuToggle . addEventListener ( 'click' , function ( ) {
2123 this . classList . toggle ( 'active' ) ;
2224 navLinksContainer . classList . toggle ( 'active' ) ;
2325 } ) ;
2426
25- // 3. Sistema de Navegação
27+ // 3. Navigation System
2628 function setupNavigation ( ) {
27- // Mostra uma seção específica
29+ // Displays a specific section based on ID
2830 function showSection ( sectionId ) {
29- // Esconde todas as seções
31+ // Hide all sections
3032 contentSections . forEach ( section => {
3133 section . style . display = 'none' ;
3234 } ) ;
33-
34- // Mostra a seção selecionada
35+
36+ // Show selected section
3537 const targetSection = document . getElementById ( sectionId ) ;
3638 if ( targetSection ) {
3739 targetSection . style . display = 'block' ;
38-
39- // Scroll suave para a seção
40+
41+ // Smooth scroll to the section
4042 setTimeout ( ( ) => {
4143 targetSection . scrollIntoView ( { behavior : 'smooth' , block : 'start' } ) ;
4244 } , 50 ) ;
4345 }
44-
45- // Atualiza o link ativo na navbar
46+
47+ // Update active link in navbar
4648 navLinks . forEach ( link => {
4749 link . classList . remove ( 'active' ) ;
4850 if ( link . getAttribute ( 'data-target' ) === sectionId ) {
4951 link . classList . add ( 'active' ) ;
5052 }
5153 } ) ;
52-
53- // Fecha o menu mobile se estiver aberto
54+
55+ // Close mobile menu if open
5456 menuToggle . classList . remove ( 'active' ) ;
5557 navLinksContainer . classList . remove ( 'active' ) ;
5658 }
57-
58- // Configura os eventos de clique nos links
59+
60+ // Set up click events on navigation links
5961 navLinks . forEach ( link => {
6062 link . addEventListener ( 'click' , function ( e ) {
6163 const targetSection = this . getAttribute ( 'data-target' ) ;
6264
63- // Só previne o comportamento padrão para links internos
65+ // Prevent default only for internal links
6466 if ( targetSection ) {
6567 e . preventDefault ( ) ;
6668 showSection ( targetSection ) ;
6769 history . pushState ( null , null , `#${ targetSection } ` ) ;
6870 }
69- // Links sem data-target (como Documentation) seguirão normalmente
71+ // External/documentation links behave normally
7072 } ) ;
7173 } ) ;
72-
73- // Verifica a hash da URL ao carregar a página
74+
75+ // Check initial hash when the page loads
7476 function checkInitialHash ( ) {
7577 const initialHash = window . location . hash . substring ( 1 ) ;
7678 if ( initialHash && document . getElementById ( initialHash ) ) {
7779 showSection ( initialHash ) ;
7880 } else {
79- // Mostra a seção home por padrão
81+ // Default to ' home' section
8082 showSection ( 'home' ) ;
8183 }
8284 }
83-
84- // Verifica mudanças na hash
85+
86+ // Listen for URL hash changes
8587 window . addEventListener ( 'hashchange' , function ( ) {
8688 const newHash = window . location . hash . substring ( 1 ) ;
8789 if ( newHash && document . getElementById ( newHash ) ) {
8890 showSection ( newHash ) ;
8991 }
9092 } ) ;
91-
92- // Inicializa
93+
94+ // Initialize navigation system
9395 checkInitialHash ( ) ;
9496 }
9597
96- // 4. Fechar menu ao clicar fora
98+ // 4. Close Mobile Menu When Clicking Outside
9799 document . addEventListener ( 'click' , function ( e ) {
98100 if ( ! navLinksContainer . contains ( e . target ) &&
99101 ! menuToggle . contains ( e . target ) &&
@@ -103,6 +105,120 @@ document.addEventListener('DOMContentLoaded', function() {
103105 }
104106 } ) ;
105107
106- // Inicializa a navegação
108+ // Initialize navigation setup
107109 setupNavigation ( ) ;
108- } ) ;
110+ } ) ;
111+ document . addEventListener ( 'DOMContentLoaded' , function ( ) {
112+ // 1. Create particle container
113+ const particlesContainer = document . createElement ( 'div' ) ;
114+ particlesContainer . id = 'particles-js' ;
115+ particlesContainer . style . position = 'absolute' ;
116+ particlesContainer . style . top = '0' ;
117+ particlesContainer . style . left = '0' ;
118+ particlesContainer . style . width = '100%' ;
119+ particlesContainer . style . height = '100%' ;
120+ particlesContainer . style . zIndex = '-1' ;
121+ particlesContainer . style . background = '#0d1117' ; // Dark background
122+
123+ // Insert particle container inside hero section
124+ const heroSection = document . querySelector ( '.hero' ) ;
125+ heroSection . style . position = 'relative' ;
126+ heroSection . style . overflow = 'hidden' ;
127+ heroSection . insertBefore ( particlesContainer , heroSection . firstChild ) ;
128+
129+ // 2. Particle.js Configuration
130+ particlesJS ( 'particles-js' , {
131+ "particles" : {
132+ "number" : {
133+ "value" : 80 ,
134+ "density" : {
135+ "enable" : true ,
136+ "value_area" : 800
137+ }
138+ } ,
139+ "color" : {
140+ "value" : [ "#d6e4f0" , "#a8c0d6" , "#7a9bbc" ] // Light blue shades
141+ } ,
142+ "shape" : {
143+ "type" : "circle" ,
144+ "stroke" : {
145+ "width" : 0 ,
146+ "color" : "#000000"
147+ }
148+ } ,
149+ "opacity" : {
150+ "value" : 0.7 ,
151+ "random" : true ,
152+ "anim" : {
153+ "enable" : true ,
154+ "speed" : 1 ,
155+ "opacity_min" : 0.1 ,
156+ "sync" : false
157+ }
158+ } ,
159+ "size" : {
160+ "value" : 3 ,
161+ "random" : true ,
162+ "anim" : {
163+ "enable" : true ,
164+ "speed" : 2 ,
165+ "size_min" : 0.1 ,
166+ "sync" : false
167+ }
168+ } ,
169+ "line_linked" : {
170+ "enable" : true ,
171+ "distance" : 150 ,
172+ "color" : "#fcfdff" , // Pure white
173+ "opacity" : 0.4 ,
174+ "width" : 1
175+ } ,
176+ "move" : {
177+ "enable" : true ,
178+ "speed" : 2 ,
179+ "direction" : "none" ,
180+ "random" : true ,
181+ "straight" : false ,
182+ "out_mode" : "out" ,
183+ "bounce" : false ,
184+ "attract" : {
185+ "enable" : true ,
186+ "rotateX" : 600 ,
187+ "rotateY" : 1200
188+ }
189+ }
190+ } ,
191+ "interactivity" : {
192+ "detect_on" : "canvas" ,
193+ "events" : {
194+ "onhover" : {
195+ "enable" : true ,
196+ "mode" : "grab"
197+ } ,
198+ "onclick" : {
199+ "enable" : true ,
200+ "mode" : "push"
201+ } ,
202+ "resize" : true
203+ } ,
204+ "modes" : {
205+ "grab" : {
206+ "distance" : 140 ,
207+ "line_linked" : {
208+ "opacity" : 1
209+ }
210+ } ,
211+ "push" : {
212+ "particles_nb" : 4
213+ }
214+ }
215+ } ,
216+ "retina_detect" : true
217+ } ) ;
218+
219+ // 3. Ensure hero content appears above particles
220+ const heroContent = document . querySelector ( '.hero-text' ) ;
221+ const heroCode = document . querySelector ( '.hero-code' ) ;
222+ if ( heroContent ) heroContent . style . position = 'relative' ;
223+ if ( heroCode ) heroCode . style . position = 'relative' ;
224+ } ) ;
0 commit comments