ultimate-jekyll-manager 0.0.189 → 0.0.191
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/CLAUDE.md +64 -0
- package/README.md +29 -0
- package/TODO.md +2 -0
- package/dist/assets/css/core/_verts.scss +14 -0
- package/dist/assets/css/ultimate-jekyll-manager.scss +1 -0
- package/dist/assets/js/core/exit-popup.js +3 -3
- package/dist/assets/themes/bootstrap/_theme.scss +9 -230
- package/dist/assets/themes/bootstrap/overrides/_accordion.scss +21 -0
- package/dist/assets/themes/{classy/css/components → bootstrap/overrides}/_avatars.scss +18 -3
- package/dist/assets/themes/bootstrap/overrides/_blog-images.scss +45 -0
- package/dist/assets/themes/bootstrap/overrides/_buttons-adaptive.scss +122 -0
- package/dist/assets/themes/bootstrap/overrides/_cursor-utilities.scss +13 -0
- package/dist/assets/themes/bootstrap/overrides/_index.scss +29 -0
- package/dist/assets/themes/bootstrap/overrides/_links.scss +31 -0
- package/dist/assets/themes/{classy/css/base → bootstrap/overrides}/_soft-colors.scss +11 -4
- package/dist/assets/themes/bootstrap/overrides/_spacing-extended.scss +74 -0
- package/dist/assets/themes/{classy/css/components → bootstrap/overrides}/_spinners.scss +6 -3
- package/dist/assets/themes/bootstrap/overrides/_typography-utilities.scss +40 -0
- package/dist/assets/themes/classy/_theme.js +2 -1
- package/dist/assets/themes/classy/_theme.scss +4 -5
- package/dist/assets/themes/classy/css/base/_typography.scss +0 -31
- package/dist/assets/themes/classy/css/base/_utilities.scss +1 -14
- package/dist/assets/themes/classy/css/components/_buttons.scss +0 -133
- package/dist/config/_config_default.yml +6 -0
- package/dist/defaults/Gemfile +6 -0
- package/dist/gulp/tasks/distribute.js +110 -0
- package/dist/gulp/tasks/jekyll.js +2 -0
- package/package.json +2 -2
- package/dist/assets/themes/classy/css/base/_spacing.scss +0 -68
- package/dist/assets/themes/classy/css/components/_links.scss +0 -19
package/CLAUDE.md
CHANGED
|
@@ -558,6 +558,70 @@ data-lazy="@type value"
|
|
|
558
558
|
|
|
559
559
|
**Implementation:** `src/assets/js/core/lazy-loading.js`
|
|
560
560
|
|
|
561
|
+
## Appearance Switching System
|
|
562
|
+
|
|
563
|
+
Ultimate Jekyll supports dark/light/system theme switching with user preference persistence.
|
|
564
|
+
|
|
565
|
+
### Supported Modes
|
|
566
|
+
- `dark` - Force dark mode
|
|
567
|
+
- `light` - Force light mode
|
|
568
|
+
- `system` - Auto-detect from OS preference (`prefers-color-scheme`)
|
|
569
|
+
|
|
570
|
+
### JavaScript API
|
|
571
|
+
|
|
572
|
+
```javascript
|
|
573
|
+
// Get/set preference
|
|
574
|
+
webManager.uj().appearance.get(); // Returns 'dark', 'light', 'system', or null
|
|
575
|
+
webManager.uj().appearance.set('dark'); // Save and apply preference
|
|
576
|
+
webManager.uj().appearance.getResolved(); // Returns actual theme: 'dark' or 'light'
|
|
577
|
+
|
|
578
|
+
// Utilities
|
|
579
|
+
webManager.uj().appearance.toggle(); // Toggle between dark/light
|
|
580
|
+
webManager.uj().appearance.cycle(); // Cycle: dark → light → system → dark
|
|
581
|
+
webManager.uj().appearance.clear(); // Clear saved preference
|
|
582
|
+
```
|
|
583
|
+
|
|
584
|
+
### HTML Data Attributes
|
|
585
|
+
|
|
586
|
+
```html
|
|
587
|
+
<!-- Buttons to set appearance (auto-gets 'active' class) -->
|
|
588
|
+
<button data-appearance-set="light">Light</button>
|
|
589
|
+
<button data-appearance-set="dark">Dark</button>
|
|
590
|
+
<button data-appearance-set="system">System</button>
|
|
591
|
+
|
|
592
|
+
<!-- Display current mode as text -->
|
|
593
|
+
<span data-appearance-current></span>
|
|
594
|
+
|
|
595
|
+
<!-- Show/hide icons based on current mode -->
|
|
596
|
+
<span data-appearance-icon="light" hidden>☀️</span>
|
|
597
|
+
<span data-appearance-icon="dark" hidden>🌙</span>
|
|
598
|
+
<span data-appearance-icon="system" hidden>💻</span>
|
|
599
|
+
```
|
|
600
|
+
|
|
601
|
+
### Dropdown Example
|
|
602
|
+
|
|
603
|
+
```html
|
|
604
|
+
<div class="dropdown">
|
|
605
|
+
<button class="btn dropdown-toggle" data-bs-toggle="dropdown">
|
|
606
|
+
<span data-appearance-icon="light" hidden>{% uj_icon "sun", "fa-md me-2" %}</span>
|
|
607
|
+
<span data-appearance-icon="dark" hidden>{% uj_icon "moon-stars", "fa-md me-2" %}</span>
|
|
608
|
+
<span data-appearance-icon="system" hidden>{% uj_icon "circle-half-stroke", "fa-md me-2" %}</span>
|
|
609
|
+
<span data-appearance-current></span>
|
|
610
|
+
</button>
|
|
611
|
+
<ul class="dropdown-menu">
|
|
612
|
+
<li><a class="dropdown-item" href="#" data-appearance-set="light">Light</a></li>
|
|
613
|
+
<li><a class="dropdown-item" href="#" data-appearance-set="dark">Dark</a></li>
|
|
614
|
+
<li><a class="dropdown-item" href="#" data-appearance-set="system">System</a></li>
|
|
615
|
+
</ul>
|
|
616
|
+
</div>
|
|
617
|
+
```
|
|
618
|
+
|
|
619
|
+
### Implementation
|
|
620
|
+
- **Inline script:** `src/defaults/dist/_includes/core/body.html` - Runs immediately to prevent flash
|
|
621
|
+
- **Module:** `src/assets/js/core/appearance.js` - API and UI handling
|
|
622
|
+
- **Storage:** Saved under `_manager.appearance.preference` in localStorage
|
|
623
|
+
- **Test page:** `/test/libraries/appearance`
|
|
624
|
+
|
|
561
625
|
## JavaScript Libraries
|
|
562
626
|
|
|
563
627
|
### WebManager
|
package/README.md
CHANGED
|
@@ -256,6 +256,35 @@ The `<html>` element has data attributes for JavaScript/CSS targeting:
|
|
|
256
256
|
| `data-runtime` | `web`, `extension`, `electron`, `node` |
|
|
257
257
|
| `aria-busy` | `true` (loading), `false` (ready) |
|
|
258
258
|
|
|
259
|
+
### Appearance Switching
|
|
260
|
+
|
|
261
|
+
Ultimate Jekyll supports dark/light/system theme switching with user preference persistence.
|
|
262
|
+
|
|
263
|
+
**JavaScript API:**
|
|
264
|
+
```javascript
|
|
265
|
+
webManager.uj().appearance.get(); // Returns 'dark', 'light', 'system', or null
|
|
266
|
+
webManager.uj().appearance.set('dark'); // Save and apply preference
|
|
267
|
+
webManager.uj().appearance.toggle(); // Toggle dark/light
|
|
268
|
+
webManager.uj().appearance.cycle(); // Cycle: dark → light → system
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
**HTML Dropdown Example:**
|
|
272
|
+
```html
|
|
273
|
+
<div class="dropdown">
|
|
274
|
+
<button class="btn dropdown-toggle" data-bs-toggle="dropdown">
|
|
275
|
+
<span data-appearance-icon="light" hidden>{% uj_icon "sun" %}</span>
|
|
276
|
+
<span data-appearance-icon="dark" hidden>{% uj_icon "moon-stars" %}</span>
|
|
277
|
+
<span data-appearance-icon="system" hidden>{% uj_icon "circle-half-stroke" %}</span>
|
|
278
|
+
<span data-appearance-current></span>
|
|
279
|
+
</button>
|
|
280
|
+
<ul class="dropdown-menu">
|
|
281
|
+
<li><a href="#" data-appearance-set="light">Light</a></li>
|
|
282
|
+
<li><a href="#" data-appearance-set="dark">Dark</a></li>
|
|
283
|
+
<li><a href="#" data-appearance-set="system">System</a></li>
|
|
284
|
+
</ul>
|
|
285
|
+
</div>
|
|
286
|
+
```
|
|
287
|
+
|
|
259
288
|
### Page Loading Protection System
|
|
260
289
|
|
|
261
290
|
Ultimate Jekyll includes an automatic protection system that prevents users from clicking buttons before JavaScript is fully loaded, eliminating race conditions and errors.
|
package/TODO.md
CHANGED
|
@@ -8,6 +8,8 @@ NEW TODO
|
|
|
8
8
|
- form manager should NOT submit if the button that was clicked is disabled (class or attribute)
|
|
9
9
|
- GLOBAL FIXES FOR ALL UJM PROJECTS: nav.json should ahve class only not color
|
|
10
10
|
|
|
11
|
+
/authentication-required
|
|
12
|
+
* ithink this is leftover from Electron Manager auth system??? but lots on proxifly. need to make a version of it for UJM2.0
|
|
11
13
|
|
|
12
14
|
Make an admin dashboard backend
|
|
13
15
|
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
// Core Verts Styles
|
|
2
|
+
// Styles for ad units (verts) and print visibility
|
|
3
|
+
|
|
4
|
+
// ============================================
|
|
5
|
+
// Print Styles
|
|
6
|
+
// ============================================
|
|
7
|
+
|
|
8
|
+
// Hide all vert units when printing
|
|
9
|
+
@media print {
|
|
10
|
+
vert-unit,
|
|
11
|
+
.uj-vert-unit {
|
|
12
|
+
display: none !important;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
@@ -28,9 +28,9 @@ export default function (Manager, options) {
|
|
|
28
28
|
|
|
29
29
|
// Register showExitPopup on the UJ library for programmatic access
|
|
30
30
|
// Usage: webManager.uj().showExitPopup()
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
31
|
+
console.log('---1');
|
|
32
|
+
|
|
33
|
+
webManager._ujLibrary.showExitPopup = showExitPopup;
|
|
34
34
|
|
|
35
35
|
function updateModalContent($modal, effectiveConfig) {
|
|
36
36
|
// Update title
|
|
@@ -1,232 +1,11 @@
|
|
|
1
|
-
//
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
//
|
|
5
|
-
//
|
|
6
|
-
|
|
7
|
-
// Adaptive button that uses light styles in light mode and dark styles in dark mode
|
|
8
|
-
.btn-adaptive {
|
|
9
|
-
@extend .btn-dark;
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
[data-bs-theme="dark"] .btn-adaptive {
|
|
13
|
-
@extend .btn-light;
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
// Do the same for btn-outline-light, btn-outline-dark,
|
|
17
|
-
.btn-outline-adaptive {
|
|
18
|
-
@extend .btn-outline-dark;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
[data-bs-theme="dark"] .btn-outline-adaptive {
|
|
22
|
-
@extend .btn-outline-light;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
// If nav-link is active, give it an underline
|
|
26
|
-
.nav-link.active {
|
|
27
|
-
text-decoration: underline !important;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
// Make a link-muted class that looks like text-muted
|
|
31
|
-
.link-muted {
|
|
32
|
-
--bs-text-opacity: 1;
|
|
33
|
-
color: var(--bs-secondary-color) !important;
|
|
34
|
-
text-decoration: none;
|
|
35
|
-
transition: opacity 0.15s ease-in-out;
|
|
36
|
-
|
|
37
|
-
&:hover,
|
|
38
|
-
&:focus {
|
|
39
|
-
color: var(--bs-secondary-color) !important;
|
|
40
|
-
text-decoration: underline;
|
|
41
|
-
opacity: 0.75;
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
// Padding - Extend to p-8
|
|
46
|
-
$spacer: 1rem;
|
|
47
|
-
@for $i from 6 through 8 {
|
|
48
|
-
$size: if($i == 6, 4, if($i == 7, 4.5, 5));
|
|
49
|
-
|
|
50
|
-
.p-#{$i} { padding: $spacer * $size !important; }
|
|
51
|
-
.pt-#{$i} { padding-top: $spacer * $size !important; }
|
|
52
|
-
.pb-#{$i} { padding-bottom: $spacer * $size !important; }
|
|
53
|
-
.ps-#{$i} { padding-left: $spacer * $size !important; }
|
|
54
|
-
.pe-#{$i} { padding-right: $spacer * $size !important; }
|
|
55
|
-
.px-#{$i} {
|
|
56
|
-
padding-left: $spacer * $size !important;
|
|
57
|
-
padding-right: $spacer * $size !important;
|
|
58
|
-
}
|
|
59
|
-
.py-#{$i} {
|
|
60
|
-
padding-top: $spacer * $size !important;
|
|
61
|
-
padding-bottom: $spacer * $size !important;
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
// Avatar sizes map
|
|
66
|
-
$avatar-sizes: (
|
|
67
|
-
null: 3rem, // default
|
|
68
|
-
xs: 1.5rem,
|
|
69
|
-
sm: 2rem,
|
|
70
|
-
md: 2.5rem,
|
|
71
|
-
lg: 3.5rem,
|
|
72
|
-
xl: 5rem,
|
|
73
|
-
xxl: 7.5rem
|
|
74
|
-
);
|
|
75
|
-
|
|
76
|
-
// Avatar base styles
|
|
77
|
-
.avatar {
|
|
78
|
-
display: inline-block;
|
|
79
|
-
height: map-get($avatar-sizes, null);
|
|
80
|
-
position: relative;
|
|
81
|
-
width: map-get($avatar-sizes, null);
|
|
82
|
-
|
|
83
|
-
img {
|
|
84
|
-
height: 100%;
|
|
85
|
-
-o-object-fit: cover;
|
|
86
|
-
object-fit: cover;
|
|
87
|
-
width: 100%;
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
// Generate avatar size classes
|
|
92
|
-
@each $size, $dimension in $avatar-sizes {
|
|
93
|
-
@if $size != null {
|
|
94
|
-
.avatar-#{$size} {
|
|
95
|
-
height: $dimension;
|
|
96
|
-
width: $dimension;
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
// Soft color utilities for all theme colors
|
|
102
|
-
$theme-colors: (
|
|
103
|
-
"primary": var(--bs-primary),
|
|
104
|
-
"secondary": var(--bs-secondary),
|
|
105
|
-
"success": var(--bs-success),
|
|
106
|
-
"info": var(--bs-info),
|
|
107
|
-
"warning": var(--bs-warning),
|
|
108
|
-
"danger": var(--bs-danger),
|
|
109
|
-
"light": var(--bs-light),
|
|
110
|
-
"dark": var(--bs-dark)
|
|
111
|
-
);
|
|
112
|
-
|
|
113
|
-
@each $color-name, $color-value in $theme-colors {
|
|
114
|
-
// Soft background colors (10% opacity)
|
|
115
|
-
.bg-#{$color-name}-soft {
|
|
116
|
-
background-color: rgba(var(--bs-#{$color-name}-rgb), 0.5) !important;
|
|
117
|
-
}
|
|
1
|
+
// =============================================================================
|
|
2
|
+
// UJ Bootstrap Theme
|
|
3
|
+
// =============================================================================
|
|
4
|
+
// Base Bootstrap theme with universal overrides.
|
|
5
|
+
// All UJ themes that extend Bootstrap inherit these utilities.
|
|
118
6
|
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
color: rgba(var(--bs-#{$color-name}-rgb), 0.8) !important;
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
// Soft border colors
|
|
125
|
-
.border-#{$color-name}-soft {
|
|
126
|
-
border-color: rgba(var(--bs-#{$color-name}-rgb), 0.2) !important;
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
// Soft buttons - background with hover states
|
|
130
|
-
.btn-#{$color-name}-soft {
|
|
131
|
-
color: var(--bs-#{$color-name});
|
|
132
|
-
background-color: rgba(var(--bs-#{$color-name}-rgb), 0.1);
|
|
133
|
-
border-color: rgba(var(--bs-#{$color-name}-rgb), 0.1);
|
|
134
|
-
|
|
135
|
-
&:hover {
|
|
136
|
-
color: var(--bs-#{$color-name});
|
|
137
|
-
background-color: rgba(var(--bs-#{$color-name}-rgb), 0.2);
|
|
138
|
-
border-color: rgba(var(--bs-#{$color-name}-rgb), 0.2);
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
&:focus,
|
|
142
|
-
&:active,
|
|
143
|
-
&.active {
|
|
144
|
-
color: var(--bs-#{$color-name});
|
|
145
|
-
background-color: rgba(var(--bs-#{$color-name}-rgb), 0.25);
|
|
146
|
-
border-color: rgba(var(--bs-#{$color-name}-rgb), 0.25);
|
|
147
|
-
box-shadow: 0 0 0 0.25rem rgba(var(--bs-#{$color-name}-rgb), 0.15);
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
&:disabled,
|
|
151
|
-
&.disabled {
|
|
152
|
-
color: rgba(var(--bs-#{$color-name}-rgb), 0.5);
|
|
153
|
-
background-color: rgba(var(--bs-#{$color-name}-rgb), 0.05);
|
|
154
|
-
border-color: rgba(var(--bs-#{$color-name}-rgb), 0.05);
|
|
155
|
-
}
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
// Soft outline buttons
|
|
159
|
-
.btn-outline-#{$color-name}-soft {
|
|
160
|
-
color: var(--bs-#{$color-name});
|
|
161
|
-
background-color: transparent;
|
|
162
|
-
border-color: rgba(var(--bs-#{$color-name}-rgb), 0.3);
|
|
163
|
-
|
|
164
|
-
&:hover {
|
|
165
|
-
color: var(--bs-#{$color-name});
|
|
166
|
-
background-color: rgba(var(--bs-#{$color-name}-rgb), 0.1);
|
|
167
|
-
border-color: rgba(var(--bs-#{$color-name}-rgb), 0.4);
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
&:focus,
|
|
171
|
-
&:active,
|
|
172
|
-
&.active {
|
|
173
|
-
color: var(--bs-#{$color-name});
|
|
174
|
-
background-color: rgba(var(--bs-#{$color-name}-rgb), 0.15);
|
|
175
|
-
border-color: rgba(var(--bs-#{$color-name}-rgb), 0.5);
|
|
176
|
-
box-shadow: 0 0 0 0.25rem rgba(var(--bs-#{$color-name}-rgb), 0.15);
|
|
177
|
-
}
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
// Soft badges
|
|
181
|
-
.badge-#{$color-name}-soft {
|
|
182
|
-
color: var(--bs-#{$color-name});
|
|
183
|
-
background-color: rgba(var(--bs-#{$color-name}-rgb), 0.1);
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
// Soft alerts
|
|
187
|
-
.alert-#{$color-name}-soft {
|
|
188
|
-
color: var(--bs-#{$color-name});
|
|
189
|
-
background-color: rgba(var(--bs-#{$color-name}-rgb), 0.1);
|
|
190
|
-
border-color: rgba(var(--bs-#{$color-name}-rgb), 0.2);
|
|
191
|
-
|
|
192
|
-
.alert-link {
|
|
193
|
-
color: var(--bs-#{$color-name});
|
|
194
|
-
text-decoration: underline;
|
|
195
|
-
}
|
|
196
|
-
}
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
/* Blog post card image height only - using Bootstrap's object-fit-cover class */
|
|
200
|
-
.blog-post-card-image {
|
|
201
|
-
height: 240px;
|
|
202
|
-
width: 100%;
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
@media (max-width: 991.98px) {
|
|
206
|
-
.blog-post-card-image {
|
|
207
|
-
height: 240px;
|
|
208
|
-
}
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
@media (max-width: 575.98px) {
|
|
212
|
-
.blog-post-card-image {
|
|
213
|
-
height: 200px;
|
|
214
|
-
}
|
|
215
|
-
}
|
|
216
|
-
|
|
217
|
-
/* Blog post image height only - using Bootstrap's object-fit-cover class */
|
|
218
|
-
.blog-post-image {
|
|
219
|
-
max-height: 480px;
|
|
220
|
-
width: 100%;
|
|
221
|
-
}
|
|
7
|
+
// Import Bootstrap
|
|
8
|
+
@use './scss/bootstrap.scss' as *;
|
|
222
9
|
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
max-height: 360px;
|
|
226
|
-
}
|
|
227
|
-
}
|
|
228
|
-
@media (max-width: 575.98px) {
|
|
229
|
-
.blog-post-image {
|
|
230
|
-
max-height: 240px;
|
|
231
|
-
}
|
|
232
|
-
}
|
|
10
|
+
// Import UJ universal overrides
|
|
11
|
+
@use './overrides' as *;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
// =============================================================================
|
|
2
|
+
// Accordion Enhancements
|
|
3
|
+
// =============================================================================
|
|
4
|
+
// Theme-aware accordion icons (plus/minus style).
|
|
5
|
+
// These are universal utilities available to all UJ themes.
|
|
6
|
+
|
|
7
|
+
// ============================================
|
|
8
|
+
// Light Mode Accordion Icons
|
|
9
|
+
// ============================================
|
|
10
|
+
.accordion-button::after {
|
|
11
|
+
--bs-accordion-btn-icon: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 448 512' fill='%23212529'%3E%3Cpath d='M256 80c0-17.7-14.3-32-32-32s-32 14.3-32 32l0 144L48 224c-17.7 0-32 14.3-32 32s14.3 32 32 32l144 0 0 144c0 17.7 14.3 32 32 32s32-14.3 32-32l0-144 144 0c17.7 0 32-14.3 32-32s-14.3-32-32-32l-144 0 0-144z'/%3E%3C/svg%3E");
|
|
12
|
+
--bs-accordion-btn-active-icon: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 448 512' fill='%23212529'%3E%3Cpath d='M432 256c0 17.7-14.3 32-32 32L48 288c-17.7 0-32-14.3-32-32s14.3-32 32-32l352 0c17.7 0 32 14.3 32 32z'/%3E%3C/svg%3E");
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
// ============================================
|
|
16
|
+
// Dark Mode Accordion Icons
|
|
17
|
+
// ============================================
|
|
18
|
+
[data-bs-theme="dark"] .accordion-button::after {
|
|
19
|
+
--bs-accordion-btn-icon: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 448 512' fill='%23ffffff'%3E%3Cpath d='M256 80c0-17.7-14.3-32-32-32s-32 14.3-32 32l0 144L48 224c-17.7 0-32 14.3-32 32s14.3 32 32 32l144 0 0 144c0 17.7 14.3 32 32 32s32-14.3 32-32l0-144 144 0c17.7 0 32-14.3 32-32s-14.3-32-32-32l-144 0 0-144z'/%3E%3C/svg%3E");
|
|
20
|
+
--bs-accordion-btn-active-icon: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 448 512' fill='%23ffffff'%3E%3Cpath d='M432 256c0 17.7-14.3 32-32 32L48 288c-17.7 0-32-14.3-32-32s14.3-32 32-32l352 0c17.7 0 32 14.3 32 32z'/%3E%3C/svg%3E");
|
|
21
|
+
}
|
|
@@ -1,6 +1,21 @@
|
|
|
1
|
-
//
|
|
2
|
-
//
|
|
3
|
-
//
|
|
1
|
+
// =============================================================================
|
|
2
|
+
// Avatar Components
|
|
3
|
+
// =============================================================================
|
|
4
|
+
// Circular profile images with responsive sizing.
|
|
5
|
+
// These are universal utilities available to all UJ themes.
|
|
6
|
+
|
|
7
|
+
// ============================================
|
|
8
|
+
// Avatar Size Map
|
|
9
|
+
// ============================================
|
|
10
|
+
$avatar-sizes: (
|
|
11
|
+
null: 3rem, // default
|
|
12
|
+
xs: 1.5rem,
|
|
13
|
+
sm: 2rem,
|
|
14
|
+
md: 2.5rem,
|
|
15
|
+
lg: 3.5rem,
|
|
16
|
+
xl: 5rem,
|
|
17
|
+
xxl: 7.5rem
|
|
18
|
+
) !default;
|
|
4
19
|
|
|
5
20
|
// ============================================
|
|
6
21
|
// Base Avatar Styles
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
// =============================================================================
|
|
2
|
+
// Blog Image Sizing
|
|
3
|
+
// =============================================================================
|
|
4
|
+
// Default blog post image dimensions.
|
|
5
|
+
// These are universal utilities available to all UJ themes.
|
|
6
|
+
|
|
7
|
+
// ============================================
|
|
8
|
+
// Blog Post Card Image
|
|
9
|
+
// ============================================
|
|
10
|
+
.blog-post-card-image {
|
|
11
|
+
height: 240px;
|
|
12
|
+
width: 100%;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
@media (max-width: 991.98px) {
|
|
16
|
+
.blog-post-card-image {
|
|
17
|
+
height: 240px;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
@media (max-width: 575.98px) {
|
|
22
|
+
.blog-post-card-image {
|
|
23
|
+
height: 200px;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
// ============================================
|
|
28
|
+
// Blog Post Image
|
|
29
|
+
// ============================================
|
|
30
|
+
.blog-post-image {
|
|
31
|
+
max-height: 480px;
|
|
32
|
+
width: 100%;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
@media (max-width: 991.98px) {
|
|
36
|
+
.blog-post-image {
|
|
37
|
+
max-height: 360px;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
@media (max-width: 575.98px) {
|
|
42
|
+
.blog-post-image {
|
|
43
|
+
max-height: 240px;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
// =============================================================================
|
|
2
|
+
// Adaptive Theme Buttons
|
|
3
|
+
// =============================================================================
|
|
4
|
+
// Buttons that automatically flip between light/dark styles based on theme.
|
|
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.
|
|
8
|
+
|
|
9
|
+
// ============================================
|
|
10
|
+
// Button Style Mixins (DRY)
|
|
11
|
+
// ============================================
|
|
12
|
+
@mixin btn-dark-styles {
|
|
13
|
+
--bs-btn-color: #fff;
|
|
14
|
+
--bs-btn-bg: var(--bs-dark);
|
|
15
|
+
--bs-btn-border-color: var(--bs-dark);
|
|
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;
|
|
20
|
+
--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);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
@mixin btn-light-styles {
|
|
29
|
+
--bs-btn-color: #000;
|
|
30
|
+
--bs-btn-bg: var(--bs-light);
|
|
31
|
+
--bs-btn-border-color: var(--bs-light);
|
|
32
|
+
--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;
|
|
36
|
+
--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);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
@mixin btn-outline-dark-styles {
|
|
45
|
+
--bs-btn-color: var(--bs-dark);
|
|
46
|
+
--bs-btn-border-color: var(--bs-dark);
|
|
47
|
+
--bs-btn-hover-color: #fff;
|
|
48
|
+
--bs-btn-hover-bg: var(--bs-dark);
|
|
49
|
+
--bs-btn-hover-border-color: var(--bs-dark);
|
|
50
|
+
--bs-btn-focus-shadow-rgb: 33, 37, 41;
|
|
51
|
+
--bs-btn-active-color: #fff;
|
|
52
|
+
--bs-btn-active-bg: var(--bs-dark);
|
|
53
|
+
--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);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
@mixin btn-outline-light-styles {
|
|
59
|
+
--bs-btn-color: var(--bs-light);
|
|
60
|
+
--bs-btn-border-color: var(--bs-light);
|
|
61
|
+
--bs-btn-hover-color: #000;
|
|
62
|
+
--bs-btn-hover-bg: var(--bs-light);
|
|
63
|
+
--bs-btn-hover-border-color: var(--bs-light);
|
|
64
|
+
--bs-btn-focus-shadow-rgb: 248, 249, 250;
|
|
65
|
+
--bs-btn-active-color: #000;
|
|
66
|
+
--bs-btn-active-bg: var(--bs-light);
|
|
67
|
+
--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
|
+
|
|
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;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
// ============================================
|
|
96
|
+
// Inverse Adaptive Buttons
|
|
97
|
+
// ============================================
|
|
98
|
+
// The opposite of adaptive - light in light mode, dark in dark mode
|
|
99
|
+
.btn-adaptive-inverse {
|
|
100
|
+
@include btn-light-styles;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
[data-bs-theme="dark"] .btn-adaptive-inverse {
|
|
104
|
+
@include btn-dark-styles;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
.btn-outline-adaptive-inverse {
|
|
108
|
+
@include btn-outline-light-styles;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
[data-bs-theme="dark"] .btn-outline-adaptive-inverse {
|
|
112
|
+
@include btn-outline-dark-styles;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
// ============================================
|
|
116
|
+
// Ghost Button
|
|
117
|
+
// ============================================
|
|
118
|
+
// Transparent background, no shadow - useful for subtle actions
|
|
119
|
+
.btn-ghost {
|
|
120
|
+
background: transparent;
|
|
121
|
+
box-shadow: none;
|
|
122
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
// =============================================================================
|
|
2
|
+
// Cursor Utilities
|
|
3
|
+
// =============================================================================
|
|
4
|
+
// Cursor style utilities for interactive elements.
|
|
5
|
+
// These are universal utilities available to all UJ themes.
|
|
6
|
+
|
|
7
|
+
.cursor-default { cursor: default !important; }
|
|
8
|
+
.cursor-pointer { cursor: pointer !important; }
|
|
9
|
+
.cursor-help { cursor: help !important; }
|
|
10
|
+
.cursor-move { cursor: move !important; }
|
|
11
|
+
.cursor-grab { cursor: grab !important; }
|
|
12
|
+
.cursor-not-allowed { cursor: not-allowed !important; }
|
|
13
|
+
.cursor-crosshair { cursor: crosshair !important; }
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
// =============================================================================
|
|
2
|
+
// UJ Bootstrap Overrides - Index
|
|
3
|
+
// =============================================================================
|
|
4
|
+
// Universal utilities and components that extend Bootstrap.
|
|
5
|
+
// All themes inheriting from Bootstrap will get these automatically.
|
|
6
|
+
|
|
7
|
+
// Buttons
|
|
8
|
+
@use 'buttons-adaptive';
|
|
9
|
+
|
|
10
|
+
// Colors
|
|
11
|
+
@use 'soft-colors';
|
|
12
|
+
|
|
13
|
+
// Components
|
|
14
|
+
@use 'avatars';
|
|
15
|
+
@use 'accordion';
|
|
16
|
+
@use 'spinners';
|
|
17
|
+
|
|
18
|
+
// Spacing & Layout
|
|
19
|
+
@use 'spacing-extended';
|
|
20
|
+
|
|
21
|
+
// Typography
|
|
22
|
+
@use 'typography-utilities';
|
|
23
|
+
|
|
24
|
+
// Utilities
|
|
25
|
+
@use 'cursor-utilities';
|
|
26
|
+
@use 'links';
|
|
27
|
+
|
|
28
|
+
// Blog
|
|
29
|
+
@use 'blog-images';
|