jekyll-theme-zer0 0.17.0 → 0.17.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: cedad3b535f19c489e0d874be9c116789f981fc042743150be32b06f7d6481c7
4
- data.tar.gz: 0cd8445680be5c73980338a85aba69a8edb5e9484003fd74daf80c104690e22d
3
+ metadata.gz: cdb1bbc3f82ba18d008ef8128592fadf16247cc1c45c6248a6f48d31c41f0c44
4
+ data.tar.gz: b62640c64c7032103f03155fdf447942e4fed67195e3b5acc3eaad526b90558f
5
5
  SHA512:
6
- metadata.gz: 35520e071daded7969373b51f103d8a8440db28b03044ca1db0c01832d676cbcfc32d677d285ce612c8f79a6a2fa2fa8023570457a28cba83615fea8363bd1eb
7
- data.tar.gz: 654aa816eeb3b3e1019f0686eb2516eb4404e17ad4e533f764d32240fd1454a6c893a6e376fb907387b0a5f3cd514c1e364b365df92ed07e1279a90144ffc222
6
+ metadata.gz: b9bcf7b150affaaba80d5787df4c1ca6fd5e7c46c8e2c6b0835dae371fa296f91915e72d5f49bb1c47482f8c0a10ed96f551ae95767831c107e93dc9ecfca395
7
+ data.tar.gz: 9886baeb0f69e536ee19b59f13ac4ef6389cdae053e1427bb8b4e177a517aa735e40555b5d0fa0a7143caa0540d40f07d419313513f606998d402c1b1201bfd3
data/CHANGELOG.md CHANGED
@@ -1,5 +1,38 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.17.2] - 2025-12-31
4
+
5
+ ### Fixed
6
+ - **Mermaid Dark Mode**: Fixed diagram rendering issues in dark mode by dynamically detecting Bootstrap theme (`data-bs-theme`) and switching Mermaid theme accordingly
7
+ - **Cookie Consent Banner**: Fixed banner appearing twice on initial page load by implementing CSS-first visibility control and removing inline style conflicts
8
+
9
+ ### Enhanced
10
+ - **UI/UX Improvements**: Comprehensive frontend enhancements including:
11
+ - Smooth scroll animations with Intersection Observer
12
+ - Enhanced card hover effects with 3D parallax on desktop
13
+ - Improved button styles with ripple effects and better transitions
14
+ - Better code block styling with enhanced copy functionality
15
+ - Mobile-responsive improvements with touch-friendly tap targets
16
+ - Improved focus states for accessibility
17
+ - Hero section animations with staggered fade-in effects
18
+
19
+ ### Added
20
+ - **UI Enhancements Module**: New `assets/js/ui-enhancements.js` for scroll animations, card interactions, and smooth scrolling
21
+ - **Enhanced Code Copy**: Improved copy-to-clipboard functionality with better visual feedback and fallback support
22
+
23
+ ### Changed
24
+ - **CI Configuration**: Made HTMLProofer non-blocking for pre-existing link issues
25
+ - **Documentation**: Enhanced contributing guide and release pipeline documentation 4630c33 (fix(ui): fix Mermaid dark mode and cookie banner rendering)
26
+
27
+ ## [0.17.1] - 2025-12-24
28
+
29
+ ### Changed
30
+ - Version bump: patch release
31
+
32
+ ### Commits in this release
33
+ - d56de0b fix(ci): update Gemfile.lock for v0.17.0 and improve HTMLProofer config
34
+
35
+
3
36
  ## [0.17.0] - 2025-12-23
4
37
 
5
38
  ### Added
@@ -49,7 +49,7 @@ Usage: Include in root.html layout
49
49
  Configuration: Uses site.posthog settings from _config.yml
50
50
  {% endcomment %}
51
51
 
52
- <div id="cookieConsent" class="cookie-consent-banner position-fixed bottom-0 start-0 end-0 bg-dark text-light p-3 shadow-lg" style="z-index: 9999; transform: translateY(100%); transition: transform 0.3s ease-in-out;">
52
+ <div id="cookieConsent" class="cookie-consent-banner position-fixed bottom-0 start-0 end-0 bg-dark text-light p-3 shadow-lg">
53
53
  <div class="container-fluid">
