jekyll-theme-zer0 0.22.0 → 0.22.19

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.
Files changed (95) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +236 -0
  3. data/README.md +66 -19
  4. data/_data/navigation/admin.yml +53 -0
  5. data/_data/theme_backgrounds.yml +121 -0
  6. data/_includes/components/admin-tabs.html +59 -0
  7. data/_includes/components/analytics-dashboard.html +232 -0
  8. data/_includes/components/background-customizer.html +159 -0
  9. data/_includes/components/background-settings.html +137 -0
  10. data/_includes/components/collection-manager.html +151 -0
  11. data/_includes/components/component-showcase.html +452 -0
  12. data/_includes/components/config-editor.html +207 -0
  13. data/_includes/components/config-viewer.html +479 -0
  14. data/_includes/components/env-dashboard.html +154 -0
  15. data/_includes/components/feature-card.html +94 -0
  16. data/_includes/components/info-section.html +172 -149
  17. data/_includes/components/js-cdn.html +4 -1
  18. data/_includes/components/nav-editor.html +99 -0
  19. data/_includes/components/setup-banner.html +28 -0
  20. data/_includes/components/setup-check.html +53 -0
  21. data/_includes/components/svg-background.html +42 -0
  22. data/_includes/components/theme-customizer.html +46 -0
  23. data/_includes/content/seo.html +68 -135
  24. data/_includes/core/footer.html +1 -1
  25. data/_includes/core/head.html +3 -2
  26. data/_includes/core/header.html +14 -7
  27. data/_includes/landing/landing-install-cards.html +18 -7
  28. data/_includes/navigation/admin-nav.html +95 -0
  29. data/_includes/navigation/navbar.html +43 -5
  30. data/_includes/navigation/sidebar-left.html +1 -1
  31. data/_includes/setup/wizard.html +330 -0
  32. data/_layouts/admin.html +166 -0
  33. data/_layouts/landing.html +23 -9
  34. data/_layouts/root.html +12 -6
  35. data/_layouts/setup.html +73 -0
  36. data/_plugins/preview_image_generator.rb +26 -12
  37. data/_sass/core/_navbar.scss +2 -2
  38. data/_sass/custom.scss +28 -6
  39. data/_sass/theme/_background-mixins.scss +95 -0
  40. data/_sass/theme/_backgrounds.scss +156 -0
  41. data/_sass/theme/_color-modes.scss +2 -1
  42. data/assets/backgrounds/gradients/air.svg +15 -0
  43. data/assets/backgrounds/gradients/aqua.svg +15 -0
  44. data/assets/backgrounds/gradients/contrast.svg +15 -0
  45. data/assets/backgrounds/gradients/dark.svg +15 -0
  46. data/assets/backgrounds/gradients/dirt.svg +15 -0
  47. data/assets/backgrounds/gradients/mint.svg +15 -0
  48. data/assets/backgrounds/gradients/neon.svg +15 -0
  49. data/assets/backgrounds/gradients/plum.svg +15 -0
  50. data/assets/backgrounds/gradients/sunrise.svg +15 -0
  51. data/assets/backgrounds/noise/air.svg +8 -0
  52. data/assets/backgrounds/noise/aqua.svg +8 -0
  53. data/assets/backgrounds/noise/contrast.svg +8 -0
  54. data/assets/backgrounds/noise/dark.svg +8 -0
  55. data/assets/backgrounds/noise/dirt.svg +8 -0
  56. data/assets/backgrounds/noise/mint.svg +8 -0
  57. data/assets/backgrounds/noise/neon.svg +8 -0
  58. data/assets/backgrounds/noise/plum.svg +8 -0
  59. data/assets/backgrounds/noise/sunrise.svg +8 -0
  60. data/assets/backgrounds/patterns/air.svg +7 -0
  61. data/assets/backgrounds/patterns/aqua.svg +7 -0
  62. data/assets/backgrounds/patterns/contrast.svg +4 -0
  63. data/assets/backgrounds/patterns/dark.svg +5 -0
  64. data/assets/backgrounds/patterns/dirt.svg +5 -0
  65. data/assets/backgrounds/patterns/mint.svg +6 -0
  66. data/assets/backgrounds/patterns/neon.svg +6 -0
  67. data/assets/backgrounds/patterns/plum.svg +6 -0
  68. data/assets/backgrounds/patterns/sunrise.svg +5 -0
  69. data/assets/js/background-customizer.js +73 -0
  70. data/assets/js/code-copy.js +18 -47
  71. data/assets/js/config-utility.js +307 -0
  72. data/assets/js/nav-editor.js +39 -0
  73. data/assets/js/palette-generator.js +415 -0
  74. data/assets/js/search-modal.js +31 -11
  75. data/assets/js/setup-wizard.js +306 -0
  76. data/assets/js/skin-editor.js +645 -0
  77. data/assets/js/theme-customizer.js +102 -0
  78. data/assets/js/ui-enhancements.js +15 -24
  79. data/assets/vendor/bootstrap/css/bootstrap.min.css +1 -0
  80. data/assets/vendor/bootstrap/js/bootstrap.bundle.min.js +1 -0
  81. data/scripts/README.md +45 -0
  82. data/scripts/features/generate-preview-images +297 -7
  83. data/scripts/features/install-preview-generator +51 -33
  84. data/scripts/fork-cleanup.sh +92 -19
  85. data/scripts/github-setup.sh +284 -0
  86. data/scripts/init_setup.sh +0 -1
  87. data/scripts/lib/frontmatter.sh +543 -0
  88. data/scripts/lib/migrate.sh +265 -0
  89. data/scripts/lib/preview_generator.py +607 -32
  90. data/scripts/lint-pages +505 -0
  91. data/scripts/migrate.sh +201 -0
  92. data/scripts/platform/setup-linux.sh +244 -0
  93. data/scripts/platform/setup-macos.sh +187 -0
  94. data/scripts/platform/setup-wsl.sh +196 -0
  95. metadata +71 -6
