ultimate-jekyll-manager 1.0.8 → 1.0.10
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.
- package/CHANGELOG.md +12 -0
- package/dist/assets/js/pages/admin/dashboard/index.js +2 -3
- package/dist/build.js +5 -4
- package/dist/defaults/dist/pages/test/libraries/firestore.html +201 -0
- package/dist/defaults/src/_config.yml +1 -1
- package/dist/defaults/src/assets/css/main.scss +6 -6
- package/dist/gulp/tasks/webpack.js +1 -1
- package/package.json +2 -2
- package/dist/assets/css/bundles/umbra.scss +0 -5
- package/dist/assets/themes/umbra/README.md +0 -75
- package/dist/assets/themes/umbra/_config.scss +0 -187
- package/dist/assets/themes/umbra/_theme.js +0 -36
- package/dist/assets/themes/umbra/_theme.scss +0 -34
- package/dist/assets/themes/umbra/css/base/_animations.scss +0 -27
- package/dist/assets/themes/umbra/css/base/_backgrounds.scss +0 -191
- package/dist/assets/themes/umbra/css/base/_borders.scss +0 -65
- package/dist/assets/themes/umbra/css/base/_root.scss +0 -68
- package/dist/assets/themes/umbra/css/base/_typography.scss +0 -148
- package/dist/assets/themes/umbra/css/base/_utilities.scss +0 -15
- package/dist/assets/themes/umbra/css/components/_accordion.scss +0 -44
- package/dist/assets/themes/umbra/css/components/_badges.scss +0 -25
- package/dist/assets/themes/umbra/css/components/_buttons.scss +0 -264
- package/dist/assets/themes/umbra/css/components/_cards.scss +0 -47
- package/dist/assets/themes/umbra/css/components/_carousel.scss +0 -41
- package/dist/assets/themes/umbra/css/components/_forms.scss +0 -150
- package/dist/assets/themes/umbra/css/components/_infinite-scroll.scss +0 -140
- package/dist/assets/themes/umbra/css/components/_text.scss +0 -53
- package/dist/assets/themes/umbra/css/layout/_backend.scss +0 -59
- package/dist/assets/themes/umbra/css/layout/_blog.scss +0 -42
- package/dist/assets/themes/umbra/css/layout/_general.scss +0 -142
- package/dist/assets/themes/umbra/css/layout/_navigation.scss +0 -602
- package/dist/assets/themes/umbra/css/layout/_team.scss +0 -18
- package/dist/assets/themes/umbra/js/hero-demo-form.js +0 -42
- package/dist/assets/themes/umbra/js/infinite-scroll.js +0 -139
- package/dist/assets/themes/umbra/js/initialize-tooltips.js +0 -20
- package/dist/assets/themes/umbra/js/navbar-scroll.js +0 -65
- package/dist/defaults/dist/_includes/themes/umbra/admin/sections/sidebar.html +0 -3
- package/dist/defaults/dist/_includes/themes/umbra/admin/sections/topbar.html +0 -3
- package/dist/defaults/dist/_includes/themes/umbra/backend/sections/sidebar.html +0 -347
- package/dist/defaults/dist/_includes/themes/umbra/backend/sections/topbar.html +0 -184
- package/dist/defaults/dist/_includes/themes/umbra/frontend/components/testimonial-scroll.html +0 -84
- package/dist/defaults/dist/_includes/themes/umbra/frontend/sections/footer.html +0 -158
- package/dist/defaults/dist/_includes/themes/umbra/frontend/sections/nav.html +0 -276
- package/dist/defaults/dist/_includes/themes/umbra/global/sections/account.html +0 -72
- package/dist/defaults/dist/_layouts/themes/umbra/admin/core/minimal-viewport-locked.html +0 -31
- package/dist/defaults/dist/_layouts/themes/umbra/admin/core/minimal.html +0 -32
- package/dist/defaults/dist/_layouts/themes/umbra/backend/core/base.html +0 -55
- package/dist/defaults/dist/_layouts/themes/umbra/backend/core/minimal-viewport-locked.html +0 -149
- package/dist/defaults/dist/_layouts/themes/umbra/backend/core/minimal.html +0 -149
- package/dist/defaults/dist/_layouts/themes/umbra/backend/pages/dashboard/index.html +0 -247
- package/dist/defaults/dist/_layouts/themes/umbra/frontend/core/base.html +0 -32
- package/dist/defaults/dist/_layouts/themes/umbra/frontend/core/cover.html +0 -41
- package/dist/defaults/dist/_layouts/themes/umbra/frontend/core/minimal.html +0 -42
- package/dist/defaults/dist/_layouts/themes/umbra/frontend/pages/account/index.html +0 -152
- package/dist/defaults/dist/_layouts/themes/umbra/frontend/pages/auth/signin.html +0 -85
- package/dist/defaults/dist/_layouts/themes/umbra/frontend/pages/auth/signup.html +0 -97
- package/dist/defaults/dist/_layouts/themes/umbra/frontend/pages/index.html +0 -188
- package/dist/defaults/dist/_layouts/themes/umbra/frontend/pages/pricing.html +0 -129
- package/test.css +0 -18
package/CHANGELOG.md
CHANGED
|
@@ -15,6 +15,18 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
|
|
15
15
|
- `Security` in case of vulnerabilities.
|
|
16
16
|
|
|
17
17
|
---
|
|
18
|
+
## [1.0.10] - 2026-03-24
|
|
19
|
+
### Fixed
|
|
20
|
+
- `getUJMConfig()` now throws descriptive errors when config file is missing, empty, or malformed instead of crashing silently
|
|
21
|
+
- Admin dashboard subscription queries now filter by `subscription.status == 'active'` instead of expiry timestamp
|
|
22
|
+
|
|
23
|
+
### Changed
|
|
24
|
+
- Webpack watch path for web-manager changed from `src/` to `dist/`
|
|
25
|
+
|
|
26
|
+
## [1.0.9] - 2026-03-20
|
|
27
|
+
### Changed
|
|
28
|
+
- `authorizedFetch` no longer throws when no user is logged in; logs a warning and proceeds without the Authorization header
|
|
29
|
+
|
|
18
30
|
## [1.0.7] - 2026-03-20
|
|
19
31
|
### Changed
|
|
20
32
|
- Upgrade `web-manager` from ^4.1.29 to ^4.1.30
|
|
@@ -77,7 +77,7 @@ async function loadStatCards() {
|
|
|
77
77
|
const [totalUsers, newUsers, activeSubscriptions, pushSubscribers] = await Promise.allSettled([
|
|
78
78
|
getCountFromServer(collection(db, 'users')),
|
|
79
79
|
getCountFromServer(query(collection(db, 'users'), where('metadata.created.timestampUNIX', '>=', thirtyDaysAgo))),
|
|
80
|
-
getCountFromServer(query(collection(db, 'users'), where('subscription.
|
|
80
|
+
getCountFromServer(query(collection(db, 'users'), where('subscription.status', '==', 'active'), where('subscription.product.id', '!=', 'basic'))),
|
|
81
81
|
getCountFromServer(collection(db, 'notifications')),
|
|
82
82
|
]);
|
|
83
83
|
|
|
@@ -92,10 +92,9 @@ async function loadStatCards() {
|
|
|
92
92
|
// ============================================
|
|
93
93
|
async function loadSubscriberData() {
|
|
94
94
|
const firestore = webManager.firestore();
|
|
95
|
-
const now = Math.floor(Date.now() / 1000);
|
|
96
95
|
|
|
97
96
|
const snapshot = await firestore.collection('users')
|
|
98
|
-
.where('subscription.
|
|
97
|
+
.where('subscription.status', '==', 'active')
|
|
99
98
|
.get();
|
|
100
99
|
|
|
101
100
|
// Group by plan
|
package/dist/build.js
CHANGED
|
@@ -143,15 +143,16 @@ Manager.prototype.getPackage = Manager.getPackage;
|
|
|
143
143
|
Manager.getUJMConfig = function () {
|
|
144
144
|
const configPath = path.join(process.cwd(), 'config', 'ultimate-jekyll-manager.json');
|
|
145
145
|
if (!jetpack.exists(configPath)) {
|
|
146
|
-
|
|
146
|
+
throw new Error(`Config file not found: ${configPath}`);
|
|
147
147
|
}
|
|
148
148
|
const content = jetpack.read(configPath);
|
|
149
|
-
if (!content)
|
|
149
|
+
if (!content) {
|
|
150
|
+
throw new Error(`Config file is empty: ${configPath}`);
|
|
151
|
+
}
|
|
150
152
|
try {
|
|
151
153
|
return JSON5.parse(content);
|
|
152
154
|
} catch (e) {
|
|
153
|
-
|
|
154
|
-
return {};
|
|
155
|
+
throw new Error(`Failed to parse ${configPath}: ${e.message}`);
|
|
155
156
|
}
|
|
156
157
|
}
|
|
157
158
|
Manager.prototype.getUJMConfig = Manager.getUJMConfig;
|
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
---
|
|
2
|
+
layout: none
|
|
3
|
+
permalink: /test/libraries/firestore
|
|
4
|
+
sitemap:
|
|
5
|
+
include: false
|
|
6
|
+
---
|
|
7
|
+
<!DOCTYPE html>
|
|
8
|
+
<html>
|
|
9
|
+
<head>
|
|
10
|
+
<meta charset="utf-8">
|
|
11
|
+
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
12
|
+
<title>Firestore Version Test</title>
|
|
13
|
+
<style>
|
|
14
|
+
* { margin: 0; padding: 0; box-sizing: border-box; }
|
|
15
|
+
body { font-family: monospace; padding: 16px; font-size: 13px; background: #111; color: #eee; }
|
|
16
|
+
h1 { font-size: 18px; margin-bottom: 8px; }
|
|
17
|
+
h2 { font-size: 14px; margin-bottom: 4px; color: #aaa; }
|
|
18
|
+
.test { margin-bottom: 12px; border: 1px solid #333; padding: 8px; border-radius: 4px; }
|
|
19
|
+
.test.success { border-color: #0a0; }
|
|
20
|
+
.test.fail { border-color: #a00; }
|
|
21
|
+
pre { white-space: pre-wrap; font-size: 11px; line-height: 1.3; max-height: 150px; overflow-y: auto; }
|
|
22
|
+
#ua { font-size: 11px; color: #666; margin-bottom: 12px; word-break: break-all; }
|
|
23
|
+
#status { font-size: 14px; margin-bottom: 12px; color: #ff0; }
|
|
24
|
+
.summary { margin-bottom: 16px; padding: 12px; border: 2px solid #555; border-radius: 4px; }
|
|
25
|
+
</style>
|
|
26
|
+
</head>
|
|
27
|
+
<body>
|
|
28
|
+
<h1>Firestore Version + Transport Test</h1>
|
|
29
|
+
<div id="ua"></div>
|
|
30
|
+
<div id="status">Loading...</div>
|
|
31
|
+
<div id="sw-status" style="color: #f80; margin-bottom: 12px;"></div>
|
|
32
|
+
<div class="summary" id="summary" style="display:none"></div>
|
|
33
|
+
|
|
34
|
+
<div class="test" id="rest"><h2>Baseline: REST API (v12.11.0 auth only)</h2><pre id="rest-log"></pre></div>
|
|
35
|
+
<div class="test" id="v11"><h2>Firebase 11.0.0 - getFirestore</h2><pre id="v11-log"></pre></div>
|
|
36
|
+
<div class="test" id="v11lp"><h2>Firebase 11.0.0 - initializeFirestore + forceLongPolling</h2><pre id="v11lp-log"></pre></div>
|
|
37
|
+
<div class="test" id="v12_0"><h2>Firebase 12.0.0 - getFirestore</h2><pre id="v12_0-log"></pre></div>
|
|
38
|
+
<div class="test" id="v12_0lp"><h2>Firebase 12.0.0 - initializeFirestore + forceLongPolling</h2><pre id="v12_0lp-log"></pre></div>
|
|
39
|
+
<div class="test" id="v12_11"><h2>Firebase 12.11.0 (current) - getFirestore</h2><pre id="v12_11-log"></pre></div>
|
|
40
|
+
<div class="test" id="v12_11lp"><h2>Firebase 12.11.0 (current) - initializeFirestore + forceLongPolling</h2><pre id="v12_11lp-log"></pre></div>
|
|
41
|
+
<div class="test" id="v10"><h2>Firebase 10.14.0 - getFirestore</h2><pre id="v10-log"></pre></div>
|
|
42
|
+
<div class="test" id="v10lp"><h2>Firebase 10.14.0 - initializeFirestore + forceLongPolling</h2><pre id="v10lp-log"></pre></div>
|
|
43
|
+
|
|
44
|
+
<script type="module">
|
|
45
|
+
// Use 12.11.0 for auth only (default app)
|
|
46
|
+
import { initializeApp } from 'https://www.gstatic.com/firebasejs/12.11.0/firebase-app.js';
|
|
47
|
+
import { getAuth, onAuthStateChanged } from 'https://www.gstatic.com/firebasejs/12.11.0/firebase-auth.js';
|
|
48
|
+
|
|
49
|
+
const config = {{ page.resolved.web_manager.firebase.app.config | jsonify }};
|
|
50
|
+
|
|
51
|
+
document.getElementById('ua').textContent = navigator.userAgent;
|
|
52
|
+
|
|
53
|
+
// Unregister all service workers first
|
|
54
|
+
if ('serviceWorker' in navigator) {
|
|
55
|
+
const regs = await navigator.serviceWorker.getRegistrations();
|
|
56
|
+
console.log(`[Setup] Found ${regs.length} service worker(s)`);
|
|
57
|
+
for (const reg of regs) {
|
|
58
|
+
const result = await reg.unregister();
|
|
59
|
+
console.log(`[Setup] Unregistered service worker: ${reg.scope} (success: ${result})`);
|
|
60
|
+
}
|
|
61
|
+
const swMsg = regs.length > 0
|
|
62
|
+
? `Unregistered ${regs.length} service worker(s)`
|
|
63
|
+
: 'No service workers found';
|
|
64
|
+
document.getElementById('sw-status').textContent = swMsg;
|
|
65
|
+
document.getElementById('status').textContent = swMsg + '. Running tests...';
|
|
66
|
+
} else {
|
|
67
|
+
console.log('[Setup] Service workers not supported');
|
|
68
|
+
document.getElementById('sw-status').textContent = 'Service workers not supported';
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
function makeLogger(id) {
|
|
72
|
+
const $log = document.getElementById(id + '-log');
|
|
73
|
+
const $box = document.getElementById(id);
|
|
74
|
+
return {
|
|
75
|
+
log: (msg) => {
|
|
76
|
+
console.log(`[${id}]`, msg);
|
|
77
|
+
$log.textContent += msg + '\n';
|
|
78
|
+
$log.scrollTop = $log.scrollHeight;
|
|
79
|
+
},
|
|
80
|
+
pass: () => { $box.classList.add('success'); return 'PASS'; },
|
|
81
|
+
fail: () => { $box.classList.add('fail'); return 'FAIL'; },
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
const results = {};
|
|
86
|
+
|
|
87
|
+
// REST baseline
|
|
88
|
+
async function testRest(uid, token) {
|
|
89
|
+
const t = makeLogger('rest');
|
|
90
|
+
try {
|
|
91
|
+
const url = `https://firestore.googleapis.com/v1/projects/${config.projectId}/databases/(default)/documents/users/${uid}`;
|
|
92
|
+
t.log('Fetching via REST...');
|
|
93
|
+
const res = await fetch(url, { headers: { 'Authorization': `Bearer ${token}` } });
|
|
94
|
+
t.log(`Status: ${res.status}`);
|
|
95
|
+
if (res.ok) {
|
|
96
|
+
const data = await res.json();
|
|
97
|
+
t.log('SUCCESS');
|
|
98
|
+
results['REST'] = t.pass();
|
|
99
|
+
} else {
|
|
100
|
+
const text = await res.text();
|
|
101
|
+
t.log('ERROR: ' + text.substring(0, 150));
|
|
102
|
+
results['REST'] = t.fail();
|
|
103
|
+
}
|
|
104
|
+
} catch (e) { t.log('ERROR: ' + e.message); results['REST'] = t.fail(); }
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
// Generic version test using dynamic import
|
|
108
|
+
async function testVersion(id, version, uid, useLP) {
|
|
109
|
+
const t = makeLogger(id);
|
|
110
|
+
try {
|
|
111
|
+
const label = useLP ? 'initializeFirestore+forceLongPolling' : 'getFirestore';
|
|
112
|
+
t.log(`Loading Firebase ${version}...`);
|
|
113
|
+
|
|
114
|
+
const appMod = await import(`https://www.gstatic.com/firebasejs/${version}/firebase-app.js`);
|
|
115
|
+
const fsMod = await import(`https://www.gstatic.com/firebasejs/${version}/firebase-firestore.js`);
|
|
116
|
+
|
|
117
|
+
const appName = id;
|
|
118
|
+
let app;
|
|
119
|
+
try {
|
|
120
|
+
app = appMod.initializeApp(config, appName);
|
|
121
|
+
} catch (e) {
|
|
122
|
+
app = appMod.getApp(appName);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
let db;
|
|
126
|
+
if (useLP) {
|
|
127
|
+
t.log(`initializeFirestore + experimentalForceLongPolling...`);
|
|
128
|
+
db = fsMod.initializeFirestore(app, { experimentalForceLongPolling: true });
|
|
129
|
+
} else {
|
|
130
|
+
t.log(`getFirestore...`);
|
|
131
|
+
db = fsMod.getFirestore(app);
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
t.log(`Fetching users/${uid} (10s timeout)...`);
|
|
135
|
+
|
|
136
|
+
// Race against a timeout
|
|
137
|
+
const fetchPromise = fsMod.getDoc(fsMod.doc(db, 'users', uid));
|
|
138
|
+
const timeoutPromise = new Promise((_, reject) =>
|
|
139
|
+
setTimeout(() => reject(new Error('TIMEOUT after 10s')), 10000)
|
|
140
|
+
);
|
|
141
|
+
|
|
142
|
+
const snap = await Promise.race([fetchPromise, timeoutPromise]);
|
|
143
|
+
|
|
144
|
+
if (snap.exists()) {
|
|
145
|
+
t.log('SUCCESS: ' + JSON.stringify(snap.data()).substring(0, 100));
|
|
146
|
+
results[id] = t.pass();
|
|
147
|
+
} else {
|
|
148
|
+
t.log('Doc not found');
|
|
149
|
+
results[id] = t.fail();
|
|
150
|
+
}
|
|
151
|
+
} catch (e) {
|
|
152
|
+
const code = e.code || '';
|
|
153
|
+
if (code === 'permission-denied') {
|
|
154
|
+
t.log('TRANSPORT OK (permission-denied = network works, just no auth)');
|
|
155
|
+
results[id] = t.pass();
|
|
156
|
+
} else {
|
|
157
|
+
t.log(`ERROR: ${code} ${e.message}`);
|
|
158
|
+
results[id] = t.fail();
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
// Main
|
|
164
|
+
const defaultApp = initializeApp(config);
|
|
165
|
+
const auth = getAuth(defaultApp);
|
|
166
|
+
|
|
167
|
+
onAuthStateChanged(auth, async (user) => {
|
|
168
|
+
if (!user) {
|
|
169
|
+
document.getElementById('status').textContent = 'Not signed in. Sign in at /dashboard first.';
|
|
170
|
+
return;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
const uid = user.uid;
|
|
174
|
+
const token = await user.getIdToken();
|
|
175
|
+
document.getElementById('status').textContent = `Signed in: ${uid}. Running tests...`;
|
|
176
|
+
|
|
177
|
+
// Run REST first
|
|
178
|
+
await testRest(uid, token);
|
|
179
|
+
|
|
180
|
+
// Run version tests (sequential to avoid interference)
|
|
181
|
+
await testVersion('v10', '10.14.0', uid, false);
|
|
182
|
+
await testVersion('v10lp', '10.14.0', uid, true);
|
|
183
|
+
await testVersion('v11', '11.0.0', uid, false);
|
|
184
|
+
await testVersion('v11lp', '11.0.0', uid, true);
|
|
185
|
+
await testVersion('v12_0', '12.0.0', uid, false);
|
|
186
|
+
await testVersion('v12_0lp', '12.0.0', uid, true);
|
|
187
|
+
await testVersion('v12_11', '12.11.0', uid, false);
|
|
188
|
+
await testVersion('v12_11lp', '12.11.0', uid, true);
|
|
189
|
+
|
|
190
|
+
// Show summary
|
|
191
|
+
document.getElementById('status').textContent = 'All tests complete.';
|
|
192
|
+
const $summary = document.getElementById('summary');
|
|
193
|
+
$summary.style.display = 'block';
|
|
194
|
+
$summary.innerHTML = '<h2 style="margin-bottom:8px">Results Summary</h2>' +
|
|
195
|
+
Object.entries(results).map(([k, v]) =>
|
|
196
|
+
`<div style="color:${v === 'PASS' ? '#0f0' : '#f00'}">${v}: ${k}</div>`
|
|
197
|
+
).join('');
|
|
198
|
+
});
|
|
199
|
+
</script>
|
|
200
|
+
</body>
|
|
201
|
+
</html>
|
|
@@ -1,21 +1,21 @@
|
|
|
1
1
|
// ============================================
|
|
2
2
|
// Theme Configuration
|
|
3
3
|
// ============================================
|
|
4
|
-
// Customize theme variables here
|
|
5
|
-
// See: ultimate-jekyll-manager/src/assets/themes/
|
|
4
|
+
// Customize Classy theme variables here
|
|
5
|
+
// See: ultimate-jekyll-manager/src/assets/themes/classy/_config.scss for all available variables
|
|
6
6
|
|
|
7
7
|
@use 'ultimate-jekyll-manager' as * with (
|
|
8
8
|
// ============================================
|
|
9
9
|
// Brand Colors
|
|
10
10
|
// ============================================
|
|
11
|
-
|
|
12
|
-
// $secondary: #
|
|
11
|
+
$primary: #5B47FB,
|
|
12
|
+
// $secondary: #6C757D,
|
|
13
13
|
|
|
14
14
|
// ============================================
|
|
15
15
|
// Backgrounds
|
|
16
16
|
// ============================================
|
|
17
|
-
// $
|
|
18
|
-
// $
|
|
17
|
+
// $classy-bg-light: #FFFFFF,
|
|
18
|
+
// $classy-bg-dark: #212529,
|
|
19
19
|
|
|
20
20
|
// ============================================
|
|
21
21
|
// Typography (uncomment to customize)
|
|
@@ -62,7 +62,7 @@ const watchInput = [
|
|
|
62
62
|
`${rootPathPackage}/dist/service-worker.js`,
|
|
63
63
|
|
|
64
64
|
// So we can watch for changes while we're developing web-manager
|
|
65
|
-
`${rootPathPackage}/../web-manager/
|
|
65
|
+
`${rootPathPackage}/../web-manager/dist`,
|
|
66
66
|
];
|
|
67
67
|
|
|
68
68
|
// Files to copy directly without webpack processing
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ultimate-jekyll-manager",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.10",
|
|
4
4
|
"description": "Ultimate Jekyll dependency manager",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"exports": {
|
|
@@ -104,7 +104,7 @@
|
|
|
104
104
|
"sass": "^1.98.0",
|
|
105
105
|
"spellchecker": "^3.7.1",
|
|
106
106
|
"through2": "^4.0.2",
|
|
107
|
-
"web-manager": "^4.1.
|
|
107
|
+
"web-manager": "^4.1.31",
|
|
108
108
|
"webpack": "^5.105.4",
|
|
109
109
|
"wonderful-fetch": "^2.0.4",
|
|
110
110
|
"wonderful-version": "^1.3.2",
|
|
@@ -1,75 +0,0 @@
|
|
|
1
|
-
# Umbra Theme Customization Guide
|
|
2
|
-
|
|
3
|
-
## How to Customize in Your Consuming Project
|
|
4
|
-
|
|
5
|
-
The Umbra theme is designed to be fully customizable. All theme variables use `!default` which means you can override them BEFORE importing the theme.
|
|
6
|
-
|
|
7
|
-
### Example: Customizing Colors in Your Project
|
|
8
|
-
|
|
9
|
-
In your consuming project's `src/assets/css/main.scss`:
|
|
10
|
-
|
|
11
|
-
```scss
|
|
12
|
-
// 1. Override Umbra theme variables BEFORE importing the theme
|
|
13
|
-
$primary: #FF0000; // Change primary color to red
|
|
14
|
-
$umbra-bg-light: #F5F5F5; // Change light mode background
|
|
15
|
-
$umbra-bg-dark: #1A1A1A; // Change dark mode background
|
|
16
|
-
$font-family-sans-serif: 'Inter', sans-serif; // Change font
|
|
17
|
-
|
|
18
|
-
// 2. Now import the Umbra theme - it will use YOUR values
|
|
19
|
-
@import '~ultimate-jekyll-manager/src/assets/themes/umbra/theme';
|
|
20
|
-
|
|
21
|
-
// 3. Add your custom styles below
|
|
22
|
-
.my-custom-class {
|
|
23
|
-
// Your custom CSS
|
|
24
|
-
}
|
|
25
|
-
```
|
|
26
|
-
|
|
27
|
-
## Available Customizable Variables
|
|
28
|
-
|
|
29
|
-
See `_config.scss` for the full list of variables you can override:
|
|
30
|
-
|
|
31
|
-
### Bootstrap Colors
|
|
32
|
-
- `$primary` - Primary brand color
|
|
33
|
-
- `$secondary` - Secondary color
|
|
34
|
-
- `$success`, `$info`, `$warning`, `$danger` - Utility colors
|
|
35
|
-
- `$light`, `$dark` - Light and dark variants
|
|
36
|
-
|
|
37
|
-
### Background Colors
|
|
38
|
-
- `$umbra-bg-light` - Light mode background
|
|
39
|
-
- `$umbra-bg-dark` - Dark mode background
|
|
40
|
-
|
|
41
|
-
### Typography
|
|
42
|
-
- `$font-family-sans-serif` - Main font family
|
|
43
|
-
- `$headings-font-weight` - Heading font weight
|
|
44
|
-
|
|
45
|
-
### Border Radius
|
|
46
|
-
- `$border-radius` - Default border radius
|
|
47
|
-
- `$border-radius-sm`, `$border-radius-lg` - Size variants
|
|
48
|
-
|
|
49
|
-
### Gradients
|
|
50
|
-
- `$umbra-gradient-primary`, `$umbra-gradient-aurora`, etc.
|
|
51
|
-
|
|
52
|
-
## File Structure
|
|
53
|
-
|
|
54
|
-
```
|
|
55
|
-
umbra/
|
|
56
|
-
├── _config.scss ← All customizable variables with !default
|
|
57
|
-
├── _theme.scss ← Main entry point, imports config then Bootstrap
|
|
58
|
-
├── css/base/
|
|
59
|
-
│ ├── _variables.scss ← Internal non-customizable values
|
|
60
|
-
│ └── _root.scss ← CSS custom property overrides
|
|
61
|
-
└── ...
|
|
62
|
-
```
|
|
63
|
-
|
|
64
|
-
## How It Works
|
|
65
|
-
|
|
66
|
-
1. **`_config.scss`**: Defines all variables with `!default` (can be overridden)
|
|
67
|
-
2. **Your `main.scss`**: Sets custom values BEFORE importing theme
|
|
68
|
-
3. **`_theme.scss`**: Imports config (uses your values or defaults), then Bootstrap
|
|
69
|
-
4. **`_root.scss`**: Converts SCSS variables to CSS custom properties for runtime
|
|
70
|
-
|
|
71
|
-
This ensures:
|
|
72
|
-
- ✅ You can customize anything
|
|
73
|
-
- ✅ Bootstrap gets configured with your colors
|
|
74
|
-
- ✅ CSS custom properties update for light/dark mode
|
|
75
|
-
- ✅ No need to modify theme files
|
|
@@ -1,187 +0,0 @@
|
|
|
1
|
-
// Umbra Theme Configuration
|
|
2
|
-
// ALL customizable variables are defined here with !default
|
|
3
|
-
// Consuming projects can override any of these using @use ... with ()
|
|
4
|
-
|
|
5
|
-
// ============================================
|
|
6
|
-
// Bootstrap Color Overrides
|
|
7
|
-
// ============================================
|
|
8
|
-
$primary: #E2725B !default; // Terracotta
|
|
9
|
-
$secondary: #8B7A75 !default; // Warm Gray
|
|
10
|
-
$success: #2A9D8F !default;
|
|
11
|
-
$info: #E9C46A !default; // Soft Gold
|
|
12
|
-
$warning: #F4A261 !default;
|
|
13
|
-
$danger: #E76F51 !default;
|
|
14
|
-
$light: #FDFBF7 !default; // Warm Cream
|
|
15
|
-
$dark: #1E1A18 !default; // Warm Charcoal
|
|
16
|
-
|
|
17
|
-
// ============================================
|
|
18
|
-
// Typography
|
|
19
|
-
// ============================================
|
|
20
|
-
$font-family-sans-serif: 'Figtree', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif !default;
|
|
21
|
-
$headings-font-weight: 600 !default;
|
|
22
|
-
$umbra-font-mono: monospace !default;
|
|
23
|
-
$umbra-font-accent: 'Figtree', sans-serif !default;
|
|
24
|
-
|
|
25
|
-
// ============================================
|
|
26
|
-
// Border Radius
|
|
27
|
-
// ============================================
|
|
28
|
-
$border-radius: 0.5rem !default;
|
|
29
|
-
$border-radius-sm: 0.375rem !default;
|
|
30
|
-
$border-radius-lg: 0.75rem !default;
|
|
31
|
-
$border-radius-xl: 1rem !default;
|
|
32
|
-
$border-radius-2xl: 1.5rem !default;
|
|
33
|
-
$border-radius-pill: 50rem !default;
|
|
34
|
-
|
|
35
|
-
// Umbra-specific border radius aliases
|
|
36
|
-
$umbra-radius-sm: $border-radius-sm !default;
|
|
37
|
-
$umbra-radius-md: $border-radius !default;
|
|
38
|
-
$umbra-radius-lg: $border-radius-lg !default;
|
|
39
|
-
$umbra-radius-xl: $border-radius-xl !default;
|
|
40
|
-
$umbra-radius-2xl: $border-radius-2xl !default;
|
|
41
|
-
$umbra-radius-full: 9999px !default;
|
|
42
|
-
|
|
43
|
-
// ============================================
|
|
44
|
-
// Background Colors (Light Mode)
|
|
45
|
-
// ============================================
|
|
46
|
-
$umbra-bg-light: #FDFBF7 !default; // Main body background (warm cream)
|
|
47
|
-
$umbra-bg-light-secondary: #F5F2EC !default; // Secondary backgrounds
|
|
48
|
-
$umbra-bg-light-tertiary: #EBE5DB !default; // Tertiary backgrounds
|
|
49
|
-
|
|
50
|
-
// ============================================
|
|
51
|
-
// Background Colors (Dark Mode)
|
|
52
|
-
// ============================================
|
|
53
|
-
$umbra-bg-dark: #1E1A18 !default; // Main body background (warm charcoal)
|
|
54
|
-
$umbra-bg-dark-secondary: #2A2421 !default; // Secondary backgrounds
|
|
55
|
-
$umbra-bg-dark-tertiary: #372F2B !default; // Tertiary backgrounds
|
|
56
|
-
|
|
57
|
-
// ============================================
|
|
58
|
-
// Umbra-Specific Colors
|
|
59
|
-
// ============================================
|
|
60
|
-
$umbra-primary: $primary !default;
|
|
61
|
-
$umbra-primary-dark: darken($primary, 10%) !default;
|
|
62
|
-
$umbra-primary-light: lighten($primary, 10%) !default;
|
|
63
|
-
$umbra-primary-soft: mix($primary, white, 10%) !default;
|
|
64
|
-
|
|
65
|
-
$umbra-secondary: $secondary !default;
|
|
66
|
-
$umbra-secondary-dark: darken($secondary, 5%) !default;
|
|
67
|
-
$umbra-secondary-light: lighten($secondary, 5%) !default;
|
|
68
|
-
|
|
69
|
-
$umbra-accent: $info !default;
|
|
70
|
-
$umbra-accent-dark: darken($info, 10%) !default;
|
|
71
|
-
$umbra-accent-light: lighten($info, 10%) !default;
|
|
72
|
-
|
|
73
|
-
$umbra-dark: $dark !default;
|
|
74
|
-
$umbra-dark-900: lighten($dark, 5%) !default;
|
|
75
|
-
$umbra-dark-800: lighten($dark, 10%) !default;
|
|
76
|
-
$umbra-dark-700: lighten($dark, 15%) !default;
|
|
77
|
-
$umbra-dark-600: lighten($dark, 20%) !default;
|
|
78
|
-
|
|
79
|
-
$umbra-gray: #6B7280 !default;
|
|
80
|
-
$umbra-gray-light: #9CA3AF !default;
|
|
81
|
-
$umbra-gray-lighter: #D1D5DB !default;
|
|
82
|
-
$umbra-gray-lightest: #F3F4F6 !default;
|
|
83
|
-
|
|
84
|
-
$umbra-white: #FFFFFF !default;
|
|
85
|
-
$umbra-off-white: #FAFBFC !default;
|
|
86
|
-
$umbra-cream: #FFF9F5 !default;
|
|
87
|
-
|
|
88
|
-
// ============================================
|
|
89
|
-
// Gradient Definitions
|
|
90
|
-
// ============================================
|
|
91
|
-
$umbra-gradient-primary: linear-gradient(135deg, $umbra-primary 0%, #D58C40 100%) !default;
|
|
92
|
-
$umbra-gradient-dark: linear-gradient(135deg, $umbra-dark 0%, $umbra-dark-800 100%) !default;
|
|
93
|
-
$umbra-gradient-light: linear-gradient(135deg, $umbra-white 0%, $umbra-off-white 100%) !default;
|
|
94
|
-
$umbra-gradient-sunset: linear-gradient(135deg, #E2725B 0%, #F4A261 100%) !default;
|
|
95
|
-
$umbra-gradient-aurora: linear-gradient(135deg, #E2725B 0%, #D58C40 50%, #2A9D8F 100%) !default;
|
|
96
|
-
$umbra-gradient-rainbow: linear-gradient(60deg, #E2725B, #D58C40, #F4A261, #E9C46A, #2A9D8F, #8B7A75) !default;
|
|
97
|
-
|
|
98
|
-
// ============================================
|
|
99
|
-
// Typography Scale
|
|
100
|
-
// ============================================
|
|
101
|
-
$umbra-font-size-xs: 0.75rem !default;
|
|
102
|
-
$umbra-font-size-sm: 0.875rem !default;
|
|
103
|
-
$umbra-font-size-base: 1rem !default;
|
|
104
|
-
$umbra-font-size-lg: 1.125rem !default;
|
|
105
|
-
$umbra-font-size-xl: 1.25rem !default;
|
|
106
|
-
$umbra-font-size-2xl: 1.5rem !default;
|
|
107
|
-
$umbra-font-size-3xl: 1.875rem !default;
|
|
108
|
-
$umbra-font-size-4xl: 2.25rem !default;
|
|
109
|
-
$umbra-font-size-5xl: 3rem !default;
|
|
110
|
-
$umbra-font-size-6xl: 3.75rem !default;
|
|
111
|
-
|
|
112
|
-
// ============================================
|
|
113
|
-
// Spacing Scale
|
|
114
|
-
// ============================================
|
|
115
|
-
$umbra-spacing-xs: 0.25rem !default;
|
|
116
|
-
$umbra-spacing-sm: 0.5rem !default;
|
|
117
|
-
$umbra-spacing-md: 1rem !default;
|
|
118
|
-
$umbra-spacing-lg: 1.5rem !default;
|
|
119
|
-
$umbra-spacing-xl: 2rem !default;
|
|
120
|
-
$umbra-spacing-2xl: 3rem !default;
|
|
121
|
-
$umbra-spacing-3xl: 4rem !default;
|
|
122
|
-
$umbra-spacing-4xl: 6rem !default;
|
|
123
|
-
|
|
124
|
-
// ============================================
|
|
125
|
-
// Shadow System
|
|
126
|
-
// ============================================
|
|
127
|
-
$umbra-shadow-xs: 0 1px 2px 0 rgba(0, 0, 0, 0.05) !default;
|
|
128
|
-
$umbra-shadow-sm: 0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.06) !default;
|
|
129
|
-
$umbra-shadow-md: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06) !default;
|
|
130
|
-
$umbra-shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05) !default;
|
|
131
|
-
$umbra-shadow-xl: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04) !default;
|
|
132
|
-
$umbra-shadow-2xl: 0 25px 50px -12px rgba(0, 0, 0, 0.25) !default;
|
|
133
|
-
$umbra-shadow-glow: 0 0 40px rgba(91, 71, 251, 0.15) !default;
|
|
134
|
-
|
|
135
|
-
// ============================================
|
|
136
|
-
// Transition Timing
|
|
137
|
-
// ============================================
|
|
138
|
-
$umbra-transition-fast: all 0.15s cubic-bezier(.2,.3,0,1) !default;
|
|
139
|
-
$umbra-transition-base: all 0.3s cubic-bezier(.2,.3,0,1) !default;
|
|
140
|
-
$umbra-transition-slow: all 0.5s cubic-bezier(.2,.3,0,1) !default;
|
|
141
|
-
$umbra-transition-bounce: all 0.3s cubic-bezier(0.68, -0.55, 0.265, 1.55) !default;
|
|
142
|
-
|
|
143
|
-
// ============================================
|
|
144
|
-
// Responsive Breakpoints
|
|
145
|
-
// ============================================
|
|
146
|
-
// Bootstrap-compatible breakpoint values
|
|
147
|
-
$umbra-breakpoint-sm: 576px !default;
|
|
148
|
-
$umbra-breakpoint-md: 768px !default;
|
|
149
|
-
$umbra-breakpoint-lg: 992px !default;
|
|
150
|
-
$umbra-breakpoint-xl: 1200px !default;
|
|
151
|
-
$umbra-breakpoint-xxl: 1400px !default;
|
|
152
|
-
|
|
153
|
-
// ============================================
|
|
154
|
-
// Component Sizing
|
|
155
|
-
// ============================================
|
|
156
|
-
// Avatar sizes map
|
|
157
|
-
$avatar-sizes: (
|
|
158
|
-
null: 3rem, // default
|
|
159
|
-
2xs: 0.5rem,
|
|
160
|
-
xs: 1.5rem,
|
|
161
|
-
sm: 2rem,
|
|
162
|
-
md: 2.5rem,
|
|
163
|
-
lg: 3.5rem,
|
|
164
|
-
xl: 5rem,
|
|
165
|
-
2xl: 7.5rem,
|
|
166
|
-
3xl: 10rem,
|
|
167
|
-
4xl: 12.5rem,
|
|
168
|
-
5xl: 15rem
|
|
169
|
-
) !default;
|
|
170
|
-
|
|
171
|
-
// Forward Bootstrap with our configuration
|
|
172
|
-
@forward '../bootstrap/scss/bootstrap.scss' with (
|
|
173
|
-
$primary: $primary,
|
|
174
|
-
$secondary: $secondary,
|
|
175
|
-
$success: $success,
|
|
176
|
-
$info: $info,
|
|
177
|
-
$warning: $warning,
|
|
178
|
-
$danger: $danger,
|
|
179
|
-
$light: $light,
|
|
180
|
-
$dark: $dark,
|
|
181
|
-
$font-family-sans-serif: $font-family-sans-serif,
|
|
182
|
-
$headings-font-weight: $headings-font-weight,
|
|
183
|
-
$border-radius: $border-radius,
|
|
184
|
-
$border-radius-sm: $border-radius-sm,
|
|
185
|
-
$border-radius-lg: $border-radius-lg,
|
|
186
|
-
$enable-negative-margins: true
|
|
187
|
-
);
|
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
// Import the theme entry point
|
|
2
|
-
// __main_assets__ is a webpack alias that resolves to UJM's dist/assets
|
|
3
|
-
import bootstrap from '__main_assets__/themes/bootstrap/js/index.umd.js';
|
|
4
|
-
import { ready as domReady } from 'web-manager/modules/dom.js';
|
|
5
|
-
|
|
6
|
-
// Make Bootstrap available globally
|
|
7
|
-
window.bootstrap = bootstrap;
|
|
8
|
-
|
|
9
|
-
// Log that we've MADE IT
|
|
10
|
-
/* @dev-only:start */
|
|
11
|
-
{
|
|
12
|
-
console.log('Umbra theme loaded successfully (assets/themes/umbra/_theme.js)');
|
|
13
|
-
}
|
|
14
|
-
/* @dev-only:end */
|
|
15
|
-
|
|
16
|
-
// Import navbar scroll functionality
|
|
17
|
-
import setupNavbarScroll from './js/navbar-scroll.js';
|
|
18
|
-
// Import infinite scroll functionality (used by logo scroll, testimonials, etc.)
|
|
19
|
-
import { setupInfiniteScroll } from './js/infinite-scroll.js';
|
|
20
|
-
// Import tooltip initialization
|
|
21
|
-
import initializeTooltips from './js/initialize-tooltips.js';
|
|
22
|
-
// Import hero demo form initialization
|
|
23
|
-
import initHeroDemoForm from './js/hero-demo-form.js';
|
|
24
|
-
|
|
25
|
-
// Initialize theme components when DOM is ready
|
|
26
|
-
domReady().then(() => {
|
|
27
|
-
// Umbra Theme Initializations
|
|
28
|
-
setupNavbarScroll();
|
|
29
|
-
setupInfiniteScroll();
|
|
30
|
-
|
|
31
|
-
// Generic Bootstrap initializations
|
|
32
|
-
initializeTooltips();
|
|
33
|
-
|
|
34
|
-
// Initialize hero demo form if present
|
|
35
|
-
initHeroDemoForm();
|
|
36
|
-
});
|
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
// Forward theme configuration (allows consuming project to override)
|
|
2
|
-
@forward 'config';
|
|
3
|
-
@use 'config' as *;
|
|
4
|
-
|
|
5
|
-
// Import root overrides (CSS custom properties)
|
|
6
|
-
@import 'css/base/root';
|
|
7
|
-
|
|
8
|
-
// Import base styles
|
|
9
|
-
@import 'css/base/animations';
|
|
10
|
-
@import 'css/base/backgrounds';
|
|
11
|
-
@import 'css/base/borders';
|
|
12
|
-
@import 'css/base/typography';
|
|
13
|
-
@import 'css/base/utilities';
|
|
14
|
-
|
|
15
|
-
// Import layout styles
|
|
16
|
-
@import 'css/layout/backend';
|
|
17
|
-
@import 'css/layout/blog';
|
|
18
|
-
@import 'css/layout/general';
|
|
19
|
-
@import 'css/layout/navigation';
|
|
20
|
-
@import 'css/layout/team';
|
|
21
|
-
|
|
22
|
-
// Import component styles
|
|
23
|
-
@import 'css/components/accordion';
|
|
24
|
-
@import 'css/components/badges';
|
|
25
|
-
@import 'css/components/buttons';
|
|
26
|
-
@import 'css/components/cards';
|
|
27
|
-
@import 'css/components/carousel';
|
|
28
|
-
@import 'css/components/forms';
|
|
29
|
-
@import 'css/components/infinite-scroll';
|
|
30
|
-
@import 'css/components/text';
|
|
31
|
-
|
|
32
|
-
// Import universal Bootstrap overrides (shared across all UJ themes)
|
|
33
|
-
// Must come AFTER Bootstrap is loaded via config to use @extend
|
|
34
|
-
@import '../bootstrap/overrides';
|