54
54
  <div class="row align-items-center">
55
55
  <div class="col-12 col-lg-8">
@@ -248,18 +248,42 @@ Configuration: Uses site.posthog settings from _config.yml
248
248
  // Show consent banner
249
249
  function showConsentBanner() {
250
250
  const banner = document.getElementById('cookieConsent');
251
- if (banner) {
252
- setTimeout(() => {
253
- banner.style.transform = 'translateY(0)';
254
- }, 1000); // Show after 1 second
255
- }
251
+ if (!banner) return;
252
+
253
+ // Ensure banner starts completely hidden - remove all classes and inline styles
254
+ banner.classList.remove('cookie-banner-showing', 'cookie-banner-visible');
255
+ banner.removeAttribute('style'); // Remove all inline styles to let CSS take over
256
+
257
+ // Wait for the delay, then show and animate in one smooth motion
258
+ setTimeout(() => {
259
+ // First, make it visible but still off-screen (using class for CSS control)
260
+ banner.classList.add('cookie-banner-showing');
261
+
262
+ // Force a reflow to ensure the display change is applied
263
+ void banner.offsetHeight;
264
+
265
+ // On the next frame, animate it in smoothly
266
+ requestAnimationFrame(() => {
267
+ requestAnimationFrame(() => {
268
+ banner.classList.add('cookie-banner-visible');
269
+ });
270
+ });
271
+ }, 1000); // Show after 1 second
256
272
  }
257
273
 
258
274
  // Hide consent banner
259
275
  function hideConsentBanner() {
260
276
  const banner = document.getElementById('cookieConsent');
261
277
  if (banner) {
262
- banner.style.transform = 'translateY(100%)';
278
+ // Remove visible class to trigger transition out
279
+ banner.classList.remove('cookie-banner-visible');
280
+
281
+ // Hide after transition completes
282
+ banner.addEventListener('transitionend', function hideAfterTransition() {
283
+ banner.classList.remove('cookie-banner-showing');
284
+ banner.removeAttribute('style'); // Clean up inline styles
285
+ banner.removeEventListener('transitionend', hideAfterTransition);
286
+ }, { once: true });
263
287
  }
264
288
  }
265
289
 
@@ -281,14 +305,27 @@ Configuration: Uses site.posthog settings from _config.yml
281
305
 
282
306
  // Initialize on DOM content loaded
283
307
  document.addEventListener('DOMContentLoaded', function() {
308
+ const banner = document.getElementById('cookieConsent');
309
+
310
+ // Ensure banner starts completely hidden BEFORE any checks
311
+ // Remove all classes and inline styles - let CSS handle hiding
312
+ if (banner) {
313
+ banner.classList.remove('cookie-banner-showing', 'cookie-banner-visible');
314
+ banner.removeAttribute('style');
315
+ }
316
+
284
317
  const existingConsent = getConsentState();
285
318
 
286
319
  if (existingConsent) {
287
- // Apply existing consent
320
+ // Apply existing consent and ensure banner stays hidden
288
321
  applyConsent(existingConsent);
289
322
  updateModalUI(existingConsent);
323
+ if (banner) {
324
+ banner.classList.remove('cookie-banner-showing', 'cookie-banner-visible');
325
+ banner.removeAttribute('style');
326
+ }
290
327
  } else {
291
- // Show consent banner for new visitors
328
+ // Show consent banner for new visitors (with delay)
292
329
  showConsentBanner();
293
330
  }
294
331
 
@@ -348,12 +385,40 @@ Configuration: Uses site.posthog settings from _config.yml
348
385
  </script>
349
386
 
350
387
  <style>
388
+ /* Banner base styles */
389
+ #cookieConsent {
390
+ z-index: 9999;
391
+ transition: transform 0.4s cubic-bezier(0.4, 0, 0.2, 1), opacity 0.4s cubic-bezier(0.4, 0, 0.2, 1);
392
+ }
393
+
394
+ /* Banner starts completely hidden - CSS enforces this */
395
+ #cookieConsent:not(.cookie-banner-showing) {
396
+ display: none !important;
397
+ visibility: hidden !important;
398
+ opacity: 0 !important;
399
+ transform: translateY(100%) !important;
400
+ }
401
+
351
402
  .cookie-consent-banner {
352
403
  background: linear-gradient(135deg, #2c3e50 0%, #3498db 100%);
353
404
  backdrop-filter: blur(10px);
354
405
  border-top: 1px solid rgba(255, 255, 255, 0.1);
355
406
  }
356
407
 
408
+ /* Only show banner when explicitly enabled via JavaScript class */
409
+ #cookieConsent.cookie-banner-showing {
410
+ display: block !important;
411
+ visibility: visible !important;
412
+ opacity: 0;
413
+ transform: translateY(100%);
414
+ }
415
+
416
+ /* Animate in when visible class is added */
417
+ #cookieConsent.cookie-banner-showing.cookie-banner-visible {
418
+ opacity: 1 !important;
419
+ transform: translateY(0) !important;
420
+ }
421
+
357
422
  .cursor-pointer {
358
423
  cursor: pointer;
359
424
  }
