ultimate-jekyll-manager 1.4.3 → 1.6.0
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 +36 -0
- package/CLAUDE-ATTRIBUTION.md +215 -0
- package/CLAUDE.md +7 -6
- package/README.md +1 -0
- package/dist/assets/css/pages/test/libraries/layers/index.scss +28 -0
- package/dist/assets/js/modules/redirect.js +5 -4
- package/dist/assets/js/pages/download/index.js +1 -1
- package/dist/assets/js/pages/feedback/index.js +1 -1
- package/dist/assets/js/pages/test/libraries/layers/index.js +11 -0
- package/dist/assets/themes/_template/README.md +50 -0
- package/dist/assets/themes/_template/_config.scss +60 -0
- package/dist/assets/themes/_template/_theme.js +13 -4
- package/dist/assets/themes/_template/_theme.scss +16 -4
- package/dist/assets/themes/_template/css/base/_root.scss +19 -0
- package/dist/assets/themes/_template/css/components/_components.scss +23 -0
- package/dist/assets/themes/classy/README.md +18 -6
- package/dist/assets/themes/neobrutalism/README.md +98 -0
- package/dist/assets/themes/neobrutalism/_config.scss +139 -0
- package/dist/assets/themes/neobrutalism/_theme.js +27 -0
- package/dist/assets/themes/neobrutalism/_theme.scss +33 -0
- package/dist/assets/themes/neobrutalism/css/base/_mixins.scss +46 -0
- package/dist/assets/themes/neobrutalism/css/base/_root.scss +80 -0
- package/dist/assets/themes/neobrutalism/css/base/_typography.scss +77 -0
- package/dist/assets/themes/neobrutalism/css/base/_utilities.scss +25 -0
- package/dist/assets/themes/neobrutalism/css/components/_buttons.scss +148 -0
- package/dist/assets/themes/neobrutalism/css/components/_cards.scss +69 -0
- package/dist/assets/themes/neobrutalism/css/components/_forms.scss +88 -0
- package/dist/assets/themes/neobrutalism/css/components/_infinite-scroll.scss +94 -0
- package/dist/assets/themes/neobrutalism/css/layout/_general.scss +200 -0
- package/dist/assets/themes/neobrutalism/css/layout/_navigation.scss +153 -0
- package/dist/assets/themes/neobrutalism/js/initialize-tooltips.js +20 -0
- package/dist/assets/themes/neobrutalism/js/navbar-scroll.js +29 -0
- package/dist/assets/themes/neobrutalism/pages/index.scss +227 -0
- package/dist/assets/themes/neobrutalism/pages/pricing/index.scss +267 -0
- package/dist/assets/themes/neobrutalism/pages/test/libraries/layers/index.js +9 -0
- package/dist/assets/themes/neobrutalism/pages/test/libraries/layers/index.scss +7 -0
- package/dist/build.js +2 -5
- package/dist/commands/install.js +1 -1
- package/dist/commands/setup.js +41 -0
- package/dist/defaults/CLAUDE.md +5 -1
- package/dist/defaults/dist/_includes/core/head.html +17 -0
- package/dist/defaults/dist/_includes/themes/classy/frontend/sections/footer.html +4 -4
- package/dist/defaults/dist/_layouts/themes/classy/frontend/pages/download.html +2 -0
- package/dist/defaults/dist/_layouts/themes/classy/frontend/pages/feedback.html +7 -3
- package/dist/defaults/dist/_layouts/themes/neobrutalism/frontend/core/base.html +31 -0
- package/dist/defaults/dist/_layouts/themes/neobrutalism/frontend/pages/index.html +345 -0
- package/dist/defaults/dist/_layouts/themes/neobrutalism/frontend/pages/pricing.html +483 -0
- package/dist/defaults/dist/pages/test/libraries/layers.html +57 -0
- package/dist/defaults/src/_config.yml +2 -0
- package/dist/defaults/test/_init.js +10 -0
- package/dist/gulp/tasks/defaults.js +8 -0
- package/dist/gulp/tasks/sass.js +43 -2
- package/dist/gulp/tasks/translation.js +11 -0
- package/dist/gulp/tasks/utils/manage-test-layers.js +97 -0
- package/dist/index.js +30 -4
- package/dist/test/runner.js +62 -0
- package/dist/test/suites/build/manager.test.js +11 -4
- package/dist/test/suites/build/mode-helpers.test.js +54 -2
- package/dist/utils/mode-helpers.js +65 -40
- package/docs/assets.md +6 -1
- package/docs/environment-detection.md +85 -0
- package/docs/test-framework.md +48 -3
- package/docs/themes.md +451 -0
- package/package.json +2 -1
- package/docs/cross-context-helpers.md +0 -75
- package/package copy.json +0 -75
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
// Neobrutalism Theme — Navigation
|
|
2
|
+
// The inherited nav markup (.navbar-wrapper > .navbar.navbar-floating) is a
|
|
3
|
+
// floating glass pill in Classy. Here we make it a solid, ink-framed bar that
|
|
4
|
+
// sits flush at the top — a hard horizontal block, true to the style.
|
|
5
|
+
|
|
6
|
+
.navbar-wrapper {
|
|
7
|
+
position: fixed;
|
|
8
|
+
top: 0;
|
|
9
|
+
left: 0;
|
|
10
|
+
right: 0;
|
|
11
|
+
z-index: 1030;
|
|
12
|
+
pointer-events: none;
|
|
13
|
+
|
|
14
|
+
.navbar {
|
|
15
|
+
pointer-events: auto;
|
|
16
|
+
width: 100%;
|
|
17
|
+
max-width: 100%;
|
|
18
|
+
margin: 0;
|
|
19
|
+
padding-left: clamp(1rem, 4vw, 3rem);
|
|
20
|
+
padding-right: clamp(1rem, 4vw, 3rem);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
.navbar.navbar-floating {
|
|
25
|
+
border-radius: 0;
|
|
26
|
+
padding: 0.75rem clamp(1rem, 4vw, 3rem);
|
|
27
|
+
background: var(--nb-surface) !important;
|
|
28
|
+
border: 0;
|
|
29
|
+
border-bottom: $nb-border-width-lg solid var(--nb-border-color);
|
|
30
|
+
transition: $nb-transition;
|
|
31
|
+
|
|
32
|
+
// Slight shadow only once scrolled (set by _theme.js)
|
|
33
|
+
&.scrolled {
|
|
34
|
+
@include nb-shadow(sm);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
.container,
|
|
38
|
+
.container-fluid {
|
|
39
|
+
padding: 0;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// Brand: chunky display type, no fade
|
|
44
|
+
.navbar-brand {
|
|
45
|
+
font-family: $nb-font-display;
|
|
46
|
+
font-weight: 900;
|
|
47
|
+
font-size: 1.4rem;
|
|
48
|
+
letter-spacing: -0.03em;
|
|
49
|
+
|
|
50
|
+
.brand-logo { height: 32px; width: auto; margin-right: 0.5rem; }
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// Nav links: square hover blocks. Hover/active fill is the PRIMARY blue (white
|
|
54
|
+
// text) — not the yellow accent — so the top-bar interactions match the brand's
|
|
55
|
+
// blue buttons instead of the yellow CTA accent.
|
|
56
|
+
.navbar-nav .nav-link {
|
|
57
|
+
font-weight: 700;
|
|
58
|
+
font-size: 0.95rem;
|
|
59
|
+
padding: 0.4rem 0.85rem;
|
|
60
|
+
margin: 0 0.15rem;
|
|
61
|
+
border-radius: 0;
|
|
62
|
+
color: var(--bs-body-color);
|
|
63
|
+
border: $nb-border-width-sm solid transparent;
|
|
64
|
+
transition: $nb-transition;
|
|
65
|
+
|
|
66
|
+
// Interactive accent (blue), not the yellow signature accent. Single token so
|
|
67
|
+
// every hover/active state across the theme stays consistent.
|
|
68
|
+
&:hover {
|
|
69
|
+
background: var(--nb-accent-interactive);
|
|
70
|
+
color: var(--nb-accent-interactive-ink);
|
|
71
|
+
border-color: var(--nb-border-color);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// Active = solid blue block with white text (matches hover, always readable).
|
|
75
|
+
// Use &.active.active + !important to beat Bootstrap's .text-body utility that
|
|
76
|
+
// the nav include adds to links (which otherwise forces color back to body).
|
|
77
|
+
&.active,
|
|
78
|
+
&.active.text-body {
|
|
79
|
+
background: var(--nb-accent-interactive) !important;
|
|
80
|
+
color: var(--nb-accent-interactive-ink) !important;
|
|
81
|
+
border-color: var(--nb-border-color);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// Mobile toggle: a hard square button
|
|
86
|
+
.navbar-toggler {
|
|
87
|
+
border-radius: 0;
|
|
88
|
+
padding: 0.3rem 0.55rem;
|
|
89
|
+
background: var(--nb-surface);
|
|
90
|
+
@include nb-border($nb-border-width-sm);
|
|
91
|
+
transition: $nb-transition;
|
|
92
|
+
|
|
93
|
+
&:hover { background: var(--nb-accent-interactive); }
|
|
94
|
+
&:focus { box-shadow: var(--nb-shadow-sm); }
|
|
95
|
+
|
|
96
|
+
.navbar-toggler-icon {
|
|
97
|
+
width: 1.25em;
|
|
98
|
+
height: 1.25em;
|
|
99
|
+
background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%2817,17,17,1%29' stroke-linecap='square' stroke-miterlimit='10' stroke-width='3' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e");
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
[data-bs-theme="dark"] & .navbar-toggler-icon {
|
|
103
|
+
background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%28245,245,245,1%29' stroke-linecap='square' stroke-miterlimit='10' stroke-width='3' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e");
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
// Mobile collapsed menu becomes a bordered drawer panel
|
|
108
|
+
@media (max-width: 991.98px) {
|
|
109
|
+
.navbar-collapse {
|
|
110
|
+
margin-top: 0.75rem;
|
|
111
|
+
padding: 0.75rem;
|
|
112
|
+
background: var(--nb-surface);
|
|
113
|
+
@include nb-border();
|
|
114
|
+
@include nb-shadow(md);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
// ============================================
|
|
119
|
+
// Dropdown menus — hard bordered panels
|
|
120
|
+
// ============================================
|
|
121
|
+
.dropdown-menu {
|
|
122
|
+
background: var(--nb-surface);
|
|
123
|
+
border-radius: 0;
|
|
124
|
+
@include nb-border();
|
|
125
|
+
@include nb-shadow(md);
|
|
126
|
+
padding: 0.4rem;
|
|
127
|
+
margin-top: 0.6rem;
|
|
128
|
+
|
|
129
|
+
.dropdown-item {
|
|
130
|
+
border-radius: 0;
|
|
131
|
+
font-weight: 600;
|
|
132
|
+
padding: 0.55rem 0.85rem;
|
|
133
|
+
color: var(--bs-body-color);
|
|
134
|
+
|
|
135
|
+
&:hover,
|
|
136
|
+
&:focus {
|
|
137
|
+
background: var(--nb-accent-interactive);
|
|
138
|
+
color: var(--nb-accent-interactive-ink);
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
&.active,
|
|
142
|
+
&:active {
|
|
143
|
+
background: var(--bs-body-color);
|
|
144
|
+
color: var(--nb-paper);
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
.dropdown-divider {
|
|
149
|
+
border-top: $nb-border-width-sm solid var(--nb-border-color);
|
|
150
|
+
opacity: 1;
|
|
151
|
+
margin: 0.4rem 0;
|
|
152
|
+
}
|
|
153
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Initialize Bootstrap Tooltips
|
|
3
|
+
* Finds all elements with data-bs-toggle="tooltip" and initializes them
|
|
4
|
+
*/
|
|
5
|
+
export default function initializeTooltips() {
|
|
6
|
+
const $tooltipTriggers = document.querySelectorAll('[data-bs-toggle="tooltip"]');
|
|
7
|
+
|
|
8
|
+
// If no tooltips found, exit early
|
|
9
|
+
if ($tooltipTriggers.length === 0) {
|
|
10
|
+
return;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
// Log the number of tooltips being initialized
|
|
14
|
+
console.log(`Initializing ${$tooltipTriggers.length} tooltips`);
|
|
15
|
+
|
|
16
|
+
// Initialize each tooltip
|
|
17
|
+
$tooltipTriggers.forEach(($el) => {
|
|
18
|
+
new bootstrap.Tooltip($el);
|
|
19
|
+
});
|
|
20
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
// Navbar scroll effect for the Neobrutalism theme.
|
|
2
|
+
// Toggles a `.scrolled` class on the floating navbar once the page is scrolled
|
|
3
|
+
// past a threshold; the SCSS turns that into a hard offset shadow under the bar.
|
|
4
|
+
// Threshold is configurable via the data-nb-scroll-threshold attribute on the navbar.
|
|
5
|
+
export default function setupNavbarScroll() {
|
|
6
|
+
const navbar = document.querySelector('.navbar-floating');
|
|
7
|
+
if (!navbar) {
|
|
8
|
+
return;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
const threshold = parseInt(navbar.dataset.nbScrollThreshold, 10) || 20;
|
|
12
|
+
|
|
13
|
+
let ticking = false;
|
|
14
|
+
function update() {
|
|
15
|
+
navbar.classList.toggle('scrolled', window.scrollY > threshold);
|
|
16
|
+
ticking = false;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
function onScroll() {
|
|
20
|
+
if (!ticking) {
|
|
21
|
+
ticking = true;
|
|
22
|
+
window.requestAnimationFrame(update);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
// Initial state + listener
|
|
27
|
+
update();
|
|
28
|
+
window.addEventListener('scroll', onScroll, { passive: true });
|
|
29
|
+
}
|
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
// Neobrutalism Theme — Homepage page-specific CSS
|
|
2
|
+
// Styles the neobrutalist homepage override
|
|
3
|
+
// (_layouts/themes/neobrutalism/frontend/pages/index.html).
|
|
4
|
+
//
|
|
5
|
+
// Class names are UNIVERSAL (section-hero, showcase-row, stat-block, cta-panel,
|
|
6
|
+
// .card, Bootstrap .text-bg-* …) — no theme prefix — so the same markup is
|
|
7
|
+
// swappable across themes. This file gives those classes the neobrutalist look.
|
|
8
|
+
// Compiles standalone, so it pulls in the theme tokens + mixins via loadPaths.
|
|
9
|
+
@use 'config' as *;
|
|
10
|
+
@import 'css/base/mixins';
|
|
11
|
+
|
|
12
|
+
// Shared section heading block
|
|
13
|
+
.section-head { max-width: 60ch; }
|
|
14
|
+
.section-title {
|
|
15
|
+
font-family: $nb-font-display;
|
|
16
|
+
font-weight: 900;
|
|
17
|
+
font-size: clamp(2rem, 5vw, 3.5rem);
|
|
18
|
+
letter-spacing: -0.03em;
|
|
19
|
+
line-height: 1;
|
|
20
|
+
margin: 0;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
// ============================================
|
|
24
|
+
// Hero — asymmetric split (.text-bg-warning gives the yellow block + ink text)
|
|
25
|
+
// ============================================
|
|
26
|
+
.section-hero {
|
|
27
|
+
padding-top: clamp(3rem, 8vw, 7rem);
|
|
28
|
+
padding-bottom: clamp(3rem, 8vw, 7rem);
|
|
29
|
+
border-bottom: $nb-border-width-lg solid var(--nb-border-color);
|
|
30
|
+
|
|
31
|
+
.text-uppercase {
|
|
32
|
+
display: inline-block;
|
|
33
|
+
font-family: $nb-font-mono;
|
|
34
|
+
font-weight: 700;
|
|
35
|
+
letter-spacing: 0.08em;
|
|
36
|
+
background: #111111;
|
|
37
|
+
color: var(--nb-accent-yellow);
|
|
38
|
+
padding: 0.4rem 0.8rem;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
.hero-title {
|
|
43
|
+
font-family: $nb-font-display;
|
|
44
|
+
font-weight: 900;
|
|
45
|
+
font-size: clamp(2.75rem, 8vw, 6rem);
|
|
46
|
+
line-height: 0.92;
|
|
47
|
+
letter-spacing: -0.04em;
|
|
48
|
+
margin: 0;
|
|
49
|
+
|
|
50
|
+
.text-accent {
|
|
51
|
+
background: #111111;
|
|
52
|
+
color: var(--nb-accent-yellow);
|
|
53
|
+
padding: 0 0.1em;
|
|
54
|
+
box-decoration-break: clone;
|
|
55
|
+
-webkit-box-decoration-break: clone;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// Hero CTAs use Bootstrap `.d-grid.gap-3` (full-width stacked buttons) in the
|
|
60
|
+
// markup. The only theme-specific bit is the slight rightward offset on large
|
|
61
|
+
// screens that gives the split hero its asymmetry.
|
|
62
|
+
.hero-actions {
|
|
63
|
+
@media (min-width: 992px) { margin-left: 1.5rem; }
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
// ============================================
|
|
67
|
+
// Trusted-by — framed marquee strip
|
|
68
|
+
// ============================================
|
|
69
|
+
.logo-strip { padding: clamp(2.5rem, 6vw, 4rem) 0; }
|
|
70
|
+
.logo-strip-box {
|
|
71
|
+
position: relative;
|
|
72
|
+
padding: 2rem 0 1.75rem;
|
|
73
|
+
background: var(--nb-surface);
|
|
74
|
+
@include nb-border();
|
|
75
|
+
@include nb-shadow(md);
|
|
76
|
+
overflow: hidden;
|
|
77
|
+
}
|
|
78
|
+
.logo-strip-label {
|
|
79
|
+
position: absolute;
|
|
80
|
+
top: 0;
|
|
81
|
+
left: 0;
|
|
82
|
+
font-family: $nb-font-mono;
|
|
83
|
+
font-weight: 700;
|
|
84
|
+
font-size: 0.75rem;
|
|
85
|
+
letter-spacing: 0.08em;
|
|
86
|
+
text-transform: uppercase;
|
|
87
|
+
background: #111111;
|
|
88
|
+
color: var(--nb-accent-yellow);
|
|
89
|
+
padding: 0.3rem 0.7rem;
|
|
90
|
+
z-index: 5;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
// ============================================
|
|
94
|
+
// Showcase — alternating offset rows
|
|
95
|
+
// ============================================
|
|
96
|
+
.showcase { padding: clamp(3rem, 8vw, 6rem) 0; }
|
|
97
|
+
.showcase-list { display: flex; flex-direction: column; gap: 2rem; }
|
|
98
|
+
.showcase-row {
|
|
99
|
+
display: grid;
|
|
100
|
+
// Number column fixed; text column sized to content so it sits next to the
|
|
101
|
+
// number instead of stretching across the row (which left an awkward gap).
|
|
102
|
+
grid-template-columns: minmax(120px, 180px) minmax(auto, 60ch);
|
|
103
|
+
gap: 2.5rem;
|
|
104
|
+
align-items: center;
|
|
105
|
+
justify-content: start;
|
|
106
|
+
|
|
107
|
+
@media (max-width: 767.98px) { grid-template-columns: 1fr; gap: 1rem; }
|
|
108
|
+
|
|
109
|
+
// Flipped rows: number moves to the right, the whole pair sits to the right edge.
|
|
110
|
+
&--flip {
|
|
111
|
+
@media (min-width: 768px) {
|
|
112
|
+
grid-template-columns: minmax(auto, 60ch) minmax(120px, 180px);
|
|
113
|
+
justify-content: end;
|
|
114
|
+
.showcase-num { order: 2; }
|
|
115
|
+
.showcase-body { order: 1; }
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
.showcase-num {
|
|
120
|
+
font-family: $nb-font-display;
|
|
121
|
+
font-weight: 900;
|
|
122
|
+
font-size: clamp(3rem, 9vw, 6rem);
|
|
123
|
+
line-height: 1;
|
|
124
|
+
display: flex;
|
|
125
|
+
align-items: center;
|
|
126
|
+
justify-content: center;
|
|
127
|
+
aspect-ratio: 1;
|
|
128
|
+
@include nb-border($nb-border-width-lg);
|
|
129
|
+
@include nb-shadow(lg);
|
|
130
|
+
// Color comes from the Bootstrap .text-bg-* utility on the element.
|
|
131
|
+
}
|
|
132
|
+
.showcase-body { max-width: 60ch; }
|
|
133
|
+
.showcase-title {
|
|
134
|
+
font-family: $nb-font-display;
|
|
135
|
+
font-weight: 800;
|
|
136
|
+
font-size: clamp(1.5rem, 3.5vw, 2.25rem);
|
|
137
|
+
letter-spacing: -0.02em;
|
|
138
|
+
margin-bottom: 0.75rem;
|
|
139
|
+
}
|
|
140
|
+
.showcase-desc { font-size: 1.1rem; margin: 0; color: var(--bs-body-color); }
|
|
141
|
+
|
|
142
|
+
// ============================================
|
|
143
|
+
// Steps (features) — numbered .card blocks
|
|
144
|
+
// ============================================
|
|
145
|
+
.steps {
|
|
146
|
+
padding: clamp(3rem, 8vw, 6rem) 0;
|
|
147
|
+
border-top: $nb-border-width-lg solid var(--nb-border-color);
|
|
148
|
+
border-bottom: $nb-border-width-lg solid var(--nb-border-color);
|
|
149
|
+
}
|
|
150
|
+
.step-card { // sits on .card (gets the neobrutalist frame from the card component)
|
|
151
|
+
.card-body { padding: 1.75rem; }
|
|
152
|
+
}
|
|
153
|
+
.step-card-top {
|
|
154
|
+
display: flex;
|
|
155
|
+
align-items: center;
|
|
156
|
+
justify-content: space-between;
|
|
157
|
+
margin-bottom: 1.25rem;
|
|
158
|
+
}
|
|
159
|
+
.step-card-num { font-family: $nb-font-display; font-weight: 900; font-size: 2.5rem; line-height: 1; }
|
|
160
|
+
.step-card-icon {
|
|
161
|
+
font-size: 1.75rem;
|
|
162
|
+
width: 3.25rem;
|
|
163
|
+
height: 3.25rem;
|
|
164
|
+
display: inline-flex;
|
|
165
|
+
align-items: center;
|
|
166
|
+
justify-content: center;
|
|
167
|
+
background: var(--nb-accent-yellow);
|
|
168
|
+
color: #111111;
|
|
169
|
+
@include nb-border($nb-border-width-sm);
|
|
170
|
+
}
|
|
171
|
+
.step-card-title { font-family: $nb-font-display; font-weight: 800; font-size: 1.5rem; margin-bottom: 0.5rem; }
|
|
172
|
+
.step-card-desc { margin: 0; color: var(--bs-body-color); }
|
|
173
|
+
|
|
174
|
+
// ============================================
|
|
175
|
+
// Stats — oversized color-block cells (.text-bg-* gives the fill)
|
|
176
|
+
// ============================================
|
|
177
|
+
.stats { padding: clamp(3rem, 8vw, 6rem) 0; }
|
|
178
|
+
.stats-grid {
|
|
179
|
+
display: grid;
|
|
180
|
+
grid-template-columns: repeat(4, 1fr);
|
|
181
|
+
gap: 1.5rem;
|
|
182
|
+
|
|
183
|
+
@media (max-width: 991.98px) { grid-template-columns: repeat(2, 1fr); }
|
|
184
|
+
@media (max-width: 479.98px) { grid-template-columns: 1fr; }
|
|
185
|
+
}
|
|
186
|
+
.stat-block {
|
|
187
|
+
display: flex;
|
|
188
|
+
flex-direction: column;
|
|
189
|
+
padding: 1.75rem;
|
|
190
|
+
@include nb-border($nb-border-width-lg);
|
|
191
|
+
@include nb-shadow(lg);
|
|
192
|
+
@include nb-press($nb-shadow-offset-lg); // press matched to the lg resting shadow
|
|
193
|
+
}
|
|
194
|
+
.stat-block-num { font-family: $nb-font-display; font-weight: 900; font-size: clamp(2.5rem, 6vw, 3.5rem); line-height: 1; }
|
|
195
|
+
.stat-block-label { font-weight: 800; font-size: 1.1rem; margin-top: 0.5rem; }
|
|
196
|
+
.stat-block-sub { font-family: $nb-font-mono; font-size: 0.8rem; margin-top: 0.25rem; }
|
|
197
|
+
|
|
198
|
+
// ============================================
|
|
199
|
+
// CTA — full-bleed ink panel
|
|
200
|
+
// ============================================
|
|
201
|
+
.cta { padding: clamp(3rem, 8vw, 6rem) 0; }
|
|
202
|
+
.cta-panel {
|
|
203
|
+
background: #111111;
|
|
204
|
+
color: #FFFEF2;
|
|
205
|
+
padding: clamp(2.5rem, 6vw, 4.5rem);
|
|
206
|
+
text-align: center;
|
|
207
|
+
// Frame + offset shadow in the accent (not ink) so both read against the dark panel.
|
|
208
|
+
border: $nb-border-width-lg solid var(--nb-accent-yellow);
|
|
209
|
+
box-shadow: #{$nb-shadow-offset-lg} #{$nb-shadow-offset-lg} 0 var(--nb-accent-yellow);
|
|
210
|
+
}
|
|
211
|
+
.cta-title {
|
|
212
|
+
font-family: $nb-font-display;
|
|
213
|
+
font-weight: 900;
|
|
214
|
+
font-size: clamp(2rem, 6vw, 4rem);
|
|
215
|
+
line-height: 1;
|
|
216
|
+
letter-spacing: -0.03em;
|
|
217
|
+
margin-bottom: 1.25rem;
|
|
218
|
+
|
|
219
|
+
.text-accent {
|
|
220
|
+
background: var(--nb-accent-yellow);
|
|
221
|
+
color: #111111;
|
|
222
|
+
padding: 0 0.1em;
|
|
223
|
+
box-decoration-break: clone;
|
|
224
|
+
-webkit-box-decoration-break: clone;
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
.cta-desc { font-size: 1.25rem; max-width: 50ch; margin: 0 auto 2rem; opacity: 0.85; }
|
|
@@ -0,0 +1,267 @@
|
|
|
1
|
+
// Neobrutalism Theme — Pricing page-specific CSS
|
|
2
|
+
// Styles the neobrutalist pricing override. Class names are UNIVERSAL (no theme
|
|
3
|
+
// prefix) so the markup is swappable across themes. Compiles to its own bundle
|
|
4
|
+
// (pages/pricing/index.neobrutalism.bundle.css). See docs/themes.md.
|
|
5
|
+
@use 'config' as *;
|
|
6
|
+
@import 'css/base/mixins';
|
|
7
|
+
|
|
8
|
+
// Section heading (also defined in homepage bundle; page bundles are independent)
|
|
9
|
+
.section-head { max-width: 60ch; }
|
|
10
|
+
.section-title {
|
|
11
|
+
font-family: $nb-font-display;
|
|
12
|
+
font-weight: 900;
|
|
13
|
+
font-size: clamp(2rem, 5vw, 3.5rem);
|
|
14
|
+
letter-spacing: -0.03em;
|
|
15
|
+
line-height: 1;
|
|
16
|
+
margin: 0;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
// ============================================
|
|
20
|
+
// Hero
|
|
21
|
+
// ============================================
|
|
22
|
+
.pricing-hero {
|
|
23
|
+
text-align: center;
|
|
24
|
+
padding: clamp(3rem, 7vw, 5rem) 0 clamp(2rem, 4vw, 3rem);
|
|
25
|
+
}
|
|
26
|
+
.pricing-title {
|
|
27
|
+
font-family: $nb-font-display;
|
|
28
|
+
font-weight: 900;
|
|
29
|
+
font-size: clamp(2.5rem, 7vw, 5rem);
|
|
30
|
+
line-height: 0.95;
|
|
31
|
+
letter-spacing: -0.03em;
|
|
32
|
+
margin-bottom: 1rem;
|
|
33
|
+
|
|
34
|
+
.text-accent {
|
|
35
|
+
background: var(--nb-accent-yellow);
|
|
36
|
+
color: #111111;
|
|
37
|
+
padding: 0 0.1em;
|
|
38
|
+
box-decoration-break: clone;
|
|
39
|
+
-webkit-box-decoration-break: clone;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// ============================================
|
|
44
|
+
// Billing toggle — hard square segmented control
|
|
45
|
+
// ============================================
|
|
46
|
+
.billing-toggle {
|
|
47
|
+
display: flex;
|
|
48
|
+
justify-content: center;
|
|
49
|
+
margin: 0 auto 1.5rem;
|
|
50
|
+
width: 100%;
|
|
51
|
+
max-width: 420px;
|
|
52
|
+
@include nb-border();
|
|
53
|
+
@include nb-shadow(md);
|
|
54
|
+
}
|
|
55
|
+
.billing-option {
|
|
56
|
+
flex: 1;
|
|
57
|
+
text-align: center;
|
|
58
|
+
padding: 0.85rem 1rem;
|
|
59
|
+
font-family: $nb-font-display;
|
|
60
|
+
font-weight: 700;
|
|
61
|
+
cursor: pointer;
|
|
62
|
+
background: var(--nb-surface);
|
|
63
|
+
color: var(--bs-body-color);
|
|
64
|
+
transition: $nb-transition;
|
|
65
|
+
margin: 0;
|
|
66
|
+
|
|
67
|
+
& + .billing-option { border-left: $nb-border-width solid var(--nb-border-color); }
|
|
68
|
+
|
|
69
|
+
.btn-check:checked + & {
|
|
70
|
+
background: #111111;
|
|
71
|
+
color: var(--nb-accent-yellow);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
.billing-save {
|
|
75
|
+
display: inline-block;
|
|
76
|
+
font-family: $nb-font-mono;
|
|
77
|
+
font-size: 0.65rem;
|
|
78
|
+
font-weight: 700;
|
|
79
|
+
text-transform: uppercase;
|
|
80
|
+
background: var(--nb-accent-yellow);
|
|
81
|
+
color: #111111;
|
|
82
|
+
padding: 0.1rem 0.35rem;
|
|
83
|
+
margin-left: 0.35rem;
|
|
84
|
+
vertical-align: middle;
|
|
85
|
+
}
|
|
86
|
+
.btn-check:checked + .billing-option .billing-save { background: var(--nb-accent-yellow); }
|
|
87
|
+
|
|
88
|
+
// ============================================
|
|
89
|
+
// Plan grid — popular plan emphasized (equal height, same baseline)
|
|
90
|
+
// ============================================
|
|
91
|
+
.pricing-plan-grid {
|
|
92
|
+
display: grid;
|
|
93
|
+
grid-template-columns: repeat(4, 1fr);
|
|
94
|
+
gap: 1.5rem;
|
|
95
|
+
align-items: stretch; // all cards fill the row's full height → equal height
|
|
96
|
+
margin-bottom: 2rem;
|
|
97
|
+
|
|
98
|
+
@media (max-width: 1199.98px) { grid-template-columns: repeat(2, 1fr); }
|
|
99
|
+
@media (max-width: 575.98px) { grid-template-columns: 1fr; }
|
|
100
|
+
}
|
|
101
|
+
.pricing-plan { // sits on .card (frame/shadow come from the card component)
|
|
102
|
+
position: relative;
|
|
103
|
+
display: flex;
|
|
104
|
+
flex-direction: column; // lets the features list grow so footers align
|
|
105
|
+
padding: 1.75rem 1.5rem;
|
|
106
|
+
// No press interaction on the card itself — it's not clickable. Only the CTA
|
|
107
|
+
// button inside reacts to the pointer.
|
|
108
|
+
|
|
109
|
+
// Features sit directly under the divider (top of the lower half), not pushed
|
|
110
|
+
// to the bottom. Cards stay equal height via the grid's align-items: stretch.
|
|
111
|
+
|
|
112
|
+
// Popular plan: accent fill + thicker frame. Same height + same press as the others.
|
|
113
|
+
&--popular {
|
|
114
|
+
background: var(--nb-accent-yellow);
|
|
115
|
+
color: #111111;
|
|
116
|
+
@include nb-border($nb-border-width-lg);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
.pricing-plan-flag {
|
|
120
|
+
position: absolute;
|
|
121
|
+
top: 0;
|
|
122
|
+
right: 0;
|
|
123
|
+
transform: translateY(-50%);
|
|
124
|
+
font-family: $nb-font-mono;
|
|
125
|
+
font-weight: 700;
|
|
126
|
+
font-size: 0.7rem;
|
|
127
|
+
text-transform: uppercase;
|
|
128
|
+
letter-spacing: 0.05em;
|
|
129
|
+
background: #111111;
|
|
130
|
+
color: var(--nb-accent-yellow);
|
|
131
|
+
padding: 0.3rem 0.6rem;
|
|
132
|
+
}
|
|
133
|
+
.pricing-plan-name {
|
|
134
|
+
font-family: $nb-font-display;
|
|
135
|
+
font-weight: 900;
|
|
136
|
+
font-size: 1.75rem;
|
|
137
|
+
margin-bottom: 0.15rem;
|
|
138
|
+
}
|
|
139
|
+
.pricing-plan-tagline {
|
|
140
|
+
font-family: $nb-font-mono;
|
|
141
|
+
font-size: 0.8rem;
|
|
142
|
+
opacity: 0.7;
|
|
143
|
+
margin-bottom: 1rem;
|
|
144
|
+
}
|
|
145
|
+
.pricing-plan-price {
|
|
146
|
+
display: flex;
|
|
147
|
+
align-items: baseline;
|
|
148
|
+
gap: 0.1rem;
|
|
149
|
+
margin-bottom: 0.25rem;
|
|
150
|
+
}
|
|
151
|
+
.pricing-plan-currency { font-family: $nb-font-display; font-weight: 900; font-size: 1.5rem; }
|
|
152
|
+
.pricing-plan-amount { font-family: $nb-font-display; font-weight: 900; font-size: 3rem; line-height: 1; }
|
|
153
|
+
.pricing-plan-per { font-family: $nb-font-mono; font-size: 0.85rem; opacity: 0.7; }
|
|
154
|
+
.pricing-plan-ppu { font-family: $nb-font-mono; font-size: 0.75rem; opacity: 0.7; margin-bottom: 1.25rem; min-height: 1.2em; }
|
|
155
|
+
.pricing-plan-billing { font-size: 0.8rem; text-align: center; opacity: 0.75; margin-bottom: 0.4rem; }
|
|
156
|
+
.pricing-plan-guarantee { font-size: 0.8rem; text-align: center; opacity: 0.8; margin-bottom: 1rem; }
|
|
157
|
+
.pricing-plan-rule {
|
|
158
|
+
border: 0;
|
|
159
|
+
border-top: $nb-border-width-sm solid currentColor;
|
|
160
|
+
opacity: 0.25;
|
|
161
|
+
margin: 0 0 1.25rem;
|
|
162
|
+
}
|
|
163
|
+
.pricing-plan-features {
|
|
164
|
+
list-style: none;
|
|
165
|
+
padding: 0;
|
|
166
|
+
margin: 0;
|
|
167
|
+
display: flex;
|
|
168
|
+
flex-direction: column;
|
|
169
|
+
gap: 0.6rem;
|
|
170
|
+
|
|
171
|
+
li { display: flex; align-items: flex-start; gap: 0.6rem; font-size: 0.95rem; font-weight: 500; }
|
|
172
|
+
|
|
173
|
+
// Spacing when a second (additional-features) list follows the inherit label
|
|
174
|
+
& + .pricing-plan-inherit { margin-top: 1rem; }
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
// "Everything in <plan>, and more:" / "What you get:" tier-inheritance label
|
|
178
|
+
.pricing-plan-inherit {
|
|
179
|
+
font-family: $nb-font-mono;
|
|
180
|
+
font-size: 0.8rem;
|
|
181
|
+
opacity: 0.7;
|
|
182
|
+
margin: 0 0 0.6rem;
|
|
183
|
+
|
|
184
|
+
strong { font-weight: 700; opacity: 1; }
|
|
185
|
+
}
|
|
186
|
+
.pricing-plan-feature-icon {
|
|
187
|
+
flex-shrink: 0;
|
|
188
|
+
width: 1.5rem;
|
|
189
|
+
height: 1.5rem;
|
|
190
|
+
display: inline-flex;
|
|
191
|
+
align-items: center;
|
|
192
|
+
justify-content: center;
|
|
193
|
+
background: var(--nb-accent-green);
|
|
194
|
+
color: #111111;
|
|
195
|
+
@include nb-border($nb-border-width-sm);
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
// Enterprise strip (sits on .card)
|
|
199
|
+
.enterprise-panel {
|
|
200
|
+
display: flex;
|
|
201
|
+
flex-direction: row;
|
|
202
|
+
align-items: center;
|
|
203
|
+
justify-content: space-between;
|
|
204
|
+
gap: 1.5rem;
|
|
205
|
+
padding: 1.75rem 2rem;
|
|
206
|
+
flex-wrap: wrap;
|
|
207
|
+
}
|
|
208
|
+
.enterprise-panel-title { font-family: $nb-font-display; font-weight: 900; font-size: 1.75rem; margin-bottom: 0.25rem; }
|
|
209
|
+
|
|
210
|
+
// ============================================
|
|
211
|
+
// Stats / social proof (.text-bg-* gives the fill)
|
|
212
|
+
// ============================================
|
|
213
|
+
.stats { padding: clamp(3rem, 8vw, 6rem) 0; }
|
|
214
|
+
.stats-grid {
|
|
215
|
+
display: grid;
|
|
216
|
+
grid-template-columns: repeat(4, 1fr);
|
|
217
|
+
gap: 1.5rem;
|
|
218
|
+
|
|
219
|
+
@media (max-width: 991.98px) { grid-template-columns: repeat(2, 1fr); }
|
|
220
|
+
@media (max-width: 479.98px) { grid-template-columns: 1fr; }
|
|
221
|
+
}
|
|
222
|
+
.stat-block {
|
|
223
|
+
display: flex;
|
|
224
|
+
flex-direction: column;
|
|
225
|
+
padding: 1.75rem;
|
|
226
|
+
@include nb-border($nb-border-width-lg);
|
|
227
|
+
@include nb-shadow(lg);
|
|
228
|
+
@include nb-press($nb-shadow-offset-lg); // press matched to the lg resting shadow
|
|
229
|
+
}
|
|
230
|
+
.stat-block-num { font-family: $nb-font-display; font-weight: 900; font-size: clamp(2.5rem, 6vw, 3.5rem); line-height: 1; }
|
|
231
|
+
.stat-block-label { font-weight: 800; font-size: 1.1rem; margin-top: 0.5rem; }
|
|
232
|
+
|
|
233
|
+
// ============================================
|
|
234
|
+
// FAQ
|
|
235
|
+
// ============================================
|
|
236
|
+
.faq { padding: clamp(3rem, 8vw, 6rem) 0; }
|
|
237
|
+
|
|
238
|
+
// ============================================
|
|
239
|
+
// CTA — full-bleed ink panel
|
|
240
|
+
// ============================================
|
|
241
|
+
.cta { padding: clamp(3rem, 8vw, 6rem) 0; }
|
|
242
|
+
.cta-panel {
|
|
243
|
+
background: #111111;
|
|
244
|
+
color: #FFFEF2;
|
|
245
|
+
padding: clamp(2.5rem, 6vw, 4.5rem);
|
|
246
|
+
text-align: center;
|
|
247
|
+
// Frame + offset shadow in the accent (not ink) so both read against the dark panel.
|
|
248
|
+
border: $nb-border-width-lg solid var(--nb-accent-yellow);
|
|
249
|
+
box-shadow: #{$nb-shadow-offset-lg} #{$nb-shadow-offset-lg} 0 var(--nb-accent-yellow);
|
|
250
|
+
}
|
|
251
|
+
.cta-title {
|
|
252
|
+
font-family: $nb-font-display;
|
|
253
|
+
font-weight: 900;
|
|
254
|
+
font-size: clamp(2rem, 6vw, 4rem);
|
|
255
|
+
line-height: 1;
|
|
256
|
+
letter-spacing: -0.03em;
|
|
257
|
+
margin-bottom: 1.25rem;
|
|
258
|
+
|
|
259
|
+
.text-accent {
|
|
260
|
+
background: var(--nb-accent-yellow);
|
|
261
|
+
color: #111111;
|
|
262
|
+
padding: 0 0.1em;
|
|
263
|
+
box-decoration-break: clone;
|
|
264
|
+
-webkit-box-decoration-break: clone;
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
.cta-desc { font-size: 1.25rem; max-width: 50ch; margin: 0 auto 2rem; opacity: 0.85; }
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
// /test — Theme (neobrutalism) page JS — the #theme layer.
|
|
2
|
+
// Runs AFTER #main, BEFORE #project. Turns the "js-theme" dot green.
|
|
3
|
+
export default ({ manager, options }) => {
|
|
4
|
+
const dot = document.querySelector('.layer-dot[data-layer="js-theme"]');
|
|
5
|
+
if (dot) {
|
|
6
|
+
dot.style.background = '#30a46c'; // green
|
|
7
|
+
}
|
|
8
|
+
console.log('[test-layer] #theme JS ran → js-theme dot green');
|
|
9
|
+
};
|