jekyll-theme-zer0 1.27.0 → 1.29.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.
Files changed (142) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +812 -13
  3. data/_data/backlog.yml +356 -2
  4. data/_data/consumers.yml +252 -0
  5. data/_data/features.yml +234 -5
  6. data/_data/i18n/fr.yml +103 -0
  7. data/_data/i18n/manifest.yml +1529 -0
  8. data/_data/ingredient_densities.yml +122 -0
  9. data/_data/navigation/docs.yml +2 -0
  10. data/_data/navigation/main.yml +22 -0
  11. data/_data/recipe_courses.yml +64 -0
  12. data/_data/series.yml +19 -0
  13. data/_data/theme-manifest.yml +387 -277
  14. data/_data/ui-text.yml +8 -0
  15. data/_includes/README.md +36 -3
  16. data/_includes/analytics/google-tag-manager-body.html +11 -2
  17. data/_includes/analytics/google-tag-manager-head.html +16 -6
  18. data/_includes/analytics/posthog.html +33 -4
  19. data/_includes/components/abc-letter.html +43 -0
  20. data/_includes/components/background-customizer.html +2 -2
  21. data/_includes/components/book-card.html +42 -0
  22. data/_includes/components/book-nav.html +80 -0
  23. data/_includes/components/book-plate.html +31 -0
  24. data/_includes/components/book-toc.html +47 -0
  25. data/_includes/components/bookshelf.html +68 -0
  26. data/_includes/components/card-grid.html +60 -0
  27. data/_includes/components/cookie-consent.html +4 -4
  28. data/_includes/components/data-card.html +95 -0
  29. data/_includes/components/halfmoon.html +5 -1
  30. data/_includes/components/info-section.html +8 -3
  31. data/_includes/components/language-toggle.html +168 -21
  32. data/_includes/components/page-feedback.html +65 -2
  33. data/_includes/components/page-views-init.html +55 -0
  34. data/_includes/components/page-views.html +33 -0
  35. data/_includes/components/recipe-card.html +67 -0
  36. data/_includes/components/recipe-duration.html +50 -0
  37. data/_includes/components/recipe-grams.html +58 -0
  38. data/_includes/components/recipe-index.html +96 -0
  39. data/_includes/components/recipe-ingredients.html +90 -0
  40. data/_includes/components/recipe-meta.html +96 -0
  41. data/_includes/components/recipe-nutrition.html +57 -0
  42. data/_includes/components/recipe-qty.html +73 -0
  43. data/_includes/components/recipe-ratio.html +151 -0
  44. data/_includes/components/recipe-scaler.html +73 -0
  45. data/_includes/components/recipe-steps.html +86 -0
  46. data/_includes/components/recipe-temp.html +45 -0
  47. data/_includes/components/search-modal.html +2 -2
  48. data/_includes/components/shortcuts-modal.html +3 -0
  49. data/_includes/components/theme-controls-bar.html +10 -2
  50. data/_includes/components/theme-customizer.html +8 -2
  51. data/_includes/components/theme-info.html +8 -1
  52. data/_includes/content/jsonld-software.html +22 -3
  53. data/_includes/content/seo.html +9 -3
  54. data/_includes/core/color-mode-init.html +13 -4
  55. data/_includes/core/favicon.html +46 -0
  56. data/_includes/core/footer.html +18 -16
  57. data/_includes/core/head.html +21 -0
  58. data/_includes/core/header.html +7 -4
  59. data/_includes/custom/body-end.html +18 -0
  60. data/_includes/custom/body-start.html +17 -0
  61. data/_includes/custom/footer.html +18 -0
  62. data/_includes/custom/head.html +18 -0
  63. data/_includes/navigation/local-graph.html +28 -2
  64. data/_includes/navigation/nav-tree.html +3 -3
  65. data/_includes/navigation/section-sidebar.html +93 -11
  66. data/_includes/navigation/sidebar-config.html +21 -0
  67. data/_includes/navigation/sidebar-left.html +2 -1
  68. data/_includes/navigation/sidebar-nav.html +4 -0
  69. data/_includes/navigation/sidebar-pagetree.html +150 -0
  70. data/_includes/navigation/sidebar-right.html +2 -1
  71. data/_includes/navigation/unified-drawer.html +8 -2
  72. data/_includes/obsidian/full-graph.html +165 -136
  73. data/_includes/setup/wizard.html +173 -86
  74. data/_includes/stats/stats-metrics.html +2 -2
  75. data/_layouts/404.html +260 -0
  76. data/_layouts/README.md +4 -0
  77. data/_layouts/admin.html +2 -2
  78. data/_layouts/article.html +5 -0
  79. data/_layouts/book-abc.html +106 -0
  80. data/_layouts/book-story.html +91 -0
  81. data/_layouts/book.html +113 -0
  82. data/_layouts/collection.html +17 -5
  83. data/_layouts/cookbook.html +88 -0
  84. data/_layouts/default.html +4 -4
  85. data/_layouts/home.html +5 -2
  86. data/_layouts/landing.html +9 -0
  87. data/_layouts/news.html +155 -31
  88. data/_layouts/recipe.html +274 -0
  89. data/_layouts/root.html +38 -5
  90. data/_layouts/section.html +96 -25
  91. data/_sass/components/_book.scss +423 -0
  92. data/_sass/components/_callout.scss +1 -1
  93. data/_sass/components/_footer.scss +37 -1
  94. data/_sass/components/_page-views.scss +36 -0
  95. data/_sass/components/_recipe.scss +506 -0
  96. data/_sass/components/_setup-wizard.scss +235 -0
  97. data/_sass/components/_ui-enhancements.scss +6 -6
  98. data/_sass/core/_navbar.scss +263 -15
  99. data/_sass/core/_obsidian.scss +286 -6
  100. data/_sass/layouts/_landing.scss +2 -2
  101. data/_sass/theme/_backgrounds.scss +21 -8
  102. data/_sass/tokens/_color.scss +6 -0
  103. data/_sass/tokens/_index.scss +2 -0
  104. data/_sass/tokens/_radius.scss +21 -0
  105. data/_sass/tokens/_typography.scss +4 -0
  106. data/_sass/utilities/_focus.scss +14 -0
  107. data/assets/css/main.scss +4 -0
  108. data/assets/js/auto-hide-nav.js +5 -1
  109. data/assets/js/halfmoon.js +26 -0
  110. data/assets/js/modules/navigation/navbar.js +55 -0
  111. data/assets/js/obsidian-graph.js +702 -264
  112. data/assets/js/obsidian-local-graph.js +161 -54
  113. data/assets/js/page-views.js +372 -0
  114. data/assets/js/recipe-scaler.js +501 -0
  115. data/assets/js/search-modal.js +14 -1
  116. data/assets/js/setup-wizard.js +322 -20
  117. data/scripts/README.md +29 -0
  118. data/scripts/bin/audit-consumer +39 -7
  119. data/scripts/bin/giscus-discussions +213 -14
  120. data/scripts/bin/manifest +66 -16
  121. data/scripts/bin/validate +5 -1
  122. data/scripts/ci/agent_review_result.py +164 -0
  123. data/scripts/ci/test_agent_review_result.py +172 -0
  124. data/scripts/design-system-check.rb +170 -0
  125. data/scripts/install/README.md +47 -6
  126. data/scripts/install/ai/client.sh +302 -93
  127. data/scripts/install/ai/prompts/spec.schema.json +1 -1
  128. data/scripts/install/ai/wizard.sh +10 -5
  129. data/scripts/install/apply.sh +7 -3
  130. data/scripts/install/cli.sh +54 -4
  131. data/scripts/install/config.sh +167 -0
  132. data/scripts/install/doctor.sh +38 -0
  133. data/scripts/install/plan.sh +10 -0
  134. data/scripts/install/spec.sh +15 -7
  135. data/scripts/install/template.sh +4 -0
  136. data/scripts/lib/audit.sh +42 -2
  137. data/scripts/lint-liquid-raw.rb +137 -0
  138. data/scripts/propagate.rb +277 -0
  139. data/scripts/test/lib/run_tests.sh +2 -1
  140. data/scripts/test/lib/test_agent_review_result.sh +27 -0
  141. data/scripts/translate.rb +161 -15
  142. metadata +56 -2