@@ -379,4 +444,11 @@ Configuration: Uses site.posthog settings from _config.yml
379
444
  margin-bottom: 0;
380
445
  }
381
446
  }
447
+
448
+ /* Respect reduced motion preferences */
449
+ @media (prefers-reduced-motion: reduce) {
450
+ .cookie-consent-banner {
451
+ transition: none !important;
452
+ }
453
+ }
382
454
  </style>
@@ -47,6 +47,108 @@
47
47
  <!-- Initialize Mermaid with custom configuration -->
48
48
  <script>
49
49
  document.addEventListener('DOMContentLoaded', function() {
50
+ // ============================================================
51
+ // Helper function to detect Bootstrap theme
52
+ // ============================================================
53
+ function getBootstrapTheme() {
54
+ // Check data-bs-theme attribute on html element
55
+ var htmlTheme = document.documentElement.getAttribute('data-bs-theme');
56
+ if (htmlTheme === 'dark' || htmlTheme === 'light') {
57
+ return htmlTheme;
58
+ }
59
+ // Fallback to prefers-color-scheme
60
+ if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) {
61
+ return 'dark';
62
+ }
63
+ return 'light';
64
+ }
65
+
66
+ // ============================================================
67
+ // Helper function to get Mermaid theme configuration
68
+ // ============================================================
69
+ function getMermaidConfig(theme) {
70
+ var isDark = theme === 'dark';
71
+
72
+ if (isDark) {
73
+ // Dark mode configuration
74
+ return {
75
+ theme: 'dark',
76
+ themeVariables: {
77
+ primaryColor: '#0d6efd',
78
+ primaryTextColor: '#ffffff',
79
+ primaryBorderColor: '#0a58ca',
80
+ lineColor: '#6c757d',
81
+ secondaryColor: '#6c757d',
82
+ tertiaryColor: '#212529',
83
+ background: '#212529',
84
+ mainBkg: '#212529',
85
+ secondBkg: '#343a40',
86
+ tertiaryBkg: '#495057',
87
+ textColor: '#ffffff',
88
+ secondaryTextColor: '#adb5bd',
89
+ tertiaryTextColor: '#6c757d',
90
+ lineColor: '#6c757d',
91
+ border1: '#495057',
92
+ border2: '#6c757d',
93
+ noteBkgColor: '#343a40',
94
+ noteTextColor: '#ffffff',
95
+ noteBorderColor: '#6c757d',
96
+ actorBkg: '#0d6efd',
97
+ actorBorder: '#0a58ca',
98
+ actorTextColor: '#ffffff',
99
+ actorLineColor: '#ffffff',
100
+ signalColor: '#ffffff',
101
+ signalTextColor: '#ffffff',
102
+ labelBoxBkgColor: '#343a40',
103
+ labelBoxBorderColor: '#6c757d',
104
+ labelTextColor: '#ffffff',
105
+ loopTextColor: '#ffffff',
106
+ activationBorderColor: '#0d6efd',
107
+ activationBkgColor: '#0d6efd',
108
+ sequenceNumberColor: '#ffffff',
109
+ sectionBkgColor: '#343a40',
110
+ altSectionBkgColor: '#495057',
111
+ excludeBkgColor: '#495057',
112
+ taskBorderColor: '#0d6efd',
113
+ taskBkgColor: '#0d6efd',
114
+ taskTextLightColor: '#ffffff',
115
+ taskTextColor: '#ffffff',
116
+ taskTextDarkColor: '#000000',
117
+ taskTextOutsideColor: '#ffffff',
118
+ taskTextClickableColor: '#0d6efd',
119
+ activeTaskBorderColor: '#0a58ca',
120
+ activeTaskBkgColor: '#0a58ca',
121
+ gridColor: '#6c757d',
122
+ doneTaskBkgColor: '#198754',
123
+ doneTaskBorderColor: '#146c43',
124
+ critBorderColor: '#dc3545',
125
+ critBkgColor: '#dc3545',
126
+ todayLineColor: '#ffc107'
127
+ }
128
+ };
129
+ } else {
130
+ // Light mode configuration
131
+ return {
132
+ theme: 'default',
133
+ themeVariables: {
134
+ primaryColor: '#007bff',
135
+ primaryTextColor: '#fff',
136
+ primaryBorderColor: '#0056b3',
137
+ lineColor: '#6c757d',
138
+ secondaryColor: '#6c757d',
139
+ tertiaryColor: '#f8f9fa',
140
+ background: '#ffffff',
141
+ mainBkg: '#ffffff',
142
+ secondBkg: '#f8f9fa',
143
+ tertiaryBkg: '#e9ecef',
144
+ textColor: '#212529',
145
+ secondaryTextColor: '#6c757d',
146
+ tertiaryTextColor: '#adb5bd'
147
+ }
148
+ };
149
+ }
150
+ }
151
+
50
152
  // ============================================================
51
153
  // Step 1: Convert native markdown code blocks to mermaid divs
52
154
  // This enables ```mermaid syntax to work with GitHub Pages
@@ -86,20 +188,16 @@
86
188
  });
