14
14
</ head >
15
15
< body >
16
16
< header >
17
- < div class ="header-mobile ">
17
+ < div class ="header-content ">
18
18
< div class ="logo ">
19
- < img src ="{{ '/assets/images/logo.png' | relative_url }} " alt ="OS Engine Logo ">
20
- < h1 > {{ site.title }} - Open Source AlgoTrading платформы</ h1 >
19
+ < div class ="logo-icon "> OS</ div >
20
+ < h1 > {{ site.title }}</ h1 >
21
+ </ div >
22
+
23
+ < div class ="nav-container ">
24
+ < nav >
25
+ < ul class ="nav-menu " id ="navMenu ">
26
+ < li > < a href ="/ "> Главная</ a > </ li >
27
+ < li > < a href ="https://t.me/osengine " target ="_blank "> Чат</ a > </ li >
28
+ < li > < a href ="/blog/ "> Блог</ a > </ li >
29
+ < li > < a href ="/faq/ "> Гайд</ a > </ li >
30
+ < li > < a href ="/бесплатные-торговые-роботы/ "> Торговые роботы</ a > </ li >
31
+ < li > < a href ="/скачать-os-engine/ "> Скачать</ a > </ li >
32
+ </ ul >
33
+ </ nav >
34
+
35
+ < button class ="theme-toggle " id ="themeToggle " aria-label ="Переключить тему ">
36
+ < span id ="themeIcon "> 🌙</ span >
37
+ </ button >
38
+
39
+ < button class ="burger-btn " id ="burgerBtn " aria-label ="Меню ">
40
+ < span > </ span >
41
+ < span > </ span >
42
+ < span > </ span >
43
+ </ button >
21
44
</ div >
22
-
23
- < button id ="menuButton " class ="burger-btn ">
24
- < span > </ span >
25
- < span > </ span >
26
- < span > </ span >
27
- </ button >
28
45
</ div >
29
-
30
- < nav >
31
- < ul class ="nav-menu ">
32
- < li > < a href ="/ "> Главная</ a > </ li >
33
- < li > < a href ="https://t.me/osengine " target ="_blank "> Чат</ a > </ li >
34
- < li > < a href ="/blog/ "> Блог</ a > </ li >
35
- < li > < a href ="/faq/ "> Гайд</ a > </ li >
36
- < li > < a href ="/бесплатные-торговые-роботы/ "> Торговые роботы</ a > </ li >
37
- < li > < a href ="/скачать-os-engine/ "> Скачать</ a > </ li >
38
- </ ul >
39
- </ nav >
40
46
</ header >
41
47
42
- < script >
43
- document . getElementById ( 'menuButton' ) . onclick = e => {
44
- e . target . classList . toggle ( 'active' ) ;
45
- document . querySelector ( '.nav-menu' ) . classList . toggle ( 'active' ) ;
46
- }
47
- </ script >
48
-
49
48
< main >
50
49
{{ content }}
51
50
</ main >
52
51
53
52
< footer >
54
53
< p > Присылайте новости ваших проектов нам < a href ="https://t.me/osengine_official " target ="_blank "> в телеграм</ a > </ p >
54
+ < p style ="margin-top: 0.5rem; font-size: 0.875rem; "> © 2025 OS Engine. Open Source алготрейдинг платформы.</ p >
55
55
</ footer >
56
56
57
- <!-- Yandex.Metrika counter -->
58
- < script type ="text/javascript ">
59
- ( function ( m , e , t , r , i , k , a ) { m [ i ] = m [ i ] || function ( ) { ( m [ i ] . a = m [ i ] . a || [ ] ) . push ( arguments ) } ;
60
- m [ i ] . l = 1 * new Date ( ) ;
61
- for ( var j = 0 ; j < document . scripts . length ; j ++ ) { if ( document . scripts [ j ] . src === r ) { return ; } }
62
- k = e . createElement ( t ) , a = e . getElementsByTagName ( t ) [ 0 ] , k . async = 1 , k . src = r , a . parentNode . insertBefore ( k , a ) } )
63
- ( window , document , "script" , "https://mc.yandex.ru/metrika/tag.js" , "ym" ) ;
64
-
65
- ym ( 98830374 , "init" , {
66
- clickmap :true ,
67
- trackLinks :true ,
68
- accurateTrackBounce :true ,
69
- webvisor :true
70
- } ) ;
71
- </ script >
72
- < noscript > < div > < img src ="https://mc.yandex.ru/watch/98830374 " style ="position:absolute; left:-9999px; " alt ="" /> </ div > </ noscript >
73
- <!-- /Yandex.Metrika counter -->
57
+ < script >
58
+ // Theme Toggle Functionality
59
+ const themeToggle = document . getElementById ( 'themeToggle' ) ;
60
+ const themeIcon = document . getElementById ( 'themeIcon' ) ;
61
+ const body = document . body ;
62
+
63
+ // Check for saved theme preference or default to 'light'
64
+ const currentTheme = localStorage . getItem ( 'theme' ) || 'light' ;
65
+ body . setAttribute ( 'data-theme' , currentTheme ) ;
66
+ updateThemeIcon ( currentTheme ) ;
67
+
68
+ themeToggle . addEventListener ( 'click' , ( ) => {
69
+ const currentTheme = body . getAttribute ( 'data-theme' ) ;
70
+ const newTheme = currentTheme === 'dark' ? 'light' : 'dark' ;
71
+
72
+ body . setAttribute ( 'data-theme' , newTheme ) ;
73
+ localStorage . setItem ( 'theme' , newTheme ) ;
74
+ updateThemeIcon ( newTheme ) ;
75
+ } ) ;
76
+
77
+ function updateThemeIcon ( theme ) {
78
+ themeIcon . textContent = theme === 'dark' ? '☀️' : '🌙' ;
79
+ }
80
+
81
+ // Mobile Menu Toggle
82
+ const burgerBtn = document . getElementById ( 'burgerBtn' ) ;
83
+ const navMenu = document . getElementById ( 'navMenu' ) ;
84
+
85
+ if ( burgerBtn && navMenu ) {
86
+ burgerBtn . addEventListener ( 'click' , ( ) => {
87
+ burgerBtn . classList . toggle ( 'active' ) ;
88
+ navMenu . classList . toggle ( 'active' ) ;
89
+ } ) ;
90
+
91
+ // Close mobile menu when clicking on a link
92
+ navMenu . addEventListener ( 'click' , ( e ) => {
93
+ if ( e . target . tagName === 'A' ) {
94
+ burgerBtn . classList . remove ( 'active' ) ;
95
+ navMenu . classList . remove ( 'active' ) ;
96
+ }
97
+ } ) ;
98
+ }
99
+
100
+ // Smooth scrolling for anchor links
101
+ document . querySelectorAll ( 'a[href^="#"]' ) . forEach ( anchor => {
102
+ anchor . addEventListener ( 'click' , function ( e ) {
103
+ e . preventDefault ( ) ;
104
+ const target = document . querySelector ( this . getAttribute ( 'href' ) ) ;
105
+ if ( target ) {
106
+ target . scrollIntoView ( {
107
+ behavior : 'smooth' ,
108
+ block : 'start'
109
+ } ) ;
110
+ }
111
+ } ) ;
112
+ } ) ;
113
+
114
+ // Add scroll effect to header
115
+ let lastScrollTop = 0 ;
116
+ const header = document . querySelector ( 'header' ) ;
117
+
118
+ window . addEventListener ( 'scroll' , ( ) => {
119
+ const scrollTop = window . pageYOffset || document . documentElement . scrollTop ;
120
+
121
+ if ( scrollTop > lastScrollTop && scrollTop > 100 ) {
122
+ // Scrolling down
123
+ header . style . transform = 'translateY(-100%)' ;
124
+ } else {
125
+ // Scrolling up
126
+ header . style . transform = 'translateY(0)' ;
127
+ }
128
+
129
+ lastScrollTop = scrollTop ;
130
+ } ) ;
131
+
132
+ // Add animation delay to cards
133
+ const cards = document . querySelectorAll ( '.project-card' ) ;
134
+ cards . forEach ( ( card , index ) => {
135
+ card . style . animationDelay = `${ index * 0.1 } s` ;
136
+ } ) ;
137
+
138
+ // Add intersection observer for fade-in animations
139
+ const observerOptions = {
140
+ threshold : 0.1 ,
141
+ rootMargin : '0px 0px -50px 0px'
142
+ } ;
143
+
144
+ const observer = new IntersectionObserver ( ( entries ) => {
145
+ entries . forEach ( entry => {
146
+ if ( entry . isIntersecting ) {
147
+ entry . target . style . opacity = '1' ;
148
+ entry . target . style . transform = 'translateY(0)' ;
149
+ }
150
+ } ) ;
151
+ } , observerOptions ) ;
152
+
153
+ // Observe all sections for animations
154
+ document . querySelectorAll ( '.chat-card, .resource-link, .source-card, .post-item' ) . forEach ( el => {
155
+ if ( el ) {
156
+ el . style . opacity = '0' ;
157
+ el . style . transform = 'translateY(20px)' ;
158
+ el . style . transition = 'opacity 0.6s ease, transform 0.6s ease' ;
159
+ observer . observe ( el ) ;
160
+ }
161
+ } ) ;
162
+
163
+ // Initialize animations on page load
164
+ document . addEventListener ( 'DOMContentLoaded' , function ( ) {
165
+ // Reset animations for elements that should be visible immediately
166
+ document . querySelectorAll ( '.project-card' ) . forEach ( ( card , index ) => {
167
+ card . style . opacity = '1' ;
168
+ card . style . transform = 'translateY(0)' ;
169
+ } ) ;
170
+ } ) ;
171
+ </ script >
172
+
173
+ <!-- Yandex.Metrika counter -->
174
+ < script type ="text/javascript ">
175
+ ( function ( m , e , t , r , i , k , a ) { m [ i ] = m [ i ] || function ( ) { ( m [ i ] . a = m [ i ] . a || [ ] ) . push ( arguments ) } ;
176
+ m [ i ] . l = 1 * new Date ( ) ;
177
+ for ( var j = 0 ; j < document . scripts . length ; j ++ ) { if ( document . scripts [ j ] . src === r ) { return ; } }
178
+ k = e . createElement ( t ) , a = e . getElementsByTagName ( t ) [ 0 ] , k . async = 1 , k . src = r , a . parentNode . insertBefore ( k , a ) } )
179
+ ( window , document , "script" , "https://mc.yandex.ru/metrika/tag.js" , "ym" ) ;
180
+
181
+ ym ( 98830374 , "init" , {
182
+ clickmap :true ,
183
+ trackLinks :true ,
184
+ accurateTrackBounce :true ,
185
+ webvisor :true
186
+ } ) ;
187
+ </ script >
188
+ < noscript > < div > < img src ="https://mc.yandex.ru/watch/98830374 " style ="position:absolute; left:-9999px; " alt ="" /> </ div > </ noscript >
189
+ <!-- /Yandex.Metrika counter -->
74
190
</ body >
75
191
</ html >
0 commit comments