@@ -0,0 +1,423 @@
1
+ // ============================================================================
2
+ // BOOK COLLECTION — children's picture-book presentation (Feature: ZER0-080)
3
+ // ----------------------------------------------------------------------------
4
+ // Styles for the `books` collection: bookshelf cards, the book landing page
5
+ // (cover hero + table of contents), and the immersive story reading surface.
6
+ //
7
+ // Used by:
8
+ // _layouts/book.html, _layouts/book-story.html, _layouts/book-abc.html
9
+ // _includes/components/bookshelf.html, book-card.html, book-toc.html,
10
+ // _includes/components/book-nav.html, book-plate.html, abc-letter.html
11
+ //
12
+ // Theming: everything reads Bootstrap's runtime custom properties
13
+ // (var(--bs-*)) so light/dark color modes and theme skins work for free.
14
+ // Consumer knobs are exposed as --zer0-book-* custom properties.
15
+ // ============================================================================
16
+
17
+ :root {
18
+ // Friendly, readable storybook serif — system stacks only (no CDN fonts).
19
+ --zer0-book-serif: "Iowan Old Style", "Palatino Linotype", Palatino, Georgia,
20
+ "Times New Roman", serif;
21
+ --zer0-book-font-size: clamp(1.125rem, 1rem + 0.6vw, 1.375rem);
22
+ --zer0-book-measure: 42rem; // comfortable line length for read-aloud text
23
+ --zer0-book-plate-radius: 1rem;
24
+ }
25
+
26
+ // ----------------------------------------------------------------------------
27
+ // Cover frame — shared by bookshelf cards and the book landing hero.
28
+ // A portrait "physical book" look: 3/4 ratio, soft spine shadow, hover lift.
29
+ // ----------------------------------------------------------------------------
30
+ .book-cover-frame {
31
+ position: relative;
32
+ display: block;
33
+ aspect-ratio: 3 / 4;
34
+ overflow: hidden;
35
+ border-radius: 0.5rem 1rem 1rem 0.5rem; // subtle spine on the left
36
+ box-shadow:
37
+ inset 0.35rem 0 0.5rem -0.35rem rgba(0, 0, 0, 0.45), // spine crease
38
+ 0 0.75rem 1.5rem rgba(0, 0, 0, 0.25);
39
+ background-color: var(--bs-secondary-bg);
40
+
41
+ img {
42
+ width: 100%;
43
+ height: 100%;
44
+ object-fit: cover;
45
+ display: block;
46
+ }
47
+ }
48
+
49
+ .book-card {
50
+ .book-cover-frame {
51
+ transition: transform 0.25s ease, box-shadow 0.25s ease;
52
+
53
+ @media (prefers-reduced-motion: reduce) {
54
+ transition: none;
55
+ }
56
+ }
57
+
58
+ &:hover .book-cover-frame,
59
+ &:focus-within .book-cover-frame {
60
+ transform: translateY(-0.25rem) rotate(-1deg);
61
+ box-shadow:
62
+ inset 0.35rem 0 0.5rem -0.35rem rgba(0, 0, 0, 0.45),
63
+ 0 1.25rem 2rem rgba(0, 0, 0, 0.3);
64
+ }
65
+ }
66
+
67
+ // ----------------------------------------------------------------------------
68
+ // Book landing hero (cover + title block)
69
+ // ----------------------------------------------------------------------------
70
+ .book-hero {
71
+ .book-hero-title {
72
+ font-family: var(--zer0-book-serif);
73
+ letter-spacing: -0.01em;
74
+ }
75
+
76
+ .book-hero-cover {
77
+ max-width: 22rem;
78
+ }
79
+ }
80
+
81
+ // ----------------------------------------------------------------------------
82
+ // Table of contents — one row per story/chapter
83
+ // ----------------------------------------------------------------------------
84
+ .book-toc {
85
+ .book-toc-item {
86
+ display: flex;
87
+ align-items: center;
88
+ gap: 1rem;
89
+ padding: 0.75rem 1rem;
90
+ border: 1px solid var(--bs-border-color);
91
+ border-radius: 0.75rem;
92
+ background-color: var(--bs-body-bg);
93
+ color: var(--bs-body-color);
94
+ text-decoration: none;
95
+ transition: transform 0.15s ease, border-color 0.15s ease;
96
+
97
+ @media (prefers-reduced-motion: reduce) {
98
+ transition: none;
99
+ }
100
+
101
+ &:hover,
102
+ &:focus-visible {
103
+ border-color: var(--bs-primary);
104
+ transform: translateX(0.25rem);
105
+ }
106
+ }
107
+
108
+ .book-toc-number {
109
+ flex: 0 0 auto;
110
+ display: inline-flex;
111
+ align-items: center;
112
+ justify-content: center;
113
+ width: 2.5rem;
114
+ height: 2.5rem;
115
+ border-radius: 50%;
116
+ font-weight: 700;
117
+ background-color: var(--bs-primary-bg-subtle);
118
+ color: var(--bs-primary-text-emphasis);
119
+ }
120
+
121
+ .book-toc-thumb {
122
+ flex: 0 0 auto;
123
+ width: 4.5rem;
124
+ height: 3rem;
125
+ object-fit: cover;
126
+ border-radius: 0.5rem;
127
+ }
128
+ }
129
+
130
+ // ----------------------------------------------------------------------------
131
+ // Story reading surface — big friendly type, generous leading, drop cap
132
+ // ----------------------------------------------------------------------------
133
+ .book-story-content {
134
+ max-width: var(--zer0-book-measure);
135
+ margin-inline: auto;
136
+ font-family: var(--zer0-book-serif);
137
+ font-size: var(--zer0-book-font-size);
138
+ line-height: 1.8;
139
+
140
+ p {
141
+ margin-bottom: 1.25em;
142
+ }
143
+
144
+ // Storybook drop cap on the opening paragraph.
145
+ > p:first-of-type::first-letter {
146
+ float: left;
147
+ font-size: 3.2em;
148
+ line-height: 0.85;
149
+ padding-right: 0.12em;
150
+ font-weight: 700;
151
+ color: var(--bs-primary-text-emphasis);
152
+ }
153
+
154
+ // Bare markdown images inside a story get the plate treatment too, so
155
+ // content written without the book-plate include still looks right.
156
+ > p > img,
157
+ > img {
158
+ display: block;
159
+ width: 100%;
160
+ height: auto;
161
+ border-radius: var(--zer0-book-plate-radius);
162
+ box-shadow: 0 0.5rem 1.25rem rgba(0, 0, 0, 0.2);
163
+ }
164
+ }
165
+
166
+ // Illustration plate (figure + optional caption). Plates break out a little
167
+ // wider than the text measure to feel like full-bleed picture-book art.
168
+ .book-plate {
169
+ margin: 2rem auto;
170
+ max-width: min(52rem, 100%);
171
+
172
+ img {
173
+ width: 100%;
174
+ height: auto;
175
+ display: block;
176
+ border-radius: var(--zer0-book-plate-radius);
177
+ box-shadow: 0 0.5rem 1.25rem rgba(0, 0, 0, 0.2);
178
+ }
179
+
180
+ figcaption {
181
+ margin-top: 0.5rem;
182
+ text-align: center;
183
+ font-style: italic;
184
+ font-size: 0.875rem;
185
+ color: var(--bs-secondary-color);
186
+ }
187
+ }
188
+
189
+ // "The End" flourish
190
+ .book-the-end {
191
+ font-family: var(--zer0-book-serif);
192
+ font-style: italic;
193
+ text-align: center;
194
+ color: var(--bs-secondary-color);
195
+
196
+ &::before,
197
+ &::after {
198
+ content: "❦";
199
+ margin-inline: 0.75rem;
200
+ color: var(--bs-primary-text-emphasis);
201
+ }
202
+ }
203
+
204
+ // ----------------------------------------------------------------------------
205
+ // Colophon — collapsed "how the illustrations were made" provenance block
206
+ // ----------------------------------------------------------------------------
207
+ .book-colophon {
208
+ max-width: var(--zer0-book-measure);
209
+ margin-inline: auto;
210
+
211
+ summary {
212
+ cursor: pointer;
213
+ color: var(--bs-secondary-color);
214
+
215
+ &:hover {
216
+ color: var(--bs-body-color);
217
+ }
218
+ }
219
+
220
+ .book-colophon-prompt {
221
+ font-size: 0.85rem;
222
+ color: var(--bs-secondary-color);
223
+ background-color: var(--bs-tertiary-bg);
224
+ border-radius: 0.5rem;
225
+ padding: 0.75rem 1rem;
226
+ }
227
+ }
228
+
229
+ // ----------------------------------------------------------------------------
230
+ // Print — read/print the story cleanly (plates keep their ink, chrome goes)
231
+ // ----------------------------------------------------------------------------
232
+ @media print {
233
+ .book-story-nav,
234
+ .book-colophon {
235
+ display: none !important;
236
+ }
237
+
238
+ .book-plate img,
239
+ .book-story-content img {
240
+ box-shadow: none;
241
+ break-inside: avoid;
242
+ }
243
+ }
244
+
245
+ // ============================================================================
246
+ // ABC BOARD BOOKS — the "ABC & Language" series (Feature: ZER0-081)
247
+ // ----------------------------------------------------------------------------
248
+ // Single-scroll toddler alphabet books: _layouts/book-abc.html renders a grid
249
+ // of abc-letter cards. Each art style (art_style front matter) adds a
250
+ // .abc-style--<id> skin that tints the placeholder tiles and letter badges.
251
+ // ============================================================================
252
+
253
+ // A–Z quick-jump strip.
254
+ .abc-jump {
255
+ display: flex;
256
+ flex-wrap: wrap;
257
+ gap: 0.35rem;
258
+ justify-content: center;
259
+ margin-bottom: 2rem;
260
+
261
+ &-link {
262
+ display: inline-flex;
263
+ align-items: center;
264
+ justify-content: center;
265
+ min-width: 2rem;
266
+ padding: 0.15rem 0.4rem;
267
+ font-family: var(--zer0-book-serif);
268
+ font-weight: 700;
269
+ text-decoration: none;
270
+ color: var(--bs-primary-text-emphasis);
271
+ background-color: var(--bs-primary-bg-subtle);
272
+ border-radius: 0.4rem;
273
+
274
+ &:hover,
275
+ &:focus-visible {
276
+ color: var(--bs-body-bg);
277
+ background-color: var(--bs-primary);
278
+ }
279
+ }
280
+ }
281
+
282
+ // The board: a responsive grid of letter cards.
283
+ .abc-board {
284
+ display: grid;
285
+ grid-template-columns: repeat(auto-fill, minmax(min(100%, 15rem), 1fr));
286
+ gap: 1.5rem;
287
+ --abc-tint: var(--bs-primary-bg-subtle);
288
+ --abc-badge-bg: var(--bs-primary);
289
+ --abc-badge-ink: var(--bs-body-bg);
290
+ }
291
+
292
+ .abc-letter {
293
+ scroll-margin-top: 5rem; // clear the sticky navbar on #letter-x jumps
294
+ text-align: center;
295
+
296
+ &-plate {
297
+ position: relative;
298
+ aspect-ratio: 1 / 1;
299
+ border-radius: var(--zer0-book-plate-radius);
300
+ overflow: hidden;
301
+ box-shadow: 0 0.5rem 1.25rem rgba(0, 0, 0, 0.18);
302
+ background-color: var(--abc-tint);
303
+ }
304
+
305
+ &-img {
306
+ width: 100%;
307
+ height: 100%;
308
+ object-fit: cover;
309
+ display: block;
310
+ }
311
+
312
+ // Placeholder tile shown until the plate is rendered.
313
+ &-placeholder {
314
+ position: absolute;
315
+ inset: 0;
316
+ display: flex;
317
+ flex-direction: column;
318
+ align-items: center;
319
+ justify-content: center;
320
+ gap: 0.5rem;
321
+ background-image: radial-gradient(
322
+ circle at 50% 40%,
323
+ color-mix(in srgb, var(--abc-tint) 55%, white),
324
+ var(--abc-tint)
325
+ );
326
+ }
327
+
328
+ &-glyph {
329
+ font-family: var(--zer0-book-serif);
330
+ font-weight: 800;
331
+ font-size: clamp(4rem, 10vw, 7rem);
332
+ line-height: 1;
333
+ color: var(--abc-badge-bg);
334
+ }
335
+
336
+ &-planned {
337
+ font-size: 0.7rem;
338
+ text-transform: uppercase;
339
+ letter-spacing: 0.05em;
340
+ color: var(--bs-secondary-color);
341
+ }
342
+
343
+ // The big letter, always shown as HTML type (never baked into the art).
344
+ &-badge {
345
+ position: absolute;
346
+ left: 0.6rem;
347
+ bottom: 0.6rem;
348
+ display: inline-flex;
349
+ align-items: center;
350
+ justify-content: center;
351
+ width: 2.6rem;
352
+ height: 2.6rem;
353
+ border-radius: 0.7rem;
354
+ font-family: var(--zer0-book-serif);
355
+ font-weight: 800;
356
+ font-size: 1.5rem;
357
+ color: var(--abc-badge-ink);
358
+ background-color: var(--abc-badge-bg);
359
+ box-shadow: 0 0.2rem 0.5rem rgba(0, 0, 0, 0.25);
360
+ }
361
+
362
+ &-word {
363
+ font-family: var(--zer0-book-serif);
364
+ font-weight: 700;
365
+ font-size: 1.4rem;
366
+ margin: 0.8rem 0 0.15rem;
367
+ color: var(--bs-emphasis-color);
368
+ }
369
+
370
+ &-tagline {
371
+ font-family: var(--zer0-book-serif);
372
+ font-size: 1rem;
373
+ line-height: 1.4;
374
+ color: var(--bs-secondary-color);
375
+ max-width: 22rem;
376
+ margin-inline: auto;
377
+ }
378
+ }
379
+
380
+ // ----------------------------------------------------------------------------
381
+ // Art-style skins — one per art_style id in the shared catalog. Each tints the
382
+ // placeholder ground and letter badge so a book reads as one look before (and
383
+ // after) its plates render. Ids are the cross-repo contract with zer0-CMS +
384
+ // zer0-image-generator (data/abc_art_styles.yml).
385
+ // ----------------------------------------------------------------------------
386
+ .abc-style--isometric-tech-toy {
387
+ --abc-tint: #dceaff;
388
+ --abc-badge-bg: #2b7de9;
389
+ --abc-badge-ink: #fff;
390
+ }
391
+ .abc-style--chalkboard-doodle {
392
+ --abc-tint: #2f4f45;
393
+ --abc-badge-bg: #f4d35e;
394
+ --abc-badge-ink: #23342d;
395
+
396
+ .abc-letter-glyph { color: #f7fbf9; }
397
+ .abc-letter-planned { color: rgba(255, 255, 255, 0.7); }
398
+ }
399
+ .abc-style--soft-plush {
400
+ --abc-tint: #ffe6ef;
401
+ --abc-badge-bg: #f48fb1;
402
+ --abc-badge-ink: #5a2436;
403
+ }
404
+ .abc-style--crayon-primary {
405
+ --abc-tint: #fff3c4;
406
+ --abc-badge-bg: #e23b3b;
407
+ --abc-badge-ink: #fff;
408
+ }
409
+ .abc-style--paper-cutout {
410
+ --abc-tint: #ffe8d1;
411
+ --abc-badge-bg: #d98b4a;
412
+ --abc-badge-ink: #fff;
413
+ }
414
+ .abc-style--watercolor-storybook {
415
+ --abc-tint: #eef4e6;
416
+ --abc-badge-bg: #7fa05a;
417
+ --abc-badge-ink: #fff;
418
+ }
419
+
420
+ @media print {
421
+ .abc-jump { display: none !important; }
422
+ .abc-letter-plate { box-shadow: none; break-inside: avoid; }
423
+ }
@@ -17,7 +17,7 @@
17
17
 
18
18
  background: var(--zer0-color-bg-elevated);
19
19
  border-left: 0.25rem solid var(--zer0-callout-color, var(--zer0-color-primary));
20
- border-radius: 0.375rem;
20
+ border-radius: var(--zer0-radius);
21
21
  color: var(--zer0-color-ink);
22
22
  }