87
189
 
88
190
  // ============================================================
89
- // Step 2: Initialize Mermaid with custom configuration
191
+ // Step 2: Initialize Mermaid with theme-aware configuration
90
192
  // ============================================================
91
193
 
194
+ var bootstrapTheme = getBootstrapTheme();
195
+ var mermaidThemeConfig = getMermaidConfig(bootstrapTheme);
196
+
92
197
  mermaid.initialize({
93
198
  startOnLoad: false, // We'll manually run after conversion
94
- theme: 'forest', // Options: default, forest, dark, neutral, base
95
- themeVariables: {
96
- primaryColor: '#007bff',
97
- primaryTextColor: '#fff',
98
- primaryBorderColor: '#0056b3',
99
- lineColor: '#6c757d',
100
- secondaryColor: '#6c757d',
101
- tertiaryColor: '#f8f9fa'
102
- },
199
+ theme: mermaidThemeConfig.theme,
200
+ themeVariables: mermaidThemeConfig.themeVariables,
103
201
  flowchart: {
104
202
  useMaxWidth: true,
105
203
  htmlLabels: true,
@@ -139,10 +237,82 @@
139
237
 
140
238
  // Run mermaid to render all .mermaid divs
141
239
  mermaid.run().then(function() {
142
- console.log('Mermaid.js: All diagrams rendered successfully');
240
+ console.log('Mermaid.js: All diagrams rendered successfully with theme:', bootstrapTheme);
143
241
  }).catch(function(error) {
144
242
  console.warn('Mermaid.js: Some diagrams failed to render', error);
145
243
  });
244
+
245
+ // ============================================================
246
+ // Step 4: Watch for theme changes and re-render diagrams
247
+ // ============================================================
248
+
249
+ // Create a MutationObserver to watch for theme changes
250
+ var themeObserver = new MutationObserver(function(mutations) {
251
+ mutations.forEach(function(mutation) {
252
+ if (mutation.type === 'attributes' && mutation.attributeName === 'data-bs-theme') {
253
+ var newTheme = getBootstrapTheme();
254
+ var newMermaidConfig = getMermaidConfig(newTheme);
255
+
256
+ // Update Mermaid configuration
257
+ mermaid.initialize({
258
+ startOnLoad: false,
259
+ theme: newMermaidConfig.theme,
260
+ themeVariables: newMermaidConfig.themeVariables,
261
+ flowchart: {
262
+ useMaxWidth: true,
263
+ htmlLabels: true,
264
+ curve: 'basis'
265
+ },
266
+ sequence: {
267
+ diagramMarginX: 50,
268
+ diagramMarginY: 10,
269
+ actorMargin: 50,
270
+ width: 150,
271
+ height: 65,
272
+ boxMargin: 10,
273
+ boxTextMargin: 5,
274
+ noteMargin: 10,
275
+ messageMargin: 35,
276
+ mirrorActors: true,
277
+ bottomMarginAdj: 1,
278
+ useMaxWidth: true
279
+ },
280
+ gantt: {
281
+ titleTopMargin: 25,
282
+ barHeight: 20,
283
+ barGap: 4,
284
+ topPadding: 50,
285
+ leftPadding: 75,
286
+ gridLineStartPadding: 35,
287
+ fontSize: 11,
288
+ numberSectionStyles: 4,
289
+ axisFormat: '%Y-%m-%d'
290
+ },
291
+ securityLevel: 'loose'
292
+ });
293
+
294
+ // Re-render all diagrams with new theme
295
+ var mermaidDivs = document.querySelectorAll('.mermaid');
296
+ mermaidDivs.forEach(function(div) {
297
+ var content = div.textContent || div.innerText;
298
+ div.innerHTML = '';
299
+ div.textContent = content;
300
+ });
301
+
302
+ mermaid.run().then(function() {
303
+ console.log('Mermaid.js: Diagrams re-rendered with theme:', newTheme);
304
+ }).catch(function(error) {
305
+ console.warn('Mermaid.js: Some diagrams failed to re-render', error);
306
+ });
307
+ }
308
+ });
309
+ });
310
+
311
+ // Start observing the html element for theme changes
312
+ themeObserver.observe(document.documentElement, {
313
+ attributes: true,
314
+ attributeFilter: ['data-bs-theme']
315
+ });
146
316
  });
147
317
  </script>
148
318
 
@@ -157,12 +327,17 @@
157
327
  margin: 2rem auto;
158
328
  background-color: transparent;
159
329
  overflow-x: auto;
330
+ padding: 1rem;
331
+ border-radius: 0.5rem;
332
+ transition: background-color 0.3s ease;
160
333
  }
