ultimate-jekyll-manager 0.0.199 → 0.0.200

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.
@@ -6,9 +6,10 @@
6
6
  "Read(//Users/ian/Developer/Repositories/ITW-Creative-works/ultimate-jekyll-manager/src/**)",
7
7
  "Read(//Users/ian/Developer/Repositories/Trusteroo/trusteroo-website/**)",
8
8
  "Bash(cat:*)",
9
- "Read(//Users/ian/Developer/Repositories/ITW-Creative-Works/ultimate-jekyll-legacy/special/master/pages/admin/notifications/**)"
9
+ "Read(//Users/ian/Developer/Repositories/ITW-Creative-Works/ultimate-jekyll-legacy/special/master/pages/admin/notifications/**)",
10
+ "mcp__mcp-router__chrome-devtools__navigate_page"
10
11
  ],
11
12
  "deny": [],
12
13
  "ask": []
13
14
  }
14
- }
15
+ }
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- const argv = require('yargs').argv;
2
+ const argv = require('yargs')(process.argv.slice(2)).parseSync();
3
3
  const cli = new (require('../dist/cli.js'))(argv);
4
4
  (async function() {
5
5
  'use strict';
@@ -156,9 +156,16 @@ function setAnalyticsUserId(user, webManager) {
156
156
  // Send user metadata to server (affiliate, UTM params, etc.)
157
157
  async function sendUserSignupMetadata(user, webManager) {
158
158
  try {
159
- // Check if this is a new user account (created in last 5 minutes)
159
+ // Skip on auth pages to avoid blocking redirect (metadata will be sent on destination page)
160
+ const pagePath = document.documentElement.getAttribute('data-page-path');
161
+ const authPages = ['/signin', '/signup', '/reset'];
162
+ if (authPages.includes(pagePath)) {
163
+ return;
164
+ }
165
+
166
+ // Check if this is a new user account (created in last X minutes)
160
167
  const accountAge = Date.now() - new Date(user.metadata.creationTime).getTime();
161
- const signupProcessed = webManager.storage().get('flags.signupProcessed', false);
168
+ const signupProcessed = webManager.storage().get('flags.signupProcessed', null) === user.uid;
162
169
 
163
170
  /* @dev-only:start */
164
171
  {
@@ -202,8 +209,8 @@ async function sendUserSignupMetadata(user, webManager) {
202
209
  // Log
203
210
  console.log('[Auth] User metadata sent successfully:', response);
204
211
 
205
- // Mark signup as sent (keep the attribution data for reference)
206
- webManager.storage().set('flags.signupProcessed', true);
212
+ // Mark signup as sent for this user (keep the attribution data for reference)
213
+ webManager.storage().set('flags.signupProcessed', user.uid);
207
214
  } catch (error) {
208
215
  console.error('[Auth] Error sending user metadata:', error);
209
216
  // Don't throw - we don't want to block the signup flow
@@ -71,6 +71,9 @@ export default function (Manager, options) {
71
71
  url.searchParams.set('itm_campaign', 'exit-popup');
72
72
  url.searchParams.set('itm_content', window.location.pathname);
73
73
  $button.href = url.toString();
74
+
75
+ // Remove data-bs-dismiss so the link navigation works properly
76
+ $button.removeAttribute('data-bs-dismiss');
74
77
  }
75
78
  }
76
79
 
@@ -13,6 +13,9 @@ export default function (Manager) {
13
13
  const url = new URL(window.location.href);
14
14
  const useAuthPopup = url.searchParams.get('authPopup') === 'true' || window !== window.top;
15
15
 
16
+ // Fire wakeup call immediately to prevent cold start on signup API call (fire-and-forget)
17
+ // wakeupServer(webManager);
18
+
16
19
  // Handle DOM ready
17
20
  webManager.dom().ready()
18
21
  .then(async () => {
@@ -653,4 +656,13 @@ export default function (Manager) {
653
656
  content_name: 'Password Reset'
654
657
  });
655
658
  }
659
+
660
+ // Wakeup server to prevent cold start on signup API call
661
+ function wakeupServer(webManager) {
662
+ const serverApiURL = `${webManager.getApiUrl()}/backend-manager/user/signup?wakeup=true`;
663
+
664
+ fetch(serverApiURL, { method: 'POST' })
665
+ .then(() => console.log('[Auth] Server wakeup sent'))
666
+ .catch(() => {}); // Silently ignore errors
667
+ }
656
668
  }
@@ -156,7 +156,7 @@ export class FormManager {
156
156
 
157
157
  // Focus the field with autofocus attribute if it exists (desktop only)
158
158
  const $autofocusField = this.$form.querySelector('[autofocus]');
159
- if ($autofocusField && !$autofocusField.disabled && window.Manager?.webManager?.utilities()?.getDeviceType() === 'desktop') {
159
+ if ($autofocusField && !$autofocusField.disabled && window.Manager?.webManager?.utilities()?.getDevice() === 'desktop') {
160
160
  this._focusField($autofocusField);
161
161
  }
162
162
  }
@@ -62,13 +62,6 @@ function setupDeleteAccountForm() {
62
62
  throw new Error('Account deletion cancelled. You must type "DELETE" exactly to confirm.');
63
63
  }
64
64
 
65
- // Final confirmation
66
- const finalConfirm = confirm('This is your last chance to cancel.\n\nAre you sure you want to permanently delete your account?');
67
-
68
- if (!finalConfirm) {
69
- throw new Error('Account deletion cancelled.');
70
- }
71
-
72
65
  // Send delete request to server
73
66
  const response = await authorizedFetch(`${webManager.getApiUrl()}/backend-manager/user`, {
74
67
  method: 'DELETE',
@@ -108,4 +101,4 @@ export async function loadData() {
108
101
  // Called when section is shown
109
102
  export function onShow() {
110
103
  // Nothing needed
111
- }
104
+ }
@@ -9,12 +9,16 @@
9
9
  // ============================================
10
10
  $avatar-sizes: (
11
11
  null: 3rem, // default
12
+ 2xs: 0.5rem,
12
13
  xs: 1.5rem,
13
14
  sm: 2rem,
14
15
  md: 2.5rem,
15
16
  lg: 3.5rem,
16
17
  xl: 5rem,
17
- xxl: 7.5rem
18
+ 2xl: 7.5rem,
19
+ 3xl: 10rem,
20
+ 4xl: 12.5rem,
21
+ 5xl: 15rem
18
22
  ) !default;
19
23
 
20
24
  // ============================================
@@ -3,93 +3,66 @@
3
3
  // =============================================================================
4
4
  // Buttons that automatically flip between light/dark styles based on theme.
5
5
  // These are universal utilities available to all UJ themes.
6
- // Note: Cannot use @extend with Bootstrap classes due to module scoping,
7
- // so we use CSS custom properties directly.
6
+ // Uses CSS custom properties from _color-shades.scss for hover/active states.
8
7
 
9
8
  // ============================================
10
- // Button Style Mixins (DRY)
9
+ // Solid Adaptive Buttons
11
10
  // ============================================
12
- @mixin btn-dark-styles {
11
+ // Dark button in light mode, light button in dark mode
12
+ .btn-adaptive {
13
13
  --bs-btn-color: #fff;
14
14
  --bs-btn-bg: var(--bs-dark);
15
15
  --bs-btn-border-color: var(--bs-dark);
16
16
  --bs-btn-hover-color: #fff;
17
- --bs-btn-hover-bg: #1c1c1c;
18
- --bs-btn-hover-border-color: #1a1a1a;
19
- --bs-btn-focus-shadow-rgb: 66, 70, 73;
17
+ --bs-btn-hover-bg: var(--bs-dark-hover);
18
+ --bs-btn-hover-border-color: var(--bs-dark-active);
20
19
  --bs-btn-active-color: #fff;
21
- --bs-btn-active-bg: #1a1a1a;
22
- --bs-btn-active-border-color: #181818;
23
- --bs-btn-disabled-color: #fff;
24
- --bs-btn-disabled-bg: var(--bs-dark);
25
- --bs-btn-disabled-border-color: var(--bs-dark);
20
+ --bs-btn-active-bg: var(--bs-dark-active);
21
+ --bs-btn-active-border-color: var(--bs-dark-active);
26
22
  }
27
23
 
28
- @mixin btn-light-styles {
24
+ [data-bs-theme="dark"] .btn-adaptive {
29
25
  --bs-btn-color: #000;
30
26
  --bs-btn-bg: var(--bs-light);
31
27
  --bs-btn-border-color: var(--bs-light);
32
28
  --bs-btn-hover-color: #000;
33
- --bs-btn-hover-bg: #e9ecef;
34
- --bs-btn-hover-border-color: #e2e6ea;
35
- --bs-btn-focus-shadow-rgb: 211, 212, 213;
29
+ --bs-btn-hover-bg: var(--bs-light-hover);
30
+ --bs-btn-hover-border-color: var(--bs-light-active);
36
31
  --bs-btn-active-color: #000;
37
- --bs-btn-active-bg: #e2e6ea;
38
- --bs-btn-active-border-color: #dae0e5;
39
- --bs-btn-disabled-color: #000;
40
- --bs-btn-disabled-bg: var(--bs-light);
41
- --bs-btn-disabled-border-color: var(--bs-light);
32
+ --bs-btn-active-bg: var(--bs-light-active);
33
+ --bs-btn-active-border-color: var(--bs-light-active);
42
34
  }
43
35
 
44
- @mixin btn-outline-dark-styles {
36
+ // ============================================
37
+ // Outline Adaptive Buttons
38
+ // ============================================
39
+ .btn-outline-adaptive {
45
40
  --bs-btn-color: var(--bs-dark);
41
+ --bs-btn-bg: transparent;
46
42
  --bs-btn-border-color: var(--bs-dark);
47
43
  --bs-btn-hover-color: #fff;
48
44
  --bs-btn-hover-bg: var(--bs-dark);
49
45
  --bs-btn-hover-border-color: var(--bs-dark);
50
- --bs-btn-focus-shadow-rgb: 33, 37, 41;
51
46
  --bs-btn-active-color: #fff;
52
47
  --bs-btn-active-bg: var(--bs-dark);
53
48
  --bs-btn-active-border-color: var(--bs-dark);
54
- --bs-btn-disabled-color: var(--bs-dark);
55
- --bs-btn-disabled-border-color: var(--bs-dark);
49
+
50
+ color: var(--bs-body-color);
51
+ border-color: var(--bs-dark);
56
52
  }
57
53
 
58
- @mixin btn-outline-light-styles {
54
+ [data-bs-theme="dark"] .btn-outline-adaptive {
59
55
  --bs-btn-color: var(--bs-light);
56
+ --bs-btn-bg: transparent;
60
57
  --bs-btn-border-color: var(--bs-light);
61
58
  --bs-btn-hover-color: #000;
62
59
  --bs-btn-hover-bg: var(--bs-light);
63
60
  --bs-btn-hover-border-color: var(--bs-light);
64
- --bs-btn-focus-shadow-rgb: 248, 249, 250;
65
61
  --bs-btn-active-color: #000;
66
62
  --bs-btn-active-bg: var(--bs-light);
67
63
  --bs-btn-active-border-color: var(--bs-light);
68
- --bs-btn-disabled-color: var(--bs-light);
69
- --bs-btn-disabled-border-color: var(--bs-light);
70
- }
71
64
 
72
- // ============================================
73
- // Solid Adaptive Buttons
74
- // ============================================
75
- // Dark button in light mode, light button in dark mode
76
- .btn-adaptive {
77
- @include btn-dark-styles;
78
- }
79
-
80
- [data-bs-theme="dark"] .btn-adaptive {
81
- @include btn-light-styles;
82
- }
83
-
84
- // ============================================
85
- // Outline Adaptive Buttons
86
- // ============================================
87
- .btn-outline-adaptive {
88
- @include btn-outline-dark-styles;
89
- }
90
-
91
- [data-bs-theme="dark"] .btn-outline-adaptive {
92
- @include btn-outline-light-styles;
65
+ border-color: var(--bs-light);
93
66
  }
94
67
 
95
68
  // ============================================
@@ -97,19 +70,59 @@
97
70
  // ============================================
98
71
  // The opposite of adaptive - light in light mode, dark in dark mode
99
72
  .btn-adaptive-inverse {
100
- @include btn-light-styles;
73
+ --bs-btn-color: #000;
74
+ --bs-btn-bg: var(--bs-light);
75
+ --bs-btn-border-color: var(--bs-light);
76
+ --bs-btn-hover-color: #000;
77
+ --bs-btn-hover-bg: var(--bs-light-hover);
78
+ --bs-btn-hover-border-color: var(--bs-light-active);
79
+ --bs-btn-active-color: #000;
80
+ --bs-btn-active-bg: var(--bs-light-active);
81
+ --bs-btn-active-border-color: var(--bs-light-active);
101
82
  }
102
83
 
103
84
  [data-bs-theme="dark"] .btn-adaptive-inverse {
104
- @include btn-dark-styles;
85
+ --bs-btn-color: #fff;
86
+ --bs-btn-bg: var(--bs-dark);
87
+ --bs-btn-border-color: var(--bs-dark);
88
+ --bs-btn-hover-color: #fff;
89
+ --bs-btn-hover-bg: var(--bs-dark-hover);
90
+ --bs-btn-hover-border-color: var(--bs-dark-active);
91
+ --bs-btn-active-color: #fff;
92
+ --bs-btn-active-bg: var(--bs-dark-active);
93
+ --bs-btn-active-border-color: var(--bs-dark-active);
105
94
  }
106
95
 
96
+ // ============================================
97
+ // Outline Inverse Adaptive Buttons
98
+ // ============================================
107
99
  .btn-outline-adaptive-inverse {
108
- @include btn-outline-light-styles;
100
+ --bs-btn-color: var(--bs-light);
101
+ --bs-btn-bg: transparent;
102
+ --bs-btn-border-color: var(--bs-light);
103
+ --bs-btn-hover-color: #000;
104
+ --bs-btn-hover-bg: var(--bs-light);
105
+ --bs-btn-hover-border-color: var(--bs-light);
106
+ --bs-btn-active-color: #000;
107
+ --bs-btn-active-bg: var(--bs-light);
108
+ --bs-btn-active-border-color: var(--bs-light);
109
+
110
+ color: var(--bs-body-color);
111
+ border-color: var(--bs-light);
109
112
  }
110
113
 
111
114
  [data-bs-theme="dark"] .btn-outline-adaptive-inverse {
112
- @include btn-outline-dark-styles;
115
+ --bs-btn-color: var(--bs-dark);
116
+ --bs-btn-bg: transparent;
117
+ --bs-btn-border-color: var(--bs-dark);
118
+ --bs-btn-hover-color: #fff;
119
+ --bs-btn-hover-bg: var(--bs-dark);
120
+ --bs-btn-hover-border-color: var(--bs-dark);
121
+ --bs-btn-active-color: #fff;
122
+ --bs-btn-active-bg: var(--bs-dark);
123
+ --bs-btn-active-border-color: var(--bs-dark);
124
+
125
+ border-color: var(--bs-dark);
113
126
  }
114
127
 
115
128
  // ============================================
@@ -0,0 +1,25 @@
1
+ // =============================================================================
2
+ // Color Shade CSS Custom Properties
3
+ // =============================================================================
4
+ // Provides hover/active shade variants for light and dark colors.
5
+ // These are used by adaptive buttons and can be reused elsewhere.
6
+
7
+ :root,
8
+ [data-bs-theme="light"] {
9
+ // Dark color shades (for hover/active states on dark buttons)
10
+ --bs-dark-hover: #3a3a44;
11
+ --bs-dark-active: #34343e;
12
+
13
+ // Light color shades (for hover/active states on light buttons)
14
+ --bs-light-hover: #d3d6db;
15
+ --bs-light-active: #c8ccd1;
16
+ }
17
+
18
+ [data-bs-theme="dark"] {
19
+ // In dark mode, the values are the same but semantic meaning is swapped
20
+ --bs-dark-hover: #3a3a44;
21
+ --bs-dark-active: #34343e;
22
+
23
+ --bs-light-hover: #d3d6db;
24
+ --bs-light-active: #c8ccd1;
25
+ }
@@ -8,6 +8,7 @@
8
8
  @use 'buttons-adaptive';
9
9
 
10
10
  // Colors
11
+ @use 'color-shades';
11
12
  @use 'soft-colors';
12
13
 
13
14
  // Components
@@ -110,11 +110,10 @@
110
110
  // Outline Button Overrides
111
111
  // ============================================
112
112
  [class*="btn-outline-"] {
113
- background: transparent !important;
114
113
  border-width: 2px !important;
115
114
  border-style: solid !important;
116
115
 
117
- &:not(:hover) {
116
+ &:not(:hover):not(:active):not(.active) {
118
117
  background: transparent !important;
119
118
  }
120
119
  }
package/dist/build.js CHANGED
@@ -3,7 +3,7 @@ const path = require('path');
3
3
  const jetpack = require('fs-jetpack');
4
4
  const fs = require('fs');
5
5
  const JSON5 = require('json5');
6
- const argv = require('yargs').argv;
6
+ const argv = require('yargs')(process.argv.slice(2)).parseSync();
7
7
  const { force, execute } = require('node-powertools');
8
8
  const yaml = require('js-yaml');
9
9
 
@@ -453,6 +453,13 @@ meta:
453
453
  <button type="button" class="btn btn-outline-light">Light</button>
454
454
  <button type="button" class="btn btn-outline-dark">Dark</button>
455
455
 
456
+ <h3 class="mt-4 mb-3">Adaptive Buttons (Theme-Aware)</h3>
457
+ <p class="text-muted">These buttons automatically adapt to light/dark mode. Use instead of btn-light/btn-dark.</p>
458
+ <button type="button" class="btn btn-adaptive">Adaptive</button>
459
+ <button type="button" class="btn btn-outline-adaptive">Outline Adaptive</button>
460
+ <button type="button" class="btn btn-adaptive-inverse">Adaptive Inverse</button>
461
+ <button type="button" class="btn btn-outline-adaptive-inverse">Outline Adaptive Inverse</button>
462
+
456
463
  <h3 class="mt-4 mb-3">Button Sizes</h3>
457
464
  <button type="button" class="btn btn-primary btn-lg">Large button</button>
458
465
  <button type="button" class="btn btn-primary">Default button</button>
@@ -8,7 +8,7 @@ const path = require('path');
8
8
  const { minimatch } = require('minimatch');
9
9
  const { template } = require('node-powertools');
10
10
  const createTemplateTransform = require('./utils/template-transform');
11
- const argv = require('yargs').argv;
11
+ const argv = require('yargs')(process.argv.slice(2)).parseSync();
12
12
  const JSON5 = require('json5');
13
13
 
14
14
  // Load package
@@ -218,6 +218,10 @@ function sass(complete) {
218
218
  /^active$/,
219
219
  /^disabled$/,
220
220
 
221
+ // Buttons
222
+ // /^btn-outline-adaptive$/,
223
+ // /^btn-adaptive$/,
224
+
221
225
  // Accordion specific
222
226
  /^accordion/,
223
227
  /^collapsed$/,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ultimate-jekyll-manager",
3
- "version": "0.0.199",
3
+ "version": "0.0.200",
4
4
  "description": "Ultimate Jekyll dependency manager",
5
5
  "main": "dist/index.js",
6
6
  "exports": {
@@ -62,7 +62,7 @@
62
62
  "dependencies": {
63
63
  "@babel/core": "^7.28.6",
64
64
  "@babel/preset-env": "^7.28.6",
65
- "@fullhuman/postcss-purgecss": "^7.0.2",
65
+ "@fullhuman/postcss-purgecss": "^8.0.0",
66
66
  "@minify-html/node": "^0.18.1",
67
67
  "@octokit/rest": "^22.0.1",
68
68
  "@popperjs/core": "^2.11.8",
@@ -71,7 +71,7 @@
71
71
  "babel-loader": "^10.0.0",
72
72
  "browser-sync": "^3.0.4",
73
73
  "chalk": "^5.6.2",
74
- "cheerio": "^1.1.2",
74
+ "cheerio": "^1.2.0",
75
75
  "chrome-launcher": "^1.2.1",
76
76
  "dotenv": "^17.2.3",
77
77
  "fast-xml-parser": "^5.3.3",
@@ -84,25 +84,25 @@
84
84
  "gulp-responsive-modern": "^1.0.0",
85
85
  "gulp-sass": "^6.0.1",
86
86
  "html-minifier-terser": "^7.2.0",
87
- "html-validate": "^10.5.0",
87
+ "html-validate": "^10.7.0",
88
88
  "itwcw-package-analytics": "^1.0.6",
89
- "js-yaml": "^3.14.2",
89
+ "js-yaml": "^4.1.1",
90
90
  "json5": "^2.2.3",
91
- "libsodium-wrappers": "^0.8.0",
92
- "lodash": "^4.17.21",
91
+ "libsodium-wrappers": "^0.8.2",
92
+ "lodash": "^4.17.23",
93
93
  "minimatch": "^10.1.1",
94
94
  "node-powertools": "^2.3.2",
95
95
  "npm-api": "^1.0.1",
96
96
  "postcss": "^8.5.6",
97
- "prettier": "^3.8.0",
98
- "sass": "^1.97.2",
97
+ "prettier": "^3.8.1",
98
+ "sass": "^1.97.3",
99
99
  "spellchecker": "^3.7.1",
100
100
  "through2": "^4.0.2",
101
101
  "web-manager": "^4.1.6",
102
102
  "webpack": "^5.104.1",
103
103
  "wonderful-fetch": "^1.3.4",
104
104
  "wonderful-version": "^1.3.2",
105
- "yargs": "^17.7.2"
105
+ "yargs": "^18.0.0"
106
106
  },
107
107
  "peerDependencies": {
108
108
  "gulp": "^5.0.1"