23
23
 
@@ -64,6 +64,12 @@
64
64
  }
65
65
  }
66
66
 
67
+ // Element-agnostic: applied to <a> (external credits), <span> (credits with
68
+ // no url) and <button> (the in-page "Info" dialog trigger — it opens the
69
+ // #info-section offcanvas rather than navigating, so it is a button, not a
70
+ // link; WCAG 4.1.2). Reboot already inherits margin/font for <button>, but
71
+ // not background, border or colour — reset those and restate the colours
72
+ // `.bd-footer a` supplies so all three elements render identically.
67
73
  .powered-by-link {
68
74
  display: inline-flex;
69
75
  align-items: center;
@@ -75,10 +81,18 @@
75
81
  text-decoration: none;
76
82
  border-radius: var(--bs-border-radius-sm, 0.25rem);
77
83
  white-space: nowrap;
84
+ // Reboot sets `-webkit-appearance: button`, which the unprefixed property
85
+ // does not cancel on older WebKit — reset both.
86
+ -webkit-appearance: none;
87
+ appearance: none;
88
+ background: none;
89
+ border: 0;
90
+ color: var(--bs-body-color);
78
91
 
79
92
  &:hover,
80
93
  &:focus-visible {
81
94
  text-decoration: none;
95
+ color: var(--bs-link-hover-color);
82
96
  }
83
97
  }
