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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +236 -0
- data/README.md +66 -19
- data/_data/navigation/admin.yml +53 -0
- data/_data/theme_backgrounds.yml +121 -0
- data/_includes/components/admin-tabs.html +59 -0
- data/_includes/components/analytics-dashboard.html +232 -0
- data/_includes/components/background-customizer.html +159 -0
- data/_includes/components/background-settings.html +137 -0
- data/_includes/components/collection-manager.html +151 -0
- data/_includes/components/component-showcase.html +452 -0
- data/_includes/components/config-editor.html +207 -0
- data/_includes/components/config-viewer.html +479 -0
- data/_includes/components/env-dashboard.html +154 -0
- data/_includes/components/feature-card.html +94 -0
- data/_includes/components/info-section.html +172 -149
- data/_includes/components/js-cdn.html +4 -1
- data/_includes/components/nav-editor.html +99 -0
- data/_includes/components/setup-banner.html +28 -0
- data/_includes/components/setup-check.html +53 -0
- data/_includes/components/svg-background.html +42 -0
- data/_includes/components/theme-customizer.html +46 -0
- data/_includes/content/seo.html +68 -135
- data/_includes/core/footer.html +1 -1
- data/_includes/core/head.html +3 -2
- data/_includes/core/header.html +14 -7
- data/_includes/landing/landing-install-cards.html +18 -7
- data/_includes/navigation/admin-nav.html +95 -0
- data/_includes/navigation/navbar.html +43 -5
- data/_includes/navigation/sidebar-left.html +1 -1
- data/_includes/setup/wizard.html +330 -0
- data/_layouts/admin.html +166 -0
- data/_layouts/landing.html +23 -9
- data/_layouts/root.html +12 -6
- data/_layouts/setup.html +73 -0
- data/_plugins/preview_image_generator.rb +26 -12
- data/_sass/core/_navbar.scss +2 -2
- data/_sass/custom.scss +28 -6
- data/_sass/theme/_background-mixins.scss +95 -0
- data/_sass/theme/_backgrounds.scss +156 -0
- data/_sass/theme/_color-modes.scss +2 -1
- data/assets/backgrounds/gradients/air.svg +15 -0
- data/assets/backgrounds/gradients/aqua.svg +15 -0
- data/assets/backgrounds/gradients/contrast.svg +15 -0
- data/assets/backgrounds/gradients/dark.svg +15 -0
- data/assets/backgrounds/gradients/dirt.svg +15 -0
- data/assets/backgrounds/gradients/mint.svg +15 -0
- data/assets/backgrounds/gradients/neon.svg +15 -0
- data/assets/backgrounds/gradients/plum.svg +15 -0
- data/assets/backgrounds/gradients/sunrise.svg +15 -0
- data/assets/backgrounds/noise/air.svg +8 -0
- data/assets/backgrounds/noise/aqua.svg +8 -0
- data/assets/backgrounds/noise/contrast.svg +8 -0
- data/assets/backgrounds/noise/dark.svg +8 -0
- data/assets/backgrounds/noise/dirt.svg +8 -0
- data/assets/backgrounds/noise/mint.svg +8 -0
- data/assets/backgrounds/noise/neon.svg +8 -0
- data/assets/backgrounds/noise/plum.svg +8 -0
- data/assets/backgrounds/noise/sunrise.svg +8 -0
- data/assets/backgrounds/patterns/air.svg +7 -0
- data/assets/backgrounds/patterns/aqua.svg +7 -0
- data/assets/backgrounds/patterns/contrast.svg +4 -0
- data/assets/backgrounds/patterns/dark.svg +5 -0
- data/assets/backgrounds/patterns/dirt.svg +5 -0
- data/assets/backgrounds/patterns/mint.svg +6 -0
- data/assets/backgrounds/patterns/neon.svg +6 -0
- data/assets/backgrounds/patterns/plum.svg +6 -0
- data/assets/backgrounds/patterns/sunrise.svg +5 -0
- data/assets/js/background-customizer.js +73 -0
- data/assets/js/code-copy.js +18 -47
- data/assets/js/config-utility.js +307 -0
- data/assets/js/nav-editor.js +39 -0
- data/assets/js/palette-generator.js +415 -0
- data/assets/js/search-modal.js +31 -11
- data/assets/js/setup-wizard.js +306 -0
- data/assets/js/skin-editor.js +645 -0
- data/assets/js/theme-customizer.js +102 -0
- data/assets/js/ui-enhancements.js +15 -24
- data/assets/vendor/bootstrap/css/bootstrap.min.css +1 -0
- data/assets/vendor/bootstrap/js/bootstrap.bundle.min.js +1 -0
- data/scripts/README.md +45 -0
- data/scripts/features/generate-preview-images +297 -7
- data/scripts/features/install-preview-generator +51 -33
- data/scripts/fork-cleanup.sh +92 -19
- data/scripts/github-setup.sh +284 -0
- data/scripts/init_setup.sh +0 -1
- data/scripts/lib/frontmatter.sh +543 -0
- data/scripts/lib/migrate.sh +265 -0
- data/scripts/lib/preview_generator.py +607 -32
- data/scripts/lint-pages +505 -0
- data/scripts/migrate.sh +201 -0
- data/scripts/platform/setup-linux.sh +244 -0
- data/scripts/platform/setup-macos.sh +187 -0
- data/scripts/platform/setup-wsl.sh +196 -0
- metadata +71 -6
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
===================================================================
|
|
3
|
+
ANALYTICS DASHBOARD — PostHog & tracking configuration overview
|
|
4
|
+
===================================================================
|
|
5
|
+
|
|
6
|
+
File: analytics-dashboard.html
|
|
7
|
+
Path: _includes/components/analytics-dashboard.html
|
|
8
|
+
Purpose: Shows current analytics configuration, privacy settings,
|
|
9
|
+
and tracking status. Reads from site.posthog config.
|
|
10
|
+
|
|
11
|
+
Dependencies: Bootstrap 5 card/table/badge, site.posthog config
|
|
12
|
+
Used by: pages/_about/settings/analytics.md
|
|
13
|
+
===================================================================
|
|
14
|
+
-->
|
|
15
|
+
|
|
16
|
+
{% assign ph = site.posthog %}
|
|
17
|
+
|
|
18
|
+
<!-- Status cards -->
|
|
19
|
+
<div class="row g-3 mb-4">
|
|
20
|
+
<div class="col-6 col-lg-3">
|
|
21
|
+
<div class="card text-center h-100 {% if ph.enabled %}border-success{% else %}border-warning{% endif %}">
|
|
22
|
+
<div class="card-body py-3">
|
|
23
|
+
<i class="bi bi-graph-up fs-3 {% if ph.enabled %}text-success{% else %}text-warning{% endif %}"></i>
|
|
24
|
+
<div class="fw-semibold mt-1">{{ ph.enabled | default: false }}</div>
|
|
25
|
+
<small class="text-body-secondary">PostHog Enabled</small>
|
|
26
|
+
</div>
|
|
27
|
+
</div>
|
|
28
|
+
</div>
|
|
29
|
+
<div class="col-6 col-lg-3">
|
|
30
|
+
<div class="card text-center h-100 border-primary">
|
|
31
|
+
<div class="card-body py-3">
|
|
32
|
+
<i class="bi bi-shield-check fs-3 text-primary"></i>
|
|
33
|
+
<div class="fw-semibold mt-1">{{ ph.respect_dnt | default: false }}</div>
|
|
34
|
+
<small class="text-body-secondary">Respect DNT</small>
|
|
35
|
+
</div>
|
|
36
|
+
</div>
|
|
37
|
+
</div>
|
|
38
|
+
<div class="col-6 col-lg-3">
|
|
39
|
+
<div class="card text-center h-100 border-primary">
|
|
40
|
+
<div class="card-body py-3">
|
|
41
|
+
<i class="bi bi-camera-video fs-3 text-primary"></i>
|
|
42
|
+
<div class="fw-semibold mt-1">{{ ph.session_recording | default: false }}</div>
|
|
43
|
+
<small class="text-body-secondary">Session Recording</small>
|
|
44
|
+
</div>
|
|
45
|
+
</div>
|
|
46
|
+
</div>
|
|
47
|
+
<div class="col-6 col-lg-3">
|
|
48
|
+
<div class="card text-center h-100 border-primary">
|
|
49
|
+
<div class="card-body py-3">
|
|
50
|
+
<i class="bi bi-cookie fs-3 text-primary"></i>
|
|
51
|
+
<div class="fw-semibold mt-1">{{ ph.secure_cookie | default: false }}</div>
|
|
52
|
+
<small class="text-body-secondary">Secure Cookies</small>
|
|
53
|
+
</div>
|
|
54
|
+
</div>
|
|
55
|
+
</div>
|
|
56
|
+
</div>
|
|
57
|
+
|
|
58
|
+
<!-- Configuration Details -->
|
|
59
|
+
<div class="row g-4">
|
|
60
|
+
|
|
61
|
+
<!-- PostHog Settings -->
|
|
62
|
+
<div class="col-lg-6">
|
|
63
|
+
<div class="card h-100">
|
|
64
|
+
<div class="card-header"><i class="bi bi-gear me-1"></i> PostHog Configuration</div>
|
|
65
|
+
<div class="card-body p-0">
|
|
66
|
+
<table class="table table-sm mb-0">
|
|
67
|
+
<tbody>
|
|
68
|
+
<tr>
|
|
69
|
+
<td class="fw-semibold">Enabled</td>
|
|
70
|
+
<td>
|
|
71
|
+
{% if ph.enabled %}
|
|
72
|
+
<span class="badge bg-success">Yes</span>
|
|
73
|
+
{% else %}
|
|
74
|
+
<span class="badge bg-secondary">No</span>
|
|
75
|
+
{% endif %}
|
|
76
|
+
</td>
|
|
77
|
+
</tr>
|
|
78
|
+
<tr>
|
|
79
|
+
<td class="fw-semibold">API Host</td>
|
|
80
|
+
<td><code class="small">{{ ph.api_host | default: "not set" }}</code></td>
|
|
81
|
+
</tr>
|
|
82
|
+
<tr>
|
|
83
|
+
<td class="fw-semibold">Person Profiles</td>
|
|
84
|
+
<td><code class="small">{{ ph.person_profiles | default: "not set" }}</code></td>
|
|
85
|
+
</tr>
|
|
86
|
+
<tr>
|
|
87
|
+
<td class="fw-semibold">Autocapture</td>
|
|
88
|
+
<td>{{ ph.autocapture | default: false }}</td>
|
|
89
|
+
</tr>
|
|
90
|
+
<tr>
|
|
91
|
+
<td class="fw-semibold">Page Views</td>
|
|
92
|
+
<td>{{ ph.capture_pageview | default: false }}</td>
|
|
93
|
+
</tr>
|
|
94
|
+
<tr>
|
|
95
|
+
<td class="fw-semibold">Page Leave</td>
|
|
96
|
+
<td>{{ ph.capture_pageleave | default: false }}</td>
|
|
97
|
+
</tr>
|
|
98
|
+
<tr>
|
|
99
|
+
<td class="fw-semibold">Persistence</td>
|
|
100
|
+
<td><code class="small">{{ ph.persistence | default: "not set" }}</code></td>
|
|
101
|
+
</tr>
|
|
102
|
+
</tbody>
|
|
103
|
+
</table>
|
|
104
|
+
</div>
|
|
105
|
+
</div>
|
|
106
|
+
</div>
|
|
107
|
+
|
|
108
|
+
<!-- Privacy & Compliance -->
|
|
109
|
+
<div class="col-lg-6">
|
|
110
|
+
<div class="card h-100">
|
|
111
|
+
<div class="card-header"><i class="bi bi-shield-lock me-1"></i> Privacy & Compliance</div>
|
|
112
|
+
<div class="card-body p-0">
|
|
113
|
+
<table class="table table-sm mb-0">
|
|
114
|
+
<tbody>
|
|
115
|
+
<tr>
|
|
116
|
+
<td class="fw-semibold">Respect Do Not Track</td>
|
|
117
|
+
<td>
|
|
118
|
+
{% if ph.respect_dnt %}
|
|
119
|
+
<span class="badge bg-success">Yes</span>
|
|
120
|
+
{% else %}
|
|
121
|
+
<span class="badge bg-warning">No</span>
|
|
122
|
+
{% endif %}
|
|
123
|
+
</td>
|
|
124
|
+
</tr>
|
|
125
|
+
<tr>
|
|
126
|
+
<td class="fw-semibold">Session Recording</td>
|
|
127
|
+
<td>
|
|
128
|
+
{% if ph.session_recording %}
|
|
129
|
+
<span class="badge bg-warning">Enabled</span>
|
|
130
|
+
{% else %}
|
|
131
|
+
<span class="badge bg-success">Disabled</span>
|
|
132
|
+
{% endif %}
|
|
133
|
+
</td>
|
|
134
|
+
</tr>
|
|
135
|
+
<tr>
|
|
136
|
+
<td class="fw-semibold">Disable Cookies</td>
|
|
137
|
+
<td>{{ ph.disable_cookie | default: false }}</td>
|
|
138
|
+
</tr>
|
|
139
|
+
<tr>
|
|
140
|
+
<td class="fw-semibold">Secure Cookies</td>
|
|
141
|
+
<td>
|
|
142
|
+
{% if ph.secure_cookie %}
|
|
143
|
+
<span class="badge bg-success">Yes</span>
|
|
144
|
+
{% else %}
|
|
145
|
+
<span class="badge bg-secondary">No</span>
|
|
146
|
+
{% endif %}
|
|
147
|
+
</td>
|
|
148
|
+
</tr>
|
|
149
|
+
<tr>
|
|
150
|
+
<td class="fw-semibold">Cross-Subdomain</td>
|
|
151
|
+
<td>{{ ph.cross_subdomain_cookie | default: false }}</td>
|
|
152
|
+
</tr>
|
|
153
|
+
{% if ph.privacy %}
|
|
154
|
+
<tr><td class="fw-semibold">Mask All Text</td><td>{{ ph.privacy.mask_all_text | default: false }}</td></tr>
|
|
155
|
+
<tr><td class="fw-semibold">Mask All Inputs</td><td>{{ ph.privacy.mask_all_inputs | default: false }}</td></tr>
|
|
156
|
+
<tr><td class="fw-semibold">IP Anonymization</td><td>{{ ph.privacy.ip_anonymization | default: false }}</td></tr>
|
|
157
|
+
{% endif %}
|
|
158
|
+
</tbody>
|
|
159
|
+
</table>
|
|
160
|
+
</div>
|
|
161
|
+
</div>
|
|
162
|
+
</div>
|
|
163
|
+
</div>
|
|
164
|
+
|
|
165
|
+
<!-- Custom Events -->
|
|
166
|
+
{% if ph.custom_events %}
|
|
167
|
+
<h5 class="mt-4 mb-3"><i class="bi bi-lightning me-1"></i> Custom Event Tracking</h5>
|
|
168
|
+
<div class="row g-3">
|
|
169
|
+
{% if ph.custom_events.track_downloads != nil %}
|
|
170
|
+
<div class="col-6 col-md-3">
|
|
171
|
+
<div class="card text-center">
|
|
172
|
+
<div class="card-body py-2">
|
|
173
|
+
<i class="bi bi-download fs-5 {% if ph.custom_events.track_downloads %}text-success{% else %}text-body-secondary{% endif %}"></i>
|
|
174
|
+
<div class="small fw-semibold mt-1">Downloads</div>
|
|
175
|
+
<span class="badge {% if ph.custom_events.track_downloads %}bg-success{% else %}bg-secondary{% endif %}">
|
|
176
|
+
{{ ph.custom_events.track_downloads }}
|
|
177
|
+
</span>
|
|
178
|
+
</div>
|
|
179
|
+
</div>
|
|
180
|
+
</div>
|
|
181
|
+
{% endif %}
|
|
182
|
+
{% if ph.custom_events.track_external_links != nil %}
|
|
183
|
+
<div class="col-6 col-md-3">
|
|
184
|
+
<div class="card text-center">
|
|
185
|
+
<div class="card-body py-2">
|
|
186
|
+
<i class="bi bi-box-arrow-up-right fs-5 {% if ph.custom_events.track_external_links %}text-success{% else %}text-body-secondary{% endif %}"></i>
|
|
187
|
+
<div class="small fw-semibold mt-1">External Links</div>
|
|
188
|
+
<span class="badge {% if ph.custom_events.track_external_links %}bg-success{% else %}bg-secondary{% endif %}">
|
|
189
|
+
{{ ph.custom_events.track_external_links }}
|
|
190
|
+
</span>
|
|
191
|
+
</div>
|
|
192
|
+
</div>
|
|
193
|
+
</div>
|
|
194
|
+
{% endif %}
|
|
195
|
+
{% if ph.custom_events.track_search != nil %}
|
|
196
|
+
<div class="col-6 col-md-3">
|
|
197
|
+
<div class="card text-center">
|
|
198
|
+
<div class="card-body py-2">
|
|
199
|
+
<i class="bi bi-search fs-5 {% if ph.custom_events.track_search %}text-success{% else %}text-body-secondary{% endif %}"></i>
|
|
200
|
+
<div class="small fw-semibold mt-1">Search</div>
|
|
201
|
+
<span class="badge {% if ph.custom_events.track_search %}bg-success{% else %}bg-secondary{% endif %}">
|
|
202
|
+
{{ ph.custom_events.track_search }}
|
|
203
|
+
</span>
|
|
204
|
+
</div>
|
|
205
|
+
</div>
|
|
206
|
+
</div>
|
|
207
|
+
{% endif %}
|
|
208
|
+
{% if ph.custom_events.track_scroll_depth != nil %}
|
|
209
|
+
<div class="col-6 col-md-3">
|
|
210
|
+
<div class="card text-center">
|
|
211
|
+
<div class="card-body py-2">
|
|
212
|
+
<i class="bi bi-arrows-vertical fs-5 {% if ph.custom_events.track_scroll_depth %}text-success{% else %}text-body-secondary{% endif %}"></i>
|
|
213
|
+
<div class="small fw-semibold mt-1">Scroll Depth</div>
|
|
214
|
+
<span class="badge {% if ph.custom_events.track_scroll_depth %}bg-success{% else %}bg-secondary{% endif %}">
|
|
215
|
+
{{ ph.custom_events.track_scroll_depth }}
|
|
216
|
+
</span>
|
|
217
|
+
</div>
|
|
218
|
+
</div>
|
|
219
|
+
</div>
|
|
220
|
+
{% endif %}
|
|
221
|
+
</div>
|
|
222
|
+
{% endif %}
|
|
223
|
+
|
|
224
|
+
<!-- External Links -->
|
|
225
|
+
<div class="mt-4">
|
|
226
|
+
<a href="https://us.posthog.com" target="_blank" rel="noopener" class="btn btn-outline-primary btn-sm me-2">
|
|
227
|
+
<i class="bi bi-box-arrow-up-right me-1"></i> Open PostHog Dashboard
|
|
228
|
+
</a>
|
|
229
|
+
<a href="{{ '/about/config/' | relative_url }}" class="btn btn-outline-secondary btn-sm">
|
|
230
|
+
<i class="bi bi-gear me-1"></i> Full Configuration
|
|
231
|
+
</a>
|
|
232
|
+
</div>
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
===================================================================
|
|
3
|
+
BACKGROUND CUSTOMIZER — fffuel-style background settings panel
|
|
4
|
+
===================================================================
|
|
5
|
+
|
|
6
|
+
File: background-customizer.html
|
|
7
|
+
Path: _includes/components/background-customizer.html
|
|
8
|
+
Purpose: Bootstrap 5 offcanvas panel for switching skins and
|
|
9
|
+
tuning SVG background layers at runtime.
|
|
10
|
+
|
|
11
|
+
Dependencies:
|
|
12
|
+
- assets/js/background-customizer.js (zer0Bg API)
|
|
13
|
+
- _sass/theme/_backgrounds.scss (CSS custom properties)
|
|
14
|
+
- Bootstrap 5 offcanvas + form components
|
|
15
|
+
===================================================================
|
|
16
|
+
-->
|
|
17
|
+
|
|
18
|
+
{% assign skins = "air,aqua,contrast,dark,dirt,neon,mint,plum,sunrise" | split: "," %}
|
|
19
|
+
{% assign current_skin = site.theme_skin | default: "dark" %}
|
|
20
|
+
|
|
21
|
+
<!-- Floating toggle button -->
|
|
22
|
+
<button class="btn btn-sm btn-outline-secondary position-fixed bottom-0 end-0 m-3 rounded-circle"
|
|
23
|
+
style="z-index: 1090; width: 40px; height: 40px;"
|
|
24
|
+
type="button"
|
|
25
|
+
data-bs-toggle="offcanvas"
|
|
26
|
+
data-bs-target="#zer0BgCustomizer"
|
|
27
|
+
aria-label="Customize background"
|
|
28
|
+
title="Background settings">
|
|
29
|
+
<i class="bi bi-palette2"></i>
|
|
30
|
+
</button>
|
|
31
|
+
|
|
32
|
+
<!-- Offcanvas panel -->
|
|
33
|
+
<div class="offcanvas offcanvas-end" tabindex="-1" id="zer0BgCustomizer" aria-labelledby="zer0BgCustomizerLabel">
|
|
34
|
+
<div class="offcanvas-header">
|
|
35
|
+
<h5 class="offcanvas-title" id="zer0BgCustomizerLabel">
|
|
36
|
+
<i class="bi bi-palette2 me-2"></i>Background Settings
|
|
37
|
+
</h5>
|
|
38
|
+
<button type="button" class="btn-close" data-bs-dismiss="offcanvas" aria-label="Close"></button>
|
|
39
|
+
</div>
|
|
40
|
+
|
|
41
|
+
<div class="offcanvas-body">
|
|
42
|
+
<!-- Skin selector -->
|
|
43
|
+
<div class="mb-4">
|
|
44
|
+
<label class="form-label fw-semibold">Theme Skin</label>
|
|
45
|
+
<div class="d-flex flex-wrap gap-2" id="zer0SkinButtons">
|
|
46
|
+
{% for skin in skins %}
|
|
47
|
+
<button class="btn btn-sm btn-outline-primary{% if skin == current_skin %} active{% endif %}"
|
|
48
|
+
data-skin="{{ skin }}"
|
|
49
|
+
type="button">
|
|
50
|
+
{{ skin | capitalize }}
|
|
51
|
+
</button>
|
|
52
|
+
{% endfor %}
|
|
53
|
+
</div>
|
|
54
|
+
</div>
|
|
55
|
+
|
|
56
|
+
<hr>
|
|
57
|
+
|
|
58
|
+
<!-- Background toggle -->
|
|
59
|
+
<div class="mb-3">
|
|
60
|
+
<div class="form-check form-switch">
|
|
61
|
+
<input class="form-check-input" type="checkbox" id="zer0BgToggle" checked>
|
|
62
|
+
<label class="form-check-label" for="zer0BgToggle">Enable SVG backgrounds</label>
|
|
63
|
+
</div>
|
|
64
|
+
</div>
|
|
65
|
+
|
|
66
|
+
<hr>
|
|
67
|
+
|
|
68
|
+
<!-- Opacity sliders -->
|
|
69
|
+
<div class="mb-3">
|
|
70
|
+
<label class="form-label" for="zer0GradientOpacity">Gradient opacity</label>
|
|
71
|
+
<input type="range" class="form-range" id="zer0GradientOpacity"
|
|
72
|
+
min="0" max="1" step="0.05" value="0.6">
|
|
73
|
+
<small class="text-body-secondary"><span id="zer0GradientOpacityVal">0.6</span></small>
|
|
74
|
+
</div>
|
|
75
|
+
|
|
76
|
+
<div class="mb-3">
|
|
77
|
+
<label class="form-label" for="zer0TextureOpacity">Texture opacity</label>
|
|
78
|
+
<input type="range" class="form-range" id="zer0TextureOpacity"
|
|
79
|
+
min="0" max="0.2" step="0.005" value="0.04">
|
|
80
|
+
<small class="text-body-secondary"><span id="zer0TextureOpacityVal">0.04</span></small>
|
|
81
|
+
</div>
|
|
82
|
+
|
|
83
|
+
<div class="mb-3">
|
|
84
|
+
<label class="form-label" for="zer0PatternOpacity">Pattern opacity</label>
|
|
85
|
+
<input type="range" class="form-range" id="zer0PatternOpacity"
|
|
86
|
+
min="0" max="0.3" step="0.01" value="0.08">
|
|
87
|
+
<small class="text-body-secondary"><span id="zer0PatternOpacityVal">0.08</span></small>
|
|
88
|
+
</div>
|
|
89
|
+
|
|
90
|
+
<hr>
|
|
91
|
+
|
|
92
|
+
<button class="btn btn-sm btn-outline-danger" id="zer0BgReset" type="button">
|
|
93
|
+
<i class="bi bi-arrow-counterclockwise me-1"></i>Reset to defaults
|
|
94
|
+
</button>
|
|
95
|
+
</div>
|
|
96
|
+
</div>
|
|
97
|
+
|
|
98
|
+
<!-- Customizer interaction logic -->
|
|
99
|
+
<script>
|
|
100
|
+
document.addEventListener("DOMContentLoaded", function () {
|
|
101
|
+
if (typeof zer0Bg === "undefined") return;
|
|
102
|
+
|
|
103
|
+
// Skin buttons
|
|
104
|
+
document.querySelectorAll("#zer0SkinButtons [data-skin]").forEach(function (btn) {
|
|
105
|
+
btn.addEventListener("click", function () {
|
|
106
|
+
var skin = this.getAttribute("data-skin");
|
|
107
|
+
zer0Bg.setSkin(skin);
|
|
108
|
+
// Update active state
|
|
109
|
+
document.querySelectorAll("#zer0SkinButtons .btn").forEach(function (b) { b.classList.remove("active"); });
|
|
110
|
+
this.classList.add("active");
|
|
111
|
+
});
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
// Background toggle
|
|
115
|
+
var toggle = document.getElementById("zer0BgToggle");
|
|
116
|
+
toggle.checked = document.documentElement.getAttribute("data-zer0-bg") !== "off";
|
|
117
|
+
toggle.addEventListener("change", function () { zer0Bg.toggle(this.checked); });
|
|
118
|
+
|
|
119
|
+
// Opacity sliders
|
|
120
|
+
function bindSlider(id, layer) {
|
|
121
|
+
var slider = document.getElementById(id);
|
|
122
|
+
var valSpan = document.getElementById(id + "Val");
|
|
123
|
+
slider.addEventListener("input", function () {
|
|
124
|
+
zer0Bg.setOpacity(layer, this.value);
|
|
125
|
+
valSpan.textContent = this.value;
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
bindSlider("zer0GradientOpacity", "gradient");
|
|
129
|
+
bindSlider("zer0TextureOpacity", "texture");
|
|
130
|
+
bindSlider("zer0PatternOpacity", "pattern");
|
|
131
|
+
|
|
132
|
+
// Reset
|
|
133
|
+
document.getElementById("zer0BgReset").addEventListener("click", function () {
|
|
134
|
+
zer0Bg.setSkin("{{ current_skin }}");
|
|
135
|
+
zer0Bg.toggle(true);
|
|
136
|
+
zer0Bg.setOpacity("gradient", 0.6);
|
|
137
|
+
zer0Bg.setOpacity("texture", 0.04);
|
|
138
|
+
zer0Bg.setOpacity("pattern", 0.08);
|
|
139
|
+
document.getElementById("zer0GradientOpacity").value = 0.6;
|
|
140
|
+
document.getElementById("zer0TextureOpacity").value = 0.04;
|
|
141
|
+
document.getElementById("zer0PatternOpacity").value = 0.08;
|
|
142
|
+
document.getElementById("zer0GradientOpacityVal").textContent = "0.6";
|
|
143
|
+
document.getElementById("zer0TextureOpacityVal").textContent = "0.04";
|
|
144
|
+
document.getElementById("zer0PatternOpacityVal").textContent = "0.08";
|
|
145
|
+
toggle.checked = true;
|
|
146
|
+
// Re-highlight correct skin button
|
|
147
|
+
document.querySelectorAll("#zer0SkinButtons .btn").forEach(function (b) { b.classList.remove("active"); });
|
|
148
|
+
var active = document.querySelector('#zer0SkinButtons [data-skin="{{ current_skin }}"]');
|
|
149
|
+
if (active) active.classList.add("active");
|
|
150
|
+
});
|
|
151
|
+
|
|
152
|
+
// Sync on external skin change events
|
|
153
|
+
document.addEventListener("zer0:skin-change", function (e) {
|
|
154
|
+
document.querySelectorAll("#zer0SkinButtons .btn").forEach(function (b) { b.classList.remove("active"); });
|
|
155
|
+
var active = document.querySelector('#zer0SkinButtons [data-skin="' + e.detail.skin + '"]');
|
|
156
|
+
if (active) active.classList.add("active");
|
|
157
|
+
});
|
|
158
|
+
});
|
|
159
|
+
</script>
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
===================================================================
|
|
3
|
+
BACKGROUND SETTINGS — fffuel-style background controls (tab content)
|
|
4
|
+
===================================================================
|
|
5
|
+
|
|
6
|
+
File: background-settings.html
|
|
7
|
+
Path: _includes/components/background-settings.html
|
|
8
|
+
Purpose: Background skin selector and opacity controls, rendered
|
|
9
|
+
inside the Settings offcanvas Background tab.
|
|
10
|
+
|
|
11
|
+
Dependencies:
|
|
12
|
+
- assets/js/background-customizer.js (zer0Bg API)
|
|
13
|
+
- _sass/theme/_backgrounds.scss (CSS custom properties)
|
|
14
|
+
- Bootstrap 5 form components
|
|
15
|
+
===================================================================
|
|
16
|
+
-->
|
|
17
|
+
|
|
18
|
+
{% assign skins = "air,aqua,contrast,dark,dirt,neon,mint,plum,sunrise" | split: "," %}
|
|
19
|
+
{% assign current_skin = site.theme_skin | default: "dark" %}
|
|
20
|
+
|
|
21
|
+
<!-- Skin selector -->
|
|
22
|
+
<div class="mb-4">
|
|
23
|
+
<h6 class="text-body-secondary small text-uppercase fw-semibold mb-2">
|
|
24
|
+
<i class="bi bi-palette2 me-1"></i>Theme Skin
|
|
25
|
+
</h6>
|
|
26
|
+
<div class="d-flex flex-wrap gap-2" id="zer0SkinButtons">
|
|
27
|
+
{% for skin in skins %}
|
|
28
|
+
<button class="btn btn-sm btn-outline-primary{% if skin == current_skin %} active{% endif %}"
|
|
29
|
+
data-skin="{{ skin }}"
|
|
30
|
+
type="button">
|
|
31
|
+
{{ skin | capitalize }}
|
|
32
|
+
</button>
|
|
33
|
+
{% endfor %}
|
|
34
|
+
</div>
|
|
35
|
+
</div>
|
|
36
|
+
|
|
37
|
+
<!-- Background toggle -->
|
|
38
|
+
<div class="mb-4">
|
|
39
|
+
<h6 class="text-body-secondary small text-uppercase fw-semibold mb-2">
|
|
40
|
+
<i class="bi bi-image me-1"></i>SVG Backgrounds
|
|
41
|
+
</h6>
|
|
42
|
+
<div class="d-flex align-items-center justify-content-between p-3 bg-body-tertiary rounded">
|
|
43
|
+
<label class="form-check-label" for="zer0BgToggle">Enable SVG backgrounds</label>
|
|
44
|
+
<div class="form-check form-switch mb-0">
|
|
45
|
+
<input class="form-check-input" type="checkbox" id="zer0BgToggle" checked>
|
|
46
|
+
</div>
|
|
47
|
+
</div>
|
|
48
|
+
</div>
|
|
49
|
+
|
|
50
|
+
<!-- Opacity sliders -->
|
|
51
|
+
<div class="mb-4">
|
|
52
|
+
<h6 class="text-body-secondary small text-uppercase fw-semibold mb-2">
|
|
53
|
+
<i class="bi bi-sliders2 me-1"></i>Layer Opacity
|
|
54
|
+
</h6>
|
|
55
|
+
|
|
56
|
+
<div class="mb-3">
|
|
57
|
+
<label class="form-label small" for="zer0GradientOpacity">Gradient opacity</label>
|
|
58
|
+
<input type="range" class="form-range" id="zer0GradientOpacity"
|
|
59
|
+
min="0" max="1" step="0.05" value="0.6">
|
|
60
|
+
<small class="text-body-secondary"><span id="zer0GradientOpacityVal">0.6</span></small>
|
|
61
|
+
</div>
|
|
62
|
+
|
|
63
|
+
<div class="mb-3">
|
|
64
|
+
<label class="form-label small" for="zer0TextureOpacity">Texture opacity</label>
|
|
65
|
+
<input type="range" class="form-range" id="zer0TextureOpacity"
|
|
66
|
+
min="0" max="0.2" step="0.005" value="0.04">
|
|
67
|
+
<small class="text-body-secondary"><span id="zer0TextureOpacityVal">0.04</span></small>
|
|
68
|
+
</div>
|
|
69
|
+
|
|
70
|
+
<div class="mb-3">
|
|
71
|
+
<label class="form-label small" for="zer0PatternOpacity">Pattern opacity</label>
|
|
72
|
+
<input type="range" class="form-range" id="zer0PatternOpacity"
|
|
73
|
+
min="0" max="0.3" step="0.01" value="0.08">
|
|
74
|
+
<small class="text-body-secondary"><span id="zer0PatternOpacityVal">0.08</span></small>
|
|
75
|
+
</div>
|
|
76
|
+
</div>
|
|
77
|
+
|
|
78
|
+
<!-- Reset -->
|
|
79
|
+
<div>
|
|
80
|
+
<button class="btn btn-sm btn-outline-danger" id="zer0BgReset" type="button">
|
|
81
|
+
<i class="bi bi-arrow-counterclockwise me-1"></i>Reset to defaults
|
|
82
|
+
</button>
|
|
83
|
+
</div>
|
|
84
|
+
|
|
85
|
+
<!-- Customizer interaction logic -->
|
|
86
|
+
<script>
|
|
87
|
+
document.addEventListener("DOMContentLoaded", function () {
|
|
88
|
+
if (typeof zer0Bg === "undefined") return;
|
|
89
|
+
|
|
90
|
+
// Skin buttons
|
|
91
|
+
document.querySelectorAll("#zer0SkinButtons [data-skin]").forEach(function (btn) {
|
|
92
|
+
btn.addEventListener("click", function () {
|
|
93
|
+
var skin = this.getAttribute("data-skin");
|
|
94
|
+
zer0Bg.setSkin(skin);
|
|
95
|
+
document.querySelectorAll("#zer0SkinButtons .btn").forEach(function (b) { b.classList.remove("active"); });
|
|
96
|
+
this.classList.add("active");
|
|
97
|
+
});
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
// Background toggle
|
|
101
|
+
var toggle = document.getElementById("zer0BgToggle");
|
|
102
|
+
toggle.checked = document.documentElement.getAttribute("data-zer0-bg") !== "off";
|
|
103
|
+
toggle.addEventListener("change", function () { zer0Bg.toggle(this.checked); });
|
|
104
|
+
|
|
105
|
+
// Opacity sliders
|
|
106
|
+
function bindSlider(id, layer) {
|
|
107
|
+
var slider = document.getElementById(id);
|
|
108
|
+
var valSpan = document.getElementById(id + "Val");
|
|
109
|
+
slider.addEventListener("input", function () {
|
|
110
|
+
zer0Bg.setOpacity(layer, this.value);
|
|
111
|
+
valSpan.textContent = this.value;
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
bindSlider("zer0GradientOpacity", "gradient");
|
|
115
|
+
bindSlider("zer0TextureOpacity", "texture");
|
|
116
|
+
bindSlider("zer0PatternOpacity", "pattern");
|
|
117
|
+
|
|
118
|
+
// Reset
|
|
119
|
+
document.getElementById("zer0BgReset").addEventListener("click", function () {
|
|
120
|
+
zer0Bg.setSkin("{{ current_skin }}");
|
|
121
|
+
zer0Bg.toggle(true);
|
|
122
|
+
zer0Bg.setOpacity("gradient", 0.6);
|
|
123
|
+
zer0Bg.setOpacity("texture", 0.04);
|
|
124
|
+
zer0Bg.setOpacity("pattern", 0.08);
|
|
125
|
+
document.getElementById("zer0GradientOpacity").value = 0.6;
|
|
126
|
+
document.getElementById("zer0TextureOpacity").value = 0.04;
|
|
127
|
+
document.getElementById("zer0PatternOpacity").value = 0.08;
|
|
128
|
+
document.getElementById("zer0GradientOpacityVal").textContent = "0.6";
|
|
129
|
+
document.getElementById("zer0TextureOpacityVal").textContent = "0.04";
|
|
130
|
+
document.getElementById("zer0PatternOpacityVal").textContent = "0.08";
|
|
131
|
+
toggle.checked = true;
|
|
132
|
+
document.querySelectorAll("#zer0SkinButtons .btn").forEach(function (b) { b.classList.remove("active"); });
|
|
133
|
+
var active = document.querySelector('#zer0SkinButtons [data-skin="{{ current_skin }}"]');
|
|
134
|
+
if (active) active.classList.add("active");
|
|
135
|
+
});
|
|
136
|
+
});
|
|
137
|
+
</script>
|