@@ -0,0 +1,102 @@
1
+ /**
2
+ * theme-customizer.js
3
+ * Powers the Theme Customizer admin page.
4
+ * - Skin preview: clicking a card swaps data-bs-theme for page-level preview
5
+ * - Color editor: syncs color picker ↔ text inputs
6
+ * - YAML export: builds theme_skin + theme_color YAML from current selections
7
+ */
8
+
9
+ document.addEventListener('DOMContentLoaded', function () {
10
+ 'use strict';
11
+
12
+ /* ── Skin Preview ─────────────────────────────────────────── */
13
+ const skinGrid = document.getElementById('skin-grid');
14
+ let selectedSkin = document.querySelector('.skin-card.border-primary');
15
+
16
+ if (skinGrid) {
17
+ skinGrid.addEventListener('click', function (e) {
18
+ const card = e.target.closest('.skin-card');
19
+ if (!card) return;
20
+
21
+ // Visual: deselect previous, select new
22
+ if (selectedSkin) {
23
+ selectedSkin.classList.replace('border-primary', 'border-secondary');
24
+ const prev = selectedSkin.querySelector('.badge');
25
+ if (prev) prev.outerHTML = '<small class="text-body-tertiary">Click to preview</small>';
26
+ const prevIcon = selectedSkin.querySelector('.bi-circle-fill');
27
+ if (prevIcon) { prevIcon.classList.remove('text-primary'); prevIcon.classList.add('text-body-secondary'); }
28
+ }
29
+
30
+ card.classList.replace('border-secondary', 'border-primary');
31
+ const label = card.querySelector('small');
32
+ if (label) label.outerHTML = '<span class="badge bg-primary"><i class="bi bi-check-circle me-1"></i>Selected</span>';
33
+ const icon = card.querySelector('.bi-circle-fill');
34
+ if (icon) { icon.classList.remove('text-body-secondary'); icon.classList.add('text-primary'); }
35
+
36
+ selectedSkin = card;
37
+ rebuildYaml();
38
+ });
39
+ }
40
+
41
+ /* ── Color Editor ─────────────────────────────────────────── */
42
+ document.querySelectorAll('[data-color-key]').forEach(function (picker) {
43
+ picker.addEventListener('input', function () {
44
+ const key = this.dataset.colorKey;
45
+ const textInput = document.querySelector('[data-color-text="' + key + '"]');
46
+ if (textInput) textInput.value = this.value;
47
+ rebuildYaml();
48
+ });
49
+ });
50
+
51
+ /* ── YAML Export ──────────────────────────────────────────── */
52
+ function rebuildYaml() {
53
+ // If palette-generator.js provides a full YAML builder, use it
54
+ if (typeof rebuildFullYaml === 'function') {
55
+ rebuildFullYaml();
56
+ return;
57
+ }
58
+ var lines = [];
59
+ // Skin
60
+ var skin = selectedSkin ? selectedSkin.dataset.skin : 'dark';
61
+ lines.push('theme_skin: "' + skin + '"');
62
+ lines.push('');
63
+ // Colors
64
+ lines.push('theme_color:');
65
+ document.querySelectorAll('[data-color-key]').forEach(function (el) {
66
+ var key = el.dataset.colorKey;
67
+ var val = el.value;
68
+ lines.push(' ' + key + ': ' + val);
69
+ });
70
+ var yaml = lines.join('\n');
71
+ var output = document.getElementById('theme-yaml-output');
72
+ if (output) output.textContent = yaml;
73
+ }
74
+
75
+ // Initial build
76
+ rebuildYaml();
77
+
78
+ /* ── Copy / Download Buttons ──────────────────────────────── */
79
+ var copyBtn = document.getElementById('theme-copy-yaml');
80
+ if (copyBtn) {
81
+ copyBtn.addEventListener('click', function () {
82
+ var text = document.getElementById('theme-yaml-output').textContent;
83
+ navigator.clipboard.writeText(text).then(function () {
84
+ copyBtn.innerHTML = '<i class="bi bi-check me-1"></i> Copied';
85
+ setTimeout(function () { copyBtn.innerHTML = '<i class="bi bi-clipboard me-1"></i> Copy'; }, 2000);
86
+ });
87
+ });
88
+ }
89
+
90
+ var dlBtn = document.getElementById('theme-download-yaml');
91
+ if (dlBtn) {
92
+ dlBtn.addEventListener('click', function () {
93
+ var text = document.getElementById('theme-yaml-output').textContent;
94
+ var blob = new Blob([text], { type: 'text/yaml' });
95
+ var a = document.createElement('a');
96
+ a.href = URL.createObjectURL(blob);
97
+ a.download = 'theme-config.yml';
98
+ a.click();
99
+ URL.revokeObjectURL(a.href);
100
+ });
101
+ }
102
+ });
@@ -12,6 +12,16 @@
12
12
  /**
13
13
  * Initialize scroll animations for elements with animate-on-scroll class
14
14
  */
