@@ -36,15 +36,15 @@ const categoryOrder = ["syntax", "data_structures", "classes", "advanced"];
3636 <span class =" arrow-left" ><ChevronLeft size ={ 16 } /></span >
3737 <span class =" arrow-right" ><ChevronRight size ={ 16 } /></span >
3838 </button >
39-
39+
4040
4141 <div class =" sidebar-header" >
4242 <div class =" header-top" >
4343 <a href ={ ` /ultimate-python/${activeLang }/ ` } class =" sidebar-logo" >
4444 <span class =" logo-emoji" >π</span >
4545 <span class =" logo-text" >Ultimate Python</span >
4646 </a >
47-
47+
4848 <!-- Language Selector -->
4949 <div class =" lang-selector-wrapper" >
5050 <select id =" lang-select" class =" lang-select" >
@@ -54,25 +54,25 @@ const categoryOrder = ["syntax", "data_structures", "classes", "advanced"];
5454 </select >
5555 </div >
5656 </div >
57-
57+
5858 <div class =" search-container" >
59- <input
60- type =" search"
61- id =" sidebar-search"
62- placeholder ={ t (' search.placeholder' )}
59+ <input
60+ type =" search"
61+ id =" sidebar-search"
62+ placeholder ={ t (' search.placeholder' )}
6363 autocomplete =" off"
6464 />
6565 </div >
6666 </div >
67-
67+
6868 <nav class =" sidebar-nav" >
6969 { categoryOrder .map ((catKey ) => {
7070 const cat = categoriesMap [catKey ];
7171 if (! cat ) return null ;
72-
72+
7373 // Determine if this category contains the active lesson
7474 const hasActiveChild = cat .lessons .some (l => l .path === activePath );
75-
75+
7676 return (
7777 <details class = " category-group" open = { hasActiveChild || activePath === undefined } >
7878 <summary class = " category-title" >
@@ -84,8 +84,8 @@ const categoryOrder = ["syntax", "data_structures", "classes", "advanced"];
8484 const isActive = lesson .path === activePath ;
8585 return (
8686 <li class = " lesson-item" data-lesson-id = { lesson .id } data-lesson-name = { lesson .name .toLowerCase ()} >
87- <a
88- href = { ` /ultimate-python/${activeLang }/${lesson .path }/ ` }
87+ <a
88+ href = { ` /ultimate-python/${activeLang }/${lesson .path }/ ` }
8989 class = { ` lesson-link ${isActive ? ' active' : ' ' } ` }
9090 >
9191 <span class = " lesson-indicator" ></span >
@@ -118,7 +118,7 @@ const categoryOrder = ["syntax", "data_structures", "classes", "advanced"];
118118 :global(html.sidebar-transitioning) .sidebar {
119119 transition: margin-left 0.3s cubic-bezier(0.4, 0, 0.2, 1);
120120 }
121-
121+
122122 .sidebar-toggle-btn {
123123 position: absolute;
124124 right: -15px;
@@ -144,25 +144,25 @@ const categoryOrder = ["syntax", "data_structures", "classes", "advanced"];
144144 :global(html.sidebar-transitioning) .sidebar-toggle-btn {
145145 transition: right 0.3s cubic-bezier(0.4, 0, 0.2, 1), background-color var(--transition-speed), transform var(--transition-speed);
146146 }
147-
147+
148148 .arrow-left, .arrow-right {
149149 display: flex;
150150 align-items: center;
151151 justify-content: center;
152152 }
153-
153+
154154 .arrow-right {
155155 display: none;
156156 }
157-
157+
158158 :global(html.sidebar-collapsed) .arrow-left {
159159 display: none;
160160 }
161-
161+
162162 :global(html.sidebar-collapsed) .arrow-right {
163163 display: flex;
164164 }
165-
165+
166166 .sidebar-toggle-btn:hover {
167167 background-color: var(--bg-tertiary);
168168 transform: scale(1.05);
@@ -171,39 +171,39 @@ const categoryOrder = ["syntax", "data_structures", "classes", "advanced"];
171171 :global(html.sidebar-collapsed) .sidebar {
172172 margin-left: calc(-1 * var(--sidebar-width));
173173 }
174-
174+
175175 :global(html.sidebar-collapsed) .sidebar-toggle-btn {
176176 right: -45px;
177177 }
178-
178+
179179 .sidebar-header {
180180 padding: 1.5rem;
181181 border-bottom: 1px solid var(--border-color);
182182 display: flex;
183183 flex-direction: column;
184184 gap: 1rem;
185185 }
186-
186+
187187 .header-top {
188188 display: flex;
189189 flex-direction: column;
190190 align-items: flex-start;
191191 gap: 0.75rem;
192192 width: 100%;
193193 }
194-
194+
195195 .sidebar-logo {
196196 display: flex;
197197 align-items: center;
198198 gap: 0.5rem;
199199 color: var(--forest-green);
200200 width: 100%;
201201 }
202-
202+
203203 .logo-emoji {
204204 font-size: 1.5rem;
205205 }
206-
206+
207207 .logo-text {
208208 font-family: var(--font-serif);
209209 font-size: 1.25rem;
@@ -233,11 +233,11 @@ const categoryOrder = ["syntax", "data_structures", "classes", "advanced"];
233233 .lang-select:focus {
234234 border-color: var(--forest-green);
235235 }
236-
236+
237237 .search-container {
238238 position: relative;
239239 }
240-
240+
241241 #sidebar-search {
242242 width: 100%;
243243 padding: 0.6rem 0.75rem;
@@ -250,22 +250,22 @@ const categoryOrder = ["syntax", "data_structures", "classes", "advanced"];
250250 outline: none;
251251 transition: border-color var(--transition-speed);
252252 }
253-
253+
254254 #sidebar-search:focus {
255255 border-color: var(--forest-green);
256256 box-shadow: 0 0 0 2px var(--forest-green-soft);
257257 }
258-
258+
259259 .sidebar-nav {
260260 flex: 1;
261261 overflow-y: auto;
262262 padding: 1rem 1.5rem;
263263 }
264-
264+
265265 .category-group {
266266 margin-bottom: 1.25rem;
267267 }
268-
268+
269269 .category-title {
270270 font-family: var(--font-serif);
271271 color: var(--forest-green);
@@ -279,39 +279,39 @@ const categoryOrder = ["syntax", "data_structures", "classes", "advanced"];
279279 align-items: center;
280280 padding: 0.5rem 0;
281281 }
282-
282+
283283 .category-title::-webkit-details-marker {
284284 display: none;
285285 }
286-
286+
287287 .category-title::after {
288288 content: "βΎ";
289289 font-size: 0.8rem;
290290 transition: transform var(--transition-speed);
291291 }
292-
292+
293293 .category-group[open] .category-title::after {
294294 transform: rotate(-180deg);
295295 }
296-
296+
297297 .category-count {
298298 font-size: 0.8rem;
299299 color: var(--text-secondary);
300300 margin-left: auto;
301301 margin-right: 0.5rem;
302302 }
303-
303+
304304 .lesson-list {
305305 list-style: none;
306306 padding-left: 0.5rem;
307307 margin-top: 0.25rem;
308308 border-left: 1px solid var(--border-color);
309309 }
310-
310+
311311 .lesson-item {
312312 margin-bottom: 0.25rem;
313313 }
314-
314+
315315 .lesson-link {
316316 display: flex;
317317 align-items: center;
@@ -322,25 +322,25 @@ const categoryOrder = ["syntax", "data_structures", "classes", "advanced"];
322322 transition: all var(--transition-speed);
323323 gap: 0.5rem;
324324 }
325-
325+
326326 .lesson-link:hover {
327327 background-color: var(--bg-tertiary);
328328 color: var(--text-primary);
329329 }
330-
330+
331331 .lesson-link.active {
332332 background-color: var(--forest-green-soft);
333333 color: var(--forest-green);
334334 font-weight: 500;
335335 }
336-
336+
337337 .lesson-indicator {
338338 width: 6px;
339339 height: 6px;
340340 border-radius: 50%;
341341 background-color: transparent;
342342 }
343-
343+
344344 .lesson-link.active .lesson-indicator {
345345 background-color: var(--forest-green);
346346 }
@@ -380,33 +380,33 @@ const categoryOrder = ["syntax", "data_structures", "classes", "advanced"];
380380 const searchInput = document.getElementById('sidebar-search') as HTMLInputElement;
381381 if (!searchInput || searchInput.dataset.searchInitialized) return;
382382 searchInput.dataset.searchInitialized = 'true';
383-
383+
384384 let searchTimeout: number;
385385 searchInput.addEventListener('input', (e) => {
386386 cancelAnimationFrame(searchTimeout);
387387 const target = e.target as HTMLInputElement;
388-
388+
389389 searchTimeout = requestAnimationFrame(() => {
390390 const query = target.value.toLowerCase().trim();
391391 const items = document.querySelectorAll('.lesson-item');
392392 const groups = document.querySelectorAll('.category-group');
393-
393+
394394 if (!query) {
395395 // Reset visibility
396396 items.forEach(el => el.classList.remove('hidden-search'));
397397 groups.forEach(el => el.classList.remove('hidden-search'));
398398 return;
399399 }
400-
400+
401401 // Track which categories have visible matches
402402 const categoryMatches = new Map();
403-
403+
404404 items.forEach(item => {
405405 const name = item.getAttribute('data-lesson-name') || '';
406406 const id = item.getAttribute('data-lesson-id') || '';
407-
407+
408408 const isMatch = name.includes(query) || id.includes(query);
409-
409+
410410 const parentGroup = item.closest('.category-group');
411411 if (parentGroup) {
412412 if (isMatch) {
@@ -417,7 +417,7 @@ const categoryOrder = ["syntax", "data_structures", "classes", "advanced"];
417417 }
418418 }
419419 });
420-
420+
421421 groups.forEach(group => {
422422 if (categoryMatches.has(group)) {
423423 group.classList.remove('hidden-search');
@@ -440,7 +440,7 @@ const categoryOrder = ["syntax", "data_structures", "classes", "advanced"];
440440 const newLang = (e.target as HTMLSelectElement).value;
441441 const currentPath = window.location.pathname;
442442 const segments = currentPath.split('/');
443-
443+
444444 // swap language segment (e.g. /ultimate-python/[lang]/...)
445445 const baseIndex = segments.indexOf('ultimate-python');
446446 if (baseIndex !== -1 && segments[baseIndex + 1] !== undefined) {
@@ -509,7 +509,7 @@ const categoryOrder = ["syntax", "data_structures", "classes", "advanced"];
509509 const currentWidth = window.innerWidth;
510510 const wasDesktop = lastWidth >= 900;
511511 const isMobile = currentWidth < 900;
512-
512+
513513 if (wasDesktop && isMobile) {
514514 document.documentElement.classList.add('sidebar-collapsed');
515515 document.documentElement.classList.remove('sidebar-mobile-open');
0 commit comments