ultimate-jekyll-manager 1.7.2 → 1.8.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/.claude/scheduled_tasks.lock +1 -0
- package/CHANGELOG.md +61 -1
- package/CLAUDE.md +36 -15
- package/README.md +4 -2
- package/TODO-AUTH-TESTING.md +1 -1
- package/dist/assets/themes/newsflash/README.md +58 -0
- package/dist/assets/themes/newsflash/_config.scss +138 -0
- package/dist/assets/themes/newsflash/_theme.js +27 -0
- package/dist/assets/themes/newsflash/_theme.scss +37 -0
- package/dist/assets/themes/newsflash/css/base/_mixins.scss +50 -0
- package/dist/assets/themes/newsflash/css/base/_root.scss +134 -0
- package/dist/assets/themes/newsflash/css/base/_typography.scss +49 -0
- package/dist/assets/themes/newsflash/css/base/_utilities.scss +58 -0
- package/dist/assets/themes/newsflash/css/components/_badges.scss +65 -0
- package/dist/assets/themes/newsflash/css/components/_buttons.scss +139 -0
- package/dist/assets/themes/newsflash/css/components/_cards.scss +52 -0
- package/dist/assets/themes/newsflash/css/components/_editorial.scss +182 -0
- package/dist/assets/themes/newsflash/css/components/_forms.scss +75 -0
- package/dist/assets/themes/newsflash/css/components/_infinite-scroll.scss +102 -0
- package/dist/assets/themes/newsflash/css/components/_panels.scss +91 -0
- package/dist/assets/themes/newsflash/css/components/_ticker.scss +70 -0
- package/dist/assets/themes/newsflash/css/layout/_general.scss +264 -0
- package/dist/assets/themes/newsflash/css/layout/_navigation.scss +164 -0
- package/dist/assets/themes/newsflash/js/initialize-tooltips.js +20 -0
- package/dist/assets/themes/newsflash/js/masthead-scroll.js +29 -0
- package/dist/assets/themes/newsflash/pages/404/index.scss +27 -0
- package/dist/assets/themes/newsflash/pages/about/index.scss +70 -0
- package/dist/assets/themes/newsflash/pages/blog/index.scss +17 -0
- package/dist/assets/themes/newsflash/pages/blog/post.js +29 -0
- package/dist/assets/themes/newsflash/pages/blog/post.scss +164 -0
- package/dist/assets/themes/newsflash/pages/index.scss +159 -0
- package/dist/assets/themes/newsflash/pages/pricing/index.scss +194 -0
- package/dist/assets/themes/newsflash/pages/test/libraries/layers/index.js +9 -0
- package/dist/assets/themes/newsflash/pages/test/libraries/layers/index.scss +7 -0
- package/dist/commands/blogify.js +6 -3
- package/dist/commands/test.js +34 -5
- package/dist/defaults/CLAUDE.md +17 -4
- package/dist/defaults/dist/_includes/core/pricing/resolve-plan.html +59 -0
- package/dist/defaults/dist/_includes/themes/classy/frontend/sections/footer.html +20 -3
- package/dist/defaults/dist/_layouts/themes/classy/admin/core/minimal-viewport-locked.html +1 -1
- package/dist/defaults/dist/_layouts/themes/classy/admin/core/minimal.html +1 -1
- package/dist/defaults/dist/_layouts/themes/classy/frontend/pages/pricing.html +5 -40
- package/dist/defaults/dist/_layouts/themes/neobrutalism/frontend/pages/pricing.html +33 -34
- package/dist/defaults/dist/_layouts/themes/newsflash/frontend/core/base.html +61 -0
- package/dist/defaults/dist/_layouts/themes/newsflash/frontend/pages/404.html +86 -0
- package/dist/defaults/dist/_layouts/themes/newsflash/frontend/pages/about.html +353 -0
- package/dist/defaults/dist/_layouts/themes/newsflash/frontend/pages/blog/categories/category.html +105 -0
- package/dist/defaults/dist/_layouts/themes/newsflash/frontend/pages/blog/categories/index.html +93 -0
- package/dist/defaults/dist/_layouts/themes/newsflash/frontend/pages/blog/index.html +373 -0
- package/dist/defaults/dist/_layouts/themes/newsflash/frontend/pages/blog/post.html +289 -0
- package/dist/defaults/dist/_layouts/themes/newsflash/frontend/pages/blog/tags/index.html +90 -0
- package/dist/defaults/dist/_layouts/themes/newsflash/frontend/pages/blog/tags/tag.html +107 -0
- package/dist/defaults/dist/_layouts/themes/newsflash/frontend/pages/contact.html +340 -0
- package/dist/defaults/dist/_layouts/themes/newsflash/frontend/pages/index.html +522 -0
- package/dist/defaults/dist/_layouts/themes/newsflash/frontend/pages/pricing.html +485 -0
- package/dist/defaults/dist/_layouts/themes/newsflash/frontend/pages/team/index.html +207 -0
- package/dist/defaults/dist/_layouts/themes/newsflash/frontend/pages/team/member.html +134 -0
- package/dist/defaults/test/README.md +4 -0
- package/dist/gulp/tasks/jekyll.js +4 -2
- package/dist/test/runner.js +50 -3
- package/dist/test/suites/build/attach-log-file.test.js +102 -0
- package/dist/test/suites/build/theme-contract.test.js +173 -0
- package/dist/test/utils/extended-mode-warning.js +13 -0
- package/dist/utils/attach-log-file.js +70 -43
- package/docs/appearance.md +1 -0
- package/docs/assets.md +9 -0
- package/docs/audit.md +27 -7
- package/docs/build-system.md +57 -0
- package/docs/common-mistakes.md +15 -0
- package/docs/{project-structure.md → directory-structure.md} +1 -1
- package/docs/environment-detection.md +1 -1
- package/docs/javascript-libraries.md +38 -1
- package/docs/layouts-and-pages.md +146 -0
- package/docs/local-development.md +1 -8
- package/docs/logging.md +30 -0
- package/docs/migration.md +131 -0
- package/docs/no-inline-scripts.md +304 -0
- package/docs/purgecss.md +164 -0
- package/docs/seo.md +131 -4
- package/docs/templating.md +23 -0
- package/docs/test-boot-layer.md +1 -1
- package/docs/test-framework.md +56 -8
- package/docs/themes.md +254 -13
- package/logs/test.log +111 -0
- package/package.json +1 -1
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
// Newsflash Theme — Navigation
|
|
2
|
+
// The inherited nav markup (.navbar-wrapper > .navbar.navbar-floating) is a
|
|
3
|
+
// floating glass pill in Classy. Here it becomes the MASTHEAD: a sticky,
|
|
4
|
+
// blurred-paper bar closed by a hairline ink rule, serif brand on the left,
|
|
5
|
+
// uppercase pill links in the middle. The ticker (in base.html) sits above it
|
|
6
|
+
// in-flow and scrolls away; the masthead stays.
|
|
7
|
+
|
|
8
|
+
.navbar-wrapper {
|
|
9
|
+
position: sticky;
|
|
10
|
+
top: 0;
|
|
11
|
+
left: 0;
|
|
12
|
+
right: 0;
|
|
13
|
+
z-index: 1030;
|
|
14
|
+
|
|
15
|
+
.navbar {
|
|
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-top: 0.75rem;
|
|
27
|
+
padding-bottom: 0.75rem;
|
|
28
|
+
background: var(--nf-paper-translucent) !important;
|
|
29
|
+
backdrop-filter: blur(12px);
|
|
30
|
+
-webkit-backdrop-filter: blur(12px);
|
|
31
|
+
border: 0;
|
|
32
|
+
border-bottom: var(--nf-border);
|
|
33
|
+
transition: box-shadow 0.25s ease;
|
|
34
|
+
|
|
35
|
+
// Soft shadow only once scrolled (set by js/masthead-scroll.js)
|
|
36
|
+
&.scrolled {
|
|
37
|
+
box-shadow: 0 8px 24px -16px rgba(23, 19, 16, 0.4);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
.container,
|
|
41
|
+
.container-fluid {
|
|
42
|
+
padding: 0;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// Brand: the serif masthead title
|
|
47
|
+
.navbar-brand {
|
|
48
|
+
font-family: $nf-font-display;
|
|
49
|
+
font-optical-sizing: auto;
|
|
50
|
+
font-weight: 600;
|
|
51
|
+
font-size: 1.5rem;
|
|
52
|
+
letter-spacing: -0.02em;
|
|
53
|
+
|
|
54
|
+
.brand-logo { height: 32px; width: auto; margin-right: 0.5rem; }
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// Nav links: uppercase grotesk pills. Hover fills ink; active fills vermilion.
|
|
58
|
+
.navbar-nav .nav-link {
|
|
59
|
+
font-weight: 700;
|
|
60
|
+
font-size: 0.82rem;
|
|
61
|
+
text-transform: uppercase;
|
|
62
|
+
letter-spacing: 0.05em;
|
|
63
|
+
padding: 0.55rem 0.9rem;
|
|
64
|
+
margin: 0 0.1rem;
|
|
65
|
+
border-radius: 50rem;
|
|
66
|
+
color: var(--bs-body-color);
|
|
67
|
+
transition: $nf-transition;
|
|
68
|
+
|
|
69
|
+
// Hover + active need !important on color: the nav include puts Bootstrap's
|
|
70
|
+
// .text-body utility (!important) on every link, which otherwise wins and
|
|
71
|
+
// leaves ink text on the ink hover fill (unreadable).
|
|
72
|
+
&:hover {
|
|
73
|
+
background: var(--nf-ink);
|
|
74
|
+
color: var(--nf-paper) !important;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// Active = vermilion pill.
|
|
78
|
+
&.active,
|
|
79
|
+
&.active.text-body {
|
|
80
|
+
background: var(--nf-accent-interactive) !important;
|
|
81
|
+
color: var(--nf-accent-interactive-ink) !important;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// Mobile toggle: a pill ink-framed button
|
|
86
|
+
.navbar-toggler {
|
|
87
|
+
border-radius: 50rem;
|
|
88
|
+
padding: 0.35rem 0.6rem;
|
|
89
|
+
background: transparent;
|
|
90
|
+
@include nf-border();
|
|
91
|
+
transition: $nf-transition;
|
|
92
|
+
|
|
93
|
+
&:hover { background: var(--nf-paper-2); }
|
|
94
|
+
&:focus { box-shadow: 0 0 0 3px var(--nf-volt); }
|
|
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%2823,19,16,1%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2.5' 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%28242,232,217,1%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2.5' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e");
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
// Mobile collapsed menu becomes a framed paper drawer
|
|
108
|
+
@media (max-width: 991.98px) {
|
|
109
|
+
.navbar-collapse {
|
|
110
|
+
margin-top: 0.75rem;
|
|
111
|
+
padding: 0.85rem;
|
|
112
|
+
background: var(--bs-card-bg);
|
|
113
|
+
border-radius: var(--bs-border-radius-lg);
|
|
114
|
+
@include nf-border();
|
|
115
|
+
@include nf-shadow-pop();
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
// ============================================
|
|
120
|
+
// Dropdown menus — framed paper panels
|
|
121
|
+
// ============================================
|
|
122
|
+
// Doubled selector: page bundles re-emit Bootstrap's .dropdown-menu AFTER the
|
|
123
|
+
// main bundle, and its `--bs-dropdown-padding-x: 0` strips the inset — the
|
|
124
|
+
// highlighted item pills end up pressed edge-to-edge against the panel.
|
|
125
|
+
.dropdown-menu.dropdown-menu {
|
|
126
|
+
background: var(--bs-card-bg);
|
|
127
|
+
border-radius: var(--bs-border-radius);
|
|
128
|
+
@include nf-border();
|
|
129
|
+
@include nf-shadow-pop();
|
|
130
|
+
padding: 0.4rem;
|
|
131
|
+
margin-top: 0.6rem;
|
|
132
|
+
|
|
133
|
+
.dropdown-item {
|
|
134
|
+
border-radius: 50rem;
|
|
135
|
+
font-weight: 600;
|
|
136
|
+
padding: 0.5rem 0.9rem;
|
|
137
|
+
color: var(--bs-body-color);
|
|
138
|
+
|
|
139
|
+
// !important: dropdown items (account dropdown, nav dropdowns) carry
|
|
140
|
+
// text-color utilities from the shared includes — same trap as nav links.
|
|
141
|
+
&:hover,
|
|
142
|
+
&:focus {
|
|
143
|
+
background: var(--nf-ink);
|
|
144
|
+
color: var(--nf-paper) !important;
|
|
145
|
+
|
|
146
|
+
// Child text spans with their own utility colors flip with the item
|
|
147
|
+
[class*="text-"] {
|
|
148
|
+
color: inherit !important;
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
&.active,
|
|
153
|
+
&:active {
|
|
154
|
+
background: var(--nf-accent-interactive);
|
|
155
|
+
color: var(--nf-accent-interactive-ink) !important;
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
.dropdown-divider {
|
|
160
|
+
border-top: 1px solid var(--nf-line);
|
|
161
|
+
opacity: 1;
|
|
162
|
+
margin: 0.4rem 0;
|
|
163
|
+
}
|
|
164
|
+
}
|
|
@@ -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
|
+
// Masthead scroll effect for the Newsflash theme.
|
|
2
|
+
// Toggles a `.scrolled` class on the sticky masthead once the page is scrolled
|
|
3
|
+
// past a threshold; the SCSS turns that into a soft shadow under the bar.
|
|
4
|
+
// Threshold is configurable via the data-nf-scroll-threshold attribute on the navbar.
|
|
5
|
+
export default function setupMastheadScroll() {
|
|
6
|
+
const $navbar = document.querySelector('.navbar-floating');
|
|
7
|
+
if (!$navbar) {
|
|
8
|
+
return;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
const threshold = parseInt($navbar.dataset.nfScrollThreshold, 10) || 8;
|
|
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,27 @@
|
|
|
1
|
+
// Newsflash Theme — 404 page-specific CSS
|
|
2
|
+
// The "correction notice" treatment for
|
|
3
|
+
// (_layouts/themes/newsflash/frontend/pages/404.html).
|
|
4
|
+
// Compiles standalone, so it pulls in the theme tokens + mixins via loadPaths.
|
|
5
|
+
@use 'config' as *;
|
|
6
|
+
@import 'css/base/mixins';
|
|
7
|
+
|
|
8
|
+
// Oversized stroked serif numerals
|
|
9
|
+
.error-code {
|
|
10
|
+
font-family: $nf-font-display;
|
|
11
|
+
font-style: italic;
|
|
12
|
+
font-weight: 900;
|
|
13
|
+
font-size: clamp(5rem, 16vw, 8rem);
|
|
14
|
+
line-height: 1;
|
|
15
|
+
color: transparent;
|
|
16
|
+
-webkit-text-stroke: 2px var(--nf-ink);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
// The rotated "Correction" chip pinned to the notice
|
|
20
|
+
.error-stamp {
|
|
21
|
+
position: absolute;
|
|
22
|
+
top: -0.85rem;
|
|
23
|
+
left: 50%;
|
|
24
|
+
transform: translateX(-50%) rotate(-3deg);
|
|
25
|
+
z-index: 1;
|
|
26
|
+
white-space: nowrap;
|
|
27
|
+
}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
// Newsflash Theme — About page-specific CSS
|
|
2
|
+
// The editorial timeline for
|
|
3
|
+
// (_layouts/themes/newsflash/frontend/pages/about.html).
|
|
4
|
+
// Compiles standalone, so it pulls in the theme tokens + mixins via loadPaths.
|
|
5
|
+
@use 'config' as *;
|
|
6
|
+
@import 'css/base/mixins';
|
|
7
|
+
|
|
8
|
+
// Single-rail editorial timeline: an ink rule down the left, volt year chips
|
|
9
|
+
// hanging on it, entries stepping down the page.
|
|
10
|
+
.timeline {
|
|
11
|
+
position: relative;
|
|
12
|
+
padding-left: 1.5rem;
|
|
13
|
+
border-left: var(--nf-border);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
.timeline-item {
|
|
17
|
+
position: relative;
|
|
18
|
+
display: flex;
|
|
19
|
+
flex-direction: column;
|
|
20
|
+
align-items: flex-start;
|
|
21
|
+
gap: 0.6rem;
|
|
22
|
+
padding-bottom: 2.25rem;
|
|
23
|
+
|
|
24
|
+
&:last-child {
|
|
25
|
+
padding-bottom: 0;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
// The rule marker — a vermilion dot pinned to the rail
|
|
29
|
+
&::before {
|
|
30
|
+
content: "";
|
|
31
|
+
position: absolute;
|
|
32
|
+
left: calc(-1.5rem - 5.75px); // centers the dot on the 1.5px rail
|
|
33
|
+
top: 0.45rem;
|
|
34
|
+
width: 10px;
|
|
35
|
+
height: 10px;
|
|
36
|
+
border-radius: 50%;
|
|
37
|
+
background: var(--bs-primary);
|
|
38
|
+
border: var(--nf-border);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
.timeline-year {
|
|
43
|
+
transform: rotate(-2deg);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// ============================================
|
|
47
|
+
// Reader quotes — letters to the editor
|
|
48
|
+
// ============================================
|
|
49
|
+
.quote-card {
|
|
50
|
+
&::before {
|
|
51
|
+
content: "\201C";
|
|
52
|
+
display: block;
|
|
53
|
+
font-family: $nf-font-display;
|
|
54
|
+
font-weight: 900;
|
|
55
|
+
font-size: 3rem;
|
|
56
|
+
line-height: 0.5;
|
|
57
|
+
color: var(--bs-primary);
|
|
58
|
+
margin-bottom: 0.5rem;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
p {
|
|
62
|
+
font-family: $nf-font-display;
|
|
63
|
+
font-optical-sizing: auto;
|
|
64
|
+
font-style: italic;
|
|
65
|
+
font-weight: 550;
|
|
66
|
+
font-size: 1.15rem;
|
|
67
|
+
letter-spacing: -0.01em;
|
|
68
|
+
line-height: 1.45;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
// Newsflash Theme — Blog index page-specific CSS
|
|
2
|
+
// Small accents for the newspaper front page
|
|
3
|
+
// (_layouts/themes/newsflash/frontend/pages/blog/index.html).
|
|
4
|
+
// Compiles standalone, so it pulls in the theme tokens + mixins via loadPaths.
|
|
5
|
+
@use 'config' as *;
|
|
6
|
+
@import 'css/base/mixins';
|
|
7
|
+
|
|
8
|
+
// The lead-story splash stays planted — only its framed image zooms
|
|
9
|
+
.story-card--lead {
|
|
10
|
+
&:hover {
|
|
11
|
+
transform: none;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
.art-frame {
|
|
15
|
+
aspect-ratio: 16 / 10;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
// Newsflash Theme — Blog post page JS (the #theme layer)
|
|
2
|
+
// Drives the reading-progress bar: fills the fixed top rule as the reader
|
|
3
|
+
// scrolls through the page. NOTE: flat file shape — the post layout sets
|
|
4
|
+
// `asset_path: blog/post`, so this loads as pages/blog/post.js.
|
|
5
|
+
export default ({ manager, options }) => {
|
|
6
|
+
const $bar = document.querySelector('.reading-progress > span');
|
|
7
|
+
if (!$bar) {
|
|
8
|
+
return;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
let ticking = false;
|
|
12
|
+
function update() {
|
|
13
|
+
const $doc = document.documentElement;
|
|
14
|
+
const progress = $doc.scrollTop / ($doc.scrollHeight - $doc.clientHeight);
|
|
15
|
+
$bar.style.transform = `scaleX(${Math.min(Math.max(progress, 0), 1)})`;
|
|
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,164 @@
|
|
|
1
|
+
// Newsflash Theme — Blog post page-specific CSS
|
|
2
|
+
// The editorial article treatment for
|
|
3
|
+
// (_layouts/themes/newsflash/frontend/pages/blog/post.html): reading-progress
|
|
4
|
+
// bar, drop cap, serif crossheads with the vermilion dash, framed in-content
|
|
5
|
+
// images, and the centered pullquote. NOTE: flat file shape — the post layout
|
|
6
|
+
// sets `asset_path: blog/post`, so this compiles to pages/blog/post.<id>.bundle.css.
|
|
7
|
+
// Compiles standalone, so it pulls in the theme tokens + mixins via loadPaths.
|
|
8
|
+
@use 'config' as *;
|
|
9
|
+
@import 'css/base/mixins';
|
|
10
|
+
|
|
11
|
+
// ============================================
|
|
12
|
+
// Reading progress — fixed vermilion rule across the very top
|
|
13
|
+
// ============================================
|
|
14
|
+
// Sits above the sticky masthead (z-index 1030); driven by pages/blog/post.js.
|
|
15
|
+
.reading-progress {
|
|
16
|
+
position: fixed;
|
|
17
|
+
top: 0;
|
|
18
|
+
left: 0;
|
|
19
|
+
right: 0;
|
|
20
|
+
height: 4px;
|
|
21
|
+
z-index: 1040;
|
|
22
|
+
pointer-events: none;
|
|
23
|
+
background: transparent;
|
|
24
|
+
|
|
25
|
+
span {
|
|
26
|
+
display: block;
|
|
27
|
+
height: 100%;
|
|
28
|
+
background: var(--bs-primary);
|
|
29
|
+
transform: scaleX(0);
|
|
30
|
+
transform-origin: left;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// ============================================
|
|
35
|
+
// Article hero — wide cinematic frame
|
|
36
|
+
// ============================================
|
|
37
|
+
.article-hero {
|
|
38
|
+
aspect-ratio: 21 / 10;
|
|
39
|
+
|
|
40
|
+
img {
|
|
41
|
+
height: 100%;
|
|
42
|
+
// Lift the framework's generic .blog-post-image cap (max-height: 480px in
|
|
43
|
+
// the main bundle) — the 21/10 frame is the size authority here, and the
|
|
44
|
+
// cap leaves a blank strip inside the frame on wide viewports.
|
|
45
|
+
max-height: none;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// ============================================
|
|
50
|
+
// Article body — the editorial reading column
|
|
51
|
+
// ============================================
|
|
52
|
+
.blog-post-content {
|
|
53
|
+
font-size: 1.13rem;
|
|
54
|
+
line-height: 1.78;
|
|
55
|
+
|
|
56
|
+
p {
|
|
57
|
+
margin-bottom: 1.5em;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// Drop cap on the opening paragraph
|
|
61
|
+
> p:first-of-type::first-letter {
|
|
62
|
+
font-family: $nf-font-display;
|
|
63
|
+
font-weight: 600;
|
|
64
|
+
font-size: 4.2rem;
|
|
65
|
+
line-height: 0.82;
|
|
66
|
+
color: var(--bs-primary);
|
|
67
|
+
float: left;
|
|
68
|
+
padding: 8px 12px 0 0;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// Serif crossheads with the vermilion dash
|
|
72
|
+
h2, h3 {
|
|
73
|
+
display: flex;
|
|
74
|
+
align-items: center;
|
|
75
|
+
gap: 0.5em;
|
|
76
|
+
font-size: 1.7rem;
|
|
77
|
+
letter-spacing: -0.014em;
|
|
78
|
+
line-height: 1.25;
|
|
79
|
+
margin: 2em 0 0.8em;
|
|
80
|
+
|
|
81
|
+
&::before {
|
|
82
|
+
content: "";
|
|
83
|
+
width: 0.55em;
|
|
84
|
+
height: 0.18em;
|
|
85
|
+
background: var(--bs-primary);
|
|
86
|
+
border-radius: 50rem;
|
|
87
|
+
flex: none;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
h3 {
|
|
92
|
+
font-size: 1.35rem;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
// In-content images get the editorial frame
|
|
96
|
+
img {
|
|
97
|
+
border: var(--nf-border);
|
|
98
|
+
border-radius: $nf-radius;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
figcaption {
|
|
102
|
+
font-size: 0.78rem;
|
|
103
|
+
color: var(--bs-secondary-color);
|
|
104
|
+
padding-top: 10px;
|
|
105
|
+
text-align: right;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
// Pullquote — centered italic serif with the oversized quote mark
|
|
109
|
+
blockquote {
|
|
110
|
+
margin: 2.4em 0;
|
|
111
|
+
padding: 0 1em;
|
|
112
|
+
text-align: center;
|
|
113
|
+
border: 0;
|
|
114
|
+
|
|
115
|
+
&::before {
|
|
116
|
+
content: "\201C";
|
|
117
|
+
display: block;
|
|
118
|
+
font-family: $nf-font-display;
|
|
119
|
+
font-weight: 900;
|
|
120
|
+
font-size: 4rem;
|
|
121
|
+
line-height: 0.6;
|
|
122
|
+
color: var(--bs-primary);
|
|
123
|
+
margin-bottom: 0.25em;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
p {
|
|
127
|
+
font-family: $nf-font-display;
|
|
128
|
+
font-style: italic;
|
|
129
|
+
font-weight: 550;
|
|
130
|
+
font-size: clamp(1.4rem, 2.6vw, 1.9rem);
|
|
131
|
+
letter-spacing: -0.01em;
|
|
132
|
+
line-height: 1.3;
|
|
133
|
+
margin: 0;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
cite {
|
|
137
|
+
display: block;
|
|
138
|
+
margin-top: 1.1em;
|
|
139
|
+
font-family: $font-family-sans-serif;
|
|
140
|
+
font-style: normal;
|
|
141
|
+
font-weight: 700;
|
|
142
|
+
font-size: 0.78rem;
|
|
143
|
+
letter-spacing: 0.12em;
|
|
144
|
+
text-transform: uppercase;
|
|
145
|
+
color: var(--bs-secondary-color);
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
// List markers pick up the accent
|
|
150
|
+
li::marker {
|
|
151
|
+
color: var(--bs-primary);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
// Tag row sits on a hairline rule
|
|
156
|
+
.tag-row {
|
|
157
|
+
border-top: var(--nf-border);
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
@media (max-width: 767.98px) {
|
|
161
|
+
.blog-post-content {
|
|
162
|
+
font-size: 1.05rem;
|
|
163
|
+
}
|
|
164
|
+
}
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
// Newsflash Theme — Homepage page-specific CSS
|
|
2
|
+
// Styles the editorial front-page override
|
|
3
|
+
// (_layouts/themes/newsflash/frontend/pages/index.html).
|
|
4
|
+
//
|
|
5
|
+
// Class names are UNIVERSAL (section-hero, hero-title, feed-num, rail-title,
|
|
6
|
+
// mostread, stat-num, cta-panel, Bootstrap .card/.badge …) — no theme prefix —
|
|
7
|
+
// so the same markup is swappable across themes. This file gives those classes
|
|
8
|
+
// the newsflash look. Compiles standalone, so it pulls in the theme tokens +
|
|
9
|
+
// mixins via loadPaths.
|
|
10
|
+
@use 'config' as *;
|
|
11
|
+
@import 'css/base/mixins';
|
|
12
|
+
|
|
13
|
+
// ============================================
|
|
14
|
+
// Hero — the front-page lead
|
|
15
|
+
// ============================================
|
|
16
|
+
.section-hero {
|
|
17
|
+
padding-top: clamp(2.5rem, 5vw, 4rem);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
.hero-title {
|
|
21
|
+
font-size: clamp(2.6rem, 5.4vw, 4.4rem);
|
|
22
|
+
font-weight: 550;
|
|
23
|
+
letter-spacing: -0.022em;
|
|
24
|
+
line-height: 1.04;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
.hero-art {
|
|
28
|
+
.art-frame {
|
|
29
|
+
aspect-ratio: 4 / 3;
|
|
30
|
+
@include nf-shadow-pop();
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
.hero-art-chip {
|
|
34
|
+
position: absolute;
|
|
35
|
+
top: 18px;
|
|
36
|
+
left: -14px;
|
|
37
|
+
transform: rotate(-4deg);
|
|
38
|
+
z-index: 2;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// Decorative cover art (pre-content fallback when the site has no posts yet):
|
|
43
|
+
// vermilion-to-orange wash with a blue corner glow — pure CSS, no asset.
|
|
44
|
+
.cover-art {
|
|
45
|
+
background:
|
|
46
|
+
radial-gradient(110% 90% at 88% 8%, #FFB36B 0%, rgba(255, 179, 107, 0) 52%),
|
|
47
|
+
radial-gradient(120% 110% at 8% 95%, var(--nf-blue) 0%, rgba(39, 66, 245, 0) 56%),
|
|
48
|
+
linear-gradient(155deg, var(--nf-vermilion) 10%, #FF7A3D 90%);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// ============================================
|
|
52
|
+
// The rundown — stroked step numerals on dashed rows
|
|
53
|
+
// ============================================
|
|
54
|
+
// (The latest feed uses .feed-item's BASE layout from _editorial.scss —
|
|
55
|
+
// square art thumb + text. Only the rundown swaps the thumb for a numeral.)
|
|
56
|
+
.feed-num {
|
|
57
|
+
font-family: $nf-font-display;
|
|
58
|
+
font-style: italic;
|
|
59
|
+
font-weight: 800;
|
|
60
|
+
font-size: 3.2rem;
|
|
61
|
+
line-height: 1;
|
|
62
|
+
color: transparent;
|
|
63
|
+
-webkit-text-stroke: 1.5px var(--nf-ink);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
// On rundown rows the numeral replaces the thumbnail — shrink its column
|
|
67
|
+
.feed-item .feed-num {
|
|
68
|
+
width: 5rem;
|
|
69
|
+
}
|
|
70
|
+
.section-rundown .feed-item {
|
|
71
|
+
grid-template-columns: 5rem 1fr;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// ============================================
|
|
75
|
+
// The rail (sticky sidebar)
|
|
76
|
+
// ============================================
|
|
77
|
+
.rail-stack {
|
|
78
|
+
position: sticky;
|
|
79
|
+
top: 5.75rem; // clears the sticky masthead
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
.rail-title {
|
|
83
|
+
display: flex;
|
|
84
|
+
align-items: center;
|
|
85
|
+
gap: 0.6em;
|
|
86
|
+
font-weight: 800;
|
|
87
|
+
font-size: 0.8rem;
|
|
88
|
+
letter-spacing: 0.14em;
|
|
89
|
+
text-transform: uppercase;
|
|
90
|
+
margin-bottom: 1rem;
|
|
91
|
+
|
|
92
|
+
&::after {
|
|
93
|
+
content: "";
|
|
94
|
+
flex: 1;
|
|
95
|
+
height: var(--nf-border-width);
|
|
96
|
+
background: var(--nf-border-color);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
// Most-read list — stroked counter numerals that ink in on hover
|
|
101
|
+
.mostread {
|
|
102
|
+
counter-reset: mostread;
|
|
103
|
+
|
|
104
|
+
li {
|
|
105
|
+
counter-increment: mostread;
|
|
106
|
+
display: flex;
|
|
107
|
+
gap: 1rem;
|
|
108
|
+
align-items: flex-start;
|
|
109
|
+
padding: 0.8rem 0;
|
|
110
|
+
border-bottom: 1px solid var(--nf-line);
|
|
111
|
+
|
|
112
|
+
&:first-child { padding-top: 0; }
|
|
113
|
+
&:last-child { border-bottom: 0; padding-bottom: 0; }
|
|
114
|
+
|
|
115
|
+
&::before {
|
|
116
|
+
content: counter(mostread);
|
|
117
|
+
font-family: $nf-font-display;
|
|
118
|
+
font-style: italic;
|
|
119
|
+
font-weight: 900;
|
|
120
|
+
font-size: 2rem;
|
|
121
|
+
line-height: 1;
|
|
122
|
+
color: transparent;
|
|
123
|
+
-webkit-text-stroke: 1.3px var(--nf-ink);
|
|
124
|
+
flex: none;
|
|
125
|
+
width: 1.2em;
|
|
126
|
+
transition: $nf-transition;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
&:hover::before {
|
|
130
|
+
color: var(--bs-primary);
|
|
131
|
+
-webkit-text-stroke-color: var(--bs-primary);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
a {
|
|
136
|
+
font-weight: 700;
|
|
137
|
+
font-size: 0.95rem;
|
|
138
|
+
line-height: 1.35;
|
|
139
|
+
color: inherit;
|
|
140
|
+
text-decoration: none;
|
|
141
|
+
|
|
142
|
+
&:hover {
|
|
143
|
+
color: var(--bs-primary);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
// Newsletter rail — the vermilion slab gets the hard offset shadow
|
|
149
|
+
.rail-stack .card.bg-primary {
|
|
150
|
+
box-shadow: var(--nf-shadow-hard-hover) !important;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
// (Feature icon chips, stats numerals + the CTA band live in the main bundle — _panels.scss —
|
|
154
|
+
// because pricing/about reuse them. Reader quote-cards live in pages/about/index.scss —
|
|
155
|
+
// the testimonials section moved to the about page.)
|
|
156
|
+
|
|
157
|
+
@media (max-width: 991.98px) {
|
|
158
|
+
.rail-stack { position: static; }
|
|
159
|
+
}
|