15
+ /**
16
+ * True if any part of the element is in the viewport (avoids hiding above-the-fold
17
+ * content until IntersectionObserver runs — that caused layout “jumps” on the landing hero).
18
+ */
19
+ function isInViewport(el) {
20
+ const rect = el.getBoundingClientRect();
21
+ const vh = window.innerHeight || document.documentElement.clientHeight;
22
+ return rect.bottom > 0 && rect.top < vh;
23
+ }
24
+
15
25
  function initScrollAnimations() {
16
26
  if (prefersReducedMotion) return;
17
27
 
@@ -35,6 +45,9 @@
35
45
  }, observerOptions);
36
46
 
37
47
  animatedElements.forEach(el => {
48
+ if (isInViewport(el)) {
49
+ return;
50
+ }
38
51
  el.style.opacity = '0';
39
52
  el.style.transform = 'translateY(30px)';
40
53
  el.style.transition = 'opacity 0.6s ease-out, transform 0.6s ease-out';
@@ -42,29 +55,6 @@
42
55
  });
43
56
  }
44
57
 
45
- /**
46
- * Smooth scroll for anchor links
47
- */
48
- function initSmoothScroll() {
49
- document.querySelectorAll('a[href^="#"]').forEach(anchor => {
50
- anchor.addEventListener('click', function(e) {
51
- const href = this.getAttribute('href');
52
- if (href === '#' || href === '') return;
53
-
54
- const target = document.querySelector(href);
55
- if (target) {
56
- e.preventDefault();
57
- const offsetTop = target.offsetTop - 80; // Account for fixed navbar
58
-
59
- window.scrollTo({
60
- top: offsetTop,
61
- behavior: prefersReducedMotion ? 'auto' : 'smooth'
62
- });
63
- }
64
- });
65
- });
66
- }
67
-
68
58
  /**
69
59
  * Add loading state to images
70
60
  */
@@ -152,7 +142,8 @@
152
142
  }
153
143
 
154
144
  initScrollAnimations();
155
- initSmoothScroll();
145
+ // Note: Smooth scrolling for anchor links is handled entirely by CSS
146
+ // (scroll-behavior: smooth + scroll-padding-top: 80px in custom.scss)
156
147
  initImageLoading();
157
148
  initButtonRipples();
158
149
  initScrollSpy();