84
98
 
@@ -132,6 +146,9 @@
132
146
  // Block padding grows the tap target without changing the visual text size;
133
147
  // icon links get an explicit minimum box. (`d-block` links — e.g. the
134
148
  // truncated Latest Posts titles — keep their display but gain the padding.)
149
+ // `> button` is matched alongside `> a` because the policy row's "Cookie
150
+ // Preferences" control is a <button> (it opens a modal rather than
151
+ // navigating) and must keep the same 1.75rem tap target as its siblings.
135
152
  .footer-dark-block {
136
153
  ul.list-unstyled li > a,
137
154
  p > a {
@@ -139,7 +156,8 @@
139
156
  padding-block: 0.25rem;
140
157
  }
141
158
 
142
- ul.list-inline li > a {
159
+ ul.list-inline li > a,
160
+ ul.list-inline li > button {
143
161
  display: inline-flex;
144
162
  align-items: center;
145
163
  justify-content: center;
@@ -171,6 +189,24 @@
171
189
  }
172
190
  }
173
191
 
192
+ // A <button> that must sit in running text exactly like the <a> beside it —
193
+ // used by the "Cookie Preferences" control, which opens #cookieSettingsModal
194
+ // rather than navigating (WCAG 4.1.2). Reboot inherits margin/font for
195
+ // <button> but leaves the UA background, border and padding in place, so
196
+ // strip those; colour comes from the `.text-light` utility as before.
197
+ .footer-inline-button {
198
+ // Reboot sets `-webkit-appearance: button`, which the unprefixed property
199
+ // does not cancel on older WebKit — reset both.
200
+ -webkit-appearance: none;
201
+ appearance: none;
202
+ background: none;
203
+ border: 0;
204
+ padding: 0;
205
+ vertical-align: baseline;
206
+ text-align: inherit;
207
+ cursor: pointer;
208
+ }
209
+
174
210
  .footer-policy-links {
175
211
  @media (max-width: 767.98px) {
176
212
  font-size: 0.8125rem;
@@ -0,0 +1,36 @@
1
+ // Feature: ZER0-083
2
+ // ============================================================================
3
+ // Page-view counter badge
4
+ // ----------------------------------------------------------------------------
5
+ // Markup: _includes/components/page-views.html
6
+ // Behaviour: assets/js/page-views.js
7
+ // Config: _config.yml → page_views:
8
+ // Theming: inherits the surrounding meta-row color (.post-meta is
9
+ // .text-muted), so it follows [data-bs-theme] light/dark for free.
10
+ // ============================================================================
11
+
12
+ .page-views {
13
+ display: inline-flex;
14
+ align-items: baseline;
15
+ gap: .25rem;
16
+ white-space: nowrap;
17
+
18
+ // The badge is server-rendered hidden and revealed by JS once a count is
19
+ // known. `!important` because a utility class on the include's `class`
20
+ // param (e.g. `d-inline-flex`) would otherwise win over [hidden].
21
+ &[hidden] {
22
+ display: none !important;
23
+ }
24
+
25
+ // Digits change as the count updates — tabular figures keep the meta row
26
+ // from reflowing when 9 becomes 10.
27
+ &__count {
28
+ font-variant-numeric: tabular-nums;
29
+ }
30
+
31
+ // Leading separator for meta rows; hides with the badge because it lives
32
+ // inside it (see the include's `separator` param).
33
+ &__sep {
34
+ display: inline;
35
+ }
36
+ }