161
334
 
162
335
  /* Ensure diagrams are responsive */
163
336
  .mermaid svg {
164
337
  max-width: 100%;
165
338
  height: auto;
339
+ display: block;
340
+ margin: 0 auto;
166
341
  }
167
342
 
168
343
  /* Hide code blocks before conversion (prevent flash of unstyled content) */
@@ -173,15 +348,86 @@
173
348
  transition: opacity 0.2s;
174
349
  }
175
350
 
176
- /* Dark mode compatibility */
351
+ /* Dark mode compatibility - Bootstrap theme aware */
352
+ [data-bs-theme="dark"] .mermaid {
353
+ background-color: rgba(33, 37, 41, 0.5);
354
+ border: 1px solid rgba(108, 117, 125, 0.2);
355
+ }
356
+
357
+ [data-bs-theme="dark"] .mermaid svg {
358
+ /* Ensure SVG elements are visible in dark mode */
359
+ color-scheme: dark;
360
+ }
361
+
362
+ [data-bs-theme="dark"] .mermaid svg text {
363
+ fill: #ffffff !important;
364
+ }
365
+
366
+ [data-bs-theme="dark"] .mermaid svg .node rect,
367
+ [data-bs-theme="dark"] .mermaid svg .node polygon,
368
+ [data-bs-theme="dark"] .mermaid svg .cluster rect {
369
+ fill: #343a40 !important;
370
+ stroke: #6c757d !important;
371
+ }
372
+
373
+ [data-bs-theme="dark"] .mermaid svg .edgePath .path {
374
+ stroke: #6c757d !important;
375
+ }
376
+
377
+ [data-bs-theme="dark"] .mermaid svg .edgeLabel {
378
+ background-color: #212529 !important;
379
+ color: #ffffff !important;
380
+ }
381
+
382
+ [data-bs-theme="dark"] .mermaid svg .edgeLabel text {
383
+ fill: #ffffff !important;
384
+ }
385
+
386
+ /* Light mode styling */
387
+ [data-bs-theme="light"] .mermaid {
388
+ background-color: rgba(248, 249, 250, 0.5);
389
+ border: 1px solid rgba(0, 0, 0, 0.1);
390
+ }
391
+
392
+ [data-bs-theme="light"] .mermaid svg text {
393
+ fill: #212529 !important;
394
+ }
395
+
396
+ /* Fallback for prefers-color-scheme if data-bs-theme is not set */
177
397
  @media (prefers-color-scheme: dark) {
178
- .mermaid {
179
- filter: brightness(0.9);
398
+ html:not([data-bs-theme]) .mermaid {
399
+ background-color: rgba(33, 37, 41, 0.5);
400
+ border: 1px solid rgba(108, 117, 125, 0.2);
180
401
  }
181
402
  }
182
403
 
404
+ /* Smooth theme transition */
405
+ .mermaid svg {
406
+ transition: opacity 0.3s ease;
407
+ }
408
+
409
+ /* Loading state */
410
+ .mermaid:not(:has(svg)) {
411
+ min-height: 100px;
412
+ display: flex;
413
+ align-items: center;
414
+ justify-content: center;
415
+ }
416
+
417
+ .mermaid:not(:has(svg))::after {
418
+ content: 'Loading diagram...';
419
+ color: var(--bs-secondary);
420
+ font-size: 0.875rem;
421
+ }
422
+
183
423
  /* Print styles */
184
424
  @media print {
425
+ .mermaid {
426
+ background-color: transparent !important;
427
+ border: none !important;
428
+ page-break-inside: avoid;
429
+ }
430
+
185
431
  .mermaid svg {
186
432
  max-width: 100% !important;
187
433
  page-break-inside: avoid;
@@ -42,6 +42,7 @@
42
42
  <script defer src="{{ '/assets/js/halfmoon.js' | relative_url }}"></script>
43
43
  <script defer src="{{ '/assets/js/side-bar-folders.js' | relative_url }}"></script>
44
44
  <script defer src="{{ '/assets/js/code-copy.js' | relative_url }}"></script>
45
+ <script defer src="{{ '/assets/js/ui-enhancements.js' | relative_url }}"></script>
45
46
 
46
47
  <!-- ================================ -->
47
48
  <!-- THIRD PARTY INTEGRATIONS -->
@@ -47,29 +47,29 @@ layout: root
47
47
  <!-- ================================ -->
48
48
  <!-- HERO SECTION -->
49
49
  <!-- ================================ -->
50
- <div class="bg-primary text-white">
50
+ <div class="bg-primary text-white position-relative overflow-hidden">
51
51
  <div class="container-xl py-5 px-4 px-md-5">
52
52
  <div class="row align-items-center min-vh-50 g-4 g-lg-5">
53
- <div class="col-lg-6">
54
- <h1 class="display-4 fw-bold mb-3">{{ page.title }}</h1>
55
- <p class="lead mb-4">{{ page.description }}</p>
56
- <div class="d-flex flex-column flex-md-row gap-3">
53
+ <div class="col-lg-6 order-2 order-lg-1">
54
+ <h1 class="display-4 fw-bold mb-3 animate-on-scroll">{{ page.title }}</h1>
55
+ <p class="lead mb-4 animate-on-scroll" style="animation-delay: 0.1s;">{{ page.description }}</p>
56
+ <div class="d-flex flex-column flex-md-row gap-3 animate-on-scroll" style="animation-delay: 0.2s;">
57
57
  <a href="#get-started" class="btn btn-light btn-lg">
58
58
  <i class="bi bi-rocket-takeoff me-2"></i>Get Started
59
59
  </a>
60
60
  <a href="#features" class="btn btn-outline-light btn-lg">
61
61
  <i class="bi bi-list-check me-2"></i>Features
62
62
  </a>
63
- <a href="{{ site.resources.github_repo | default: '' | join: '' }}" class="btn btn-outline-light btn-lg">
63
+ <a href="{{ site.resources.github_repo | default: '' | join: '' }}" class="btn btn-outline-light btn-lg" target="_blank" rel="noopener">
64
64
  <i class="bi bi-github me-2"></i>GitHub
65
65
  </a>
66
66
  </div>
67
67
  </div>
68
- <div class="col-lg-6 text-center">
68
+ <div class="col-lg-6 text-center order-1 order-lg-2">
69
69
  {% if page.hero_image %}
70
- <img src="{{ page.hero_image }}" alt="{{ page.title }}" class="img-fluid rounded shadow-lg">
70
+ <img src="{{ page.hero_image }}" alt="{{ page.title }}" class="img-fluid rounded shadow-lg animate-on-scroll" loading="eager" style="animation-delay: 0.3s;">
71
71
  {% else %}
72
- <div class="bg-secondary rounded p-5 text-body">
72
+ <div class="bg-secondary rounded p-5 text-body animate-on-scroll">
73
73
  <i class="bi bi-code-square display-1"></i>
74
74
  <p class="mt-3 mb-0">Jekyll Theme</p>
75
75
  </div>
@@ -102,37 +102,37 @@ layout: root
102
102
 
103
103
  <div class="row g-4">
104
104
  <div class="col-md-4">
105
- <div class="card h-100 border-0 shadow-sm">
105
+ <div class="card h-100 border-0 shadow-sm feature-card">
106
106
  <div class="card-body text-center p-4">
107
- <div class="bg-primary text-white rounded-circle d-inline-flex align-items-center justify-content-center mb-3" style="width: 60px; height: 60px;">
107
+ <div class="bg-primary text-white rounded-circle d-inline-flex align-items-center justify-content-center mb-3 feature-icon" style="width: 60px; height: 60px;">
108
108
  <i class="bi bi-shield-check fs-4"></i>
109
109
  </div>
110
- <h5 class="card-title text-body-emphasis">Error-Free Development</h5>
111
- <p class="card-text text-body-secondary">Built-in error handling and self-healing installation process ensures a smooth development experience.</p>
110
+ <h5 class="card-title text-body-emphasis">Error-Free Development</h5>
111
+ <p class="card-text text-body-secondary">Built-in error handling and self-healing installation process ensures a smooth development experience.</p>
112
112
  </div>
113
113
  </div>
114
114
  </div>
115
115
 
116
116
  <div class="col-md-4">
117
- <div class="card h-100 border-0 shadow-sm">
117
+ <div class="card h-100 border-0 shadow-sm feature-card">
118
118
  <div class="card-body text-center p-4">
119
- <div class="bg-success text-white rounded-circle d-inline-flex align-items-center justify-content-center mb-3" style="width: 60px; height: 60px;">
119
+ <div class="bg-success text-white rounded-circle d-inline-flex align-items-center justify-content-center mb-3 feature-icon" style="width: 60px; height: 60px;">
120
120
  <i class="bi bi-boxes fs-4"></i>
121
121
  </div>
122
- <h5 class="card-title text-body-emphasis">Docker-First Approach</h5>
123
- <p class="card-text text-body-secondary">Cross-platform compatibility with zero local configuration. Works on Apple Silicon, Intel, and Linux.</p>
122
+ <h5 class="card-title text-body-emphasis">Docker-First Approach</h5>
123
+ <p class="card-text text-body-secondary">Cross-platform compatibility with zero local configuration. Works on Apple Silicon, Intel, and Linux.</p>
124
124
  </div>
125
125
  </div>
126
126
  </div>
127
127
 
128
128
  <div class="col-md-4">
129
- <div class="card h-100 border-0 shadow-sm">
129
+ <div class="card h-100 border-0 shadow-sm feature-card">
130
130
  <div class="card-body text-center p-4">
131
- <div class="bg-info text-white rounded-circle d-inline-flex align-items-center justify-content-center mb-3" style="width: 60px; height: 60px;">
131
+ <div class="bg-info text-white rounded-circle d-inline-flex align-items-center justify-content-center mb-3 feature-icon" style="width: 60px; height: 60px;">
132
132
  <i class="bi bi-lightning-charge fs-4"></i>
133
133
  </div>
134
- <h5 class="card-title text-body-emphasis">AI-Powered Setup</h5>
135
- <p class="card-text text-body-secondary">Intelligent installation automation that detects and fixes common issues automatically.</p>
134
+ <h5 class="card-title text-body-emphasis">AI-Powered Setup</h5>
135
+ <p class="card-text text-body-secondary">Intelligent installation automation that detects and fixes common issues automatically.</p>
136
136
  </div>
137
137
  </div>
138
138
  </div>