@takazudo/zudo-doc 8.1.2 → 9.0.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 (45) hide show
  1. package/CHANGELOG.md +29 -0
  2. package/README.md +1 -1
  3. package/dist/ai-chat-modal/index.js +1 -0
  4. package/dist/catalog.js +1 -1
  5. package/dist/chrome/derive.js +2 -2
  6. package/dist/config.d.ts +13 -7
  7. package/dist/config.js +6 -0
  8. package/dist/footer/footer.js +1 -1
  9. package/dist/head-with-defaults/index.js +2 -2
  10. package/dist/metainfo/doc-tags.js +3 -0
  11. package/dist/nav-indexing/tag-nav.js +7 -1
  12. package/dist/preset.d.ts +10 -4
  13. package/dist/preset.js +11 -1
  14. package/dist/route-context-payload/index.d.ts +4 -1
  15. package/dist/route-context-payload/index.js +6 -0
  16. package/dist/settings-defaults.js +3 -1
  17. package/dist/settings.d.ts +9 -5
  18. package/dist/theme/theme-pack-provider.d.ts +4 -2
  19. package/dist/theme/theme-pack-provider.js +2 -1
  20. package/dist/theme-cli/config-io.js +26 -3
  21. package/dist/theme-cli/list.js +1 -1
  22. package/dist/theme-packs/default/meta.json +2 -2
  23. package/dist/theme-packs/drift/pack.css +50 -15
  24. package/dist/theme-packs/fjord/pack.css +55 -14
  25. package/dist/theme-packs/graphite/meta.json +37 -0
  26. package/dist/theme-packs/graphite/pack.css +401 -0
  27. package/dist/theme-packs/hollow/pack.css +51 -16
  28. package/dist/theme-packs/manuscript/pack.css +57 -12
  29. package/dist/theme-packs/matcha/pack.css +46 -13
  30. package/dist/theme-packs/nocturne/pack.css +46 -10
  31. package/dist/theme-packs/observatory/pack.css +61 -20
  32. package/dist/theme-packs/quiet-slate/meta.json +37 -0
  33. package/dist/theme-packs/quiet-slate/pack.css +401 -0
  34. package/dist/theme-packs/sakura/pack.css +58 -16
  35. package/dist/theme-packs/solar/pack.css +43 -10
  36. package/dist/theme-packs/warm-mineral/meta.json +37 -0
  37. package/dist/theme-packs/warm-mineral/pack.css +401 -0
  38. package/dist/theme-packs-registry/configured-theme-pack.d.ts +21 -0
  39. package/dist/theme-packs-registry/configured-theme-pack.js +13 -0
  40. package/dist/theme-packs-registry/index.d.ts +1 -0
  41. package/dist/theme-packs-registry/index.js +6 -0
  42. package/dist/theme-packs-registry/resolve-enabled-packs.d.ts +13 -6
  43. package/dist/theme-packs-registry/resolve-enabled-packs.js +15 -5
  44. package/eject/footer/footer.tsx +1 -1
  45. package/package.json +9 -9
@@ -0,0 +1,401 @@
1
+ /* ============================================================
2
+ Graphite — zudo-doc theme pack (ADR docs/adr/theme-packs.md)
3
+
4
+ Neutral grey paper and graphite night, with a single warm copper accent.
5
+ One of the three soft-tone packs (graphite, warm-mineral,
6
+ quiet-slate) that share the same component treatment and differ
7
+ only in palette. Colour only: typography, spacing, geometry and
8
+ heading hierarchy are the package defaults (no fonts loaded).
9
+
10
+ Roles beyond the public --zd-* tokens are inlined per mode:
11
+ line decorative rules, separators and tree guides
12
+ control border necessary field / control / diagram boundaries
13
+ heading heading ink, one step stronger than body text
14
+ hover bg inactive navigation hover fill
15
+ active bg current navigation fill (90% bg + 10% accent)
16
+ state bgs admonition fills (90% bg + 10% state colour)
17
+ Classic (the reserved "default" pack) shares one muted role for
18
+ text, borders and comments; these packs keep muted at readable
19
+ text contrast and give decorative rules their own quieter line.
20
+
21
+ Production-only contrast repairs (not part of the ordinary
22
+ palette): diff rows use the opaque state fills instead of the
23
+ 15% foreground tint, and code line / word highlights use opaque
24
+ active / hover fills (no stacked alpha) keeping the accent marker
25
+ and underline, so every syntax role stays >= 4.6:1.
26
+
27
+ Every rule is scoped under html[data-theme-pack="graphite"]; the
28
+ pack never declares color-scheme and follows the mode the page
29
+ already resolved (light-dark()).
30
+ ============================================================ */
31
+
32
+ html[data-theme-pack="graphite"] {
33
+ /* Tier-2 semantic roles */
34
+ --zd-bg: light-dark(#F2F3F2, #242629);
35
+ --zd-fg: light-dark(#3A4146, #D3D5D9);
36
+ --zd-surface: light-dark(#E8EBEA, #2D3034);
37
+ --zd-muted: light-dark(#566168, #ADB2B8);
38
+ --zd-accent: light-dark(#9A4919, #E9AA79);
39
+ --zd-accent-hover: light-dark(#934619, #EAAF81);
40
+ --zd-code-bg: light-dark(#E8EBEA, #202225);
41
+ --zd-code-fg: light-dark(#3A4146, #D3D5D9);
42
+ --zd-success: light-dark(#4E6552, #9DBA9A);
43
+ --zd-danger: light-dark(#89504E, #CE9B97);
44
+ --zd-warning: light-dark(#775B2E, #CEB077);
45
+ --zd-info: light-dark(#4B6373, #9DB6C5);
46
+ --zd-selection-bg: light-dark(#9A4919, #E9AA79);
47
+ --zd-selection-fg: light-dark(#F9F5EF, #242629);
48
+ --zd-matched-keyword-bg: light-dark(#9A4919, #E9AA79);
49
+ --zd-matched-keyword-fg: light-dark(#F9F5EF, #242629);
50
+ --zd-chat-user-bg: light-dark(#9A4919, #E9AA79);
51
+ --zd-chat-user-text: light-dark(#F9F5EF, #242629);
52
+ --zd-chat-assistant-bg: light-dark(#E8EBEA, #2D3034);
53
+ --zd-chat-assistant-text: light-dark(#3A4146, #D3D5D9);
54
+ --zd-image-overlay-bg: light-dark(#F2F3F2, #242629);
55
+ --zd-image-overlay-fg: light-dark(#3A4146, #D3D5D9);
56
+ /* Mermaid: text is body text; edges are necessary diagram lines */
57
+ --zd-mermaid-node-bg: light-dark(#E8EBEA, #2D3034);
58
+ --zd-mermaid-text: light-dark(#3A4146, #D3D5D9);
59
+ --zd-mermaid-line: light-dark(#737D86, #858D96);
60
+ --zd-mermaid-label-bg: light-dark(#F2F3F2, #242629);
61
+ --zd-mermaid-note-bg: light-dark(#E1E5E4, #35383D);
62
+
63
+ /* syntax — explicit role mapping */
64
+ --zd-syntax-comment: light-dark(#566168, #ADB2B8);
65
+ --zd-syntax-string: light-dark(#4E6552, #9DBA9A);
66
+ --zd-syntax-number: light-dark(#775B2E, #CEB077);
67
+ --zd-syntax-keyword: light-dark(#9A4919, #E9AA79);
68
+ --zd-syntax-callable: light-dark(#4B6373, #9DB6C5);
69
+ --zd-syntax-type: light-dark(#775B2E, #CEB077);
70
+ --zd-syntax-name: light-dark(#3A4146, #D3D5D9);
71
+ --zd-syntax-inserted: light-dark(#4E6552, #9DBA9A);
72
+ --zd-syntax-deleted: light-dark(#89504E, #CE9B97);
73
+ /* diff rows: opaque audited state fills instead of the 15% tint */
74
+ --zfb-hi-ins-bg: light-dark(#E2E5E2, #303534);
75
+ --zfb-hi-del-bg: light-dark(#E8E3E2, #353234);
76
+
77
+ /* Tier-3 seams */
78
+ --zdc-nav-active-indicator-color: light-dark(#E9E2DC, #383331);
79
+ }
80
+
81
+ /* ---- page, chrome surfaces and decorative rules ---- */
82
+
83
+ html[data-theme-pack="graphite"] header[data-header],
84
+ html[data-theme-pack="graphite"] footer[data-footer] {
85
+ background-color: var(--zd-surface);
86
+ border-color: light-dark(#D2D8DC, #41464D);
87
+ }
88
+
89
+ html[data-theme-pack="graphite"] footer[data-footer] div {
90
+ border-color: light-dark(#D2D8DC, #41464D);
91
+ }
92
+
93
+ html[data-theme-pack="graphite"] #desktop-sidebar,
94
+ html[data-theme-pack="graphite"] aside[data-zd-mobile-sidebar],
95
+ html[data-theme-pack="graphite"] #desktop-sidebar div,
96
+ html[data-theme-pack="graphite"] aside[data-zd-mobile-sidebar] div,
97
+ html[data-theme-pack="graphite"] #desktop-sidebar nav,
98
+ html[data-theme-pack="graphite"] aside[data-zd-mobile-sidebar] nav {
99
+ border-color: light-dark(#D2D8DC, #41464D);
100
+ }
101
+
102
+ html[data-theme-pack="graphite"] nav[data-zd-toc] ul,
103
+ html[data-theme-pack="graphite"] div[data-zd-mobile-toc],
104
+ html[data-theme-pack="graphite"] div[data-zd-mobile-toc] ul {
105
+ border-color: light-dark(#D2D8DC, #41464D);
106
+ }
107
+
108
+ html[data-theme-pack="graphite"] [data-site-nav] div,
109
+ html[data-theme-pack="graphite"] [data-tabs-nav],
110
+ html[data-theme-pack="graphite"] [data-version-menu] > li,
111
+ html[data-theme-pack="graphite"] [data-nav-more-menu] > li,
112
+ html[data-theme-pack="graphite"] [data-language-menu] > li,
113
+ html[data-theme-pack="graphite"] dialog[data-search-dialog] > div div,
114
+ html[data-theme-pack="graphite"] dialog[data-search-dialog] [data-search-count-narrow],
115
+ html[data-theme-pack="graphite"] dialog[data-doc-history-panel] > div,
116
+ html[data-theme-pack="graphite"] [data-theme-pack-switcher] dialog div,
117
+ html[data-theme-pack="graphite"] dialog[data-zd-ai-chat] > div > div {
118
+ border-color: light-dark(#D2D8DC, #41464D);
119
+ }
120
+
121
+ html[data-theme-pack="graphite"] .zd-content h1,
122
+ html[data-theme-pack="graphite"] .zd-content table,
123
+ html[data-theme-pack="graphite"] .zd-content th,
124
+ html[data-theme-pack="graphite"] .zd-content td,
125
+ html[data-theme-pack="graphite"] .zd-content hr,
126
+ html[data-theme-pack="graphite"] .zd-content pre,
127
+ html[data-theme-pack="graphite"] .zd-content .code-block-title,
128
+ html[data-theme-pack="graphite"] .zd-content > section,
129
+ html[data-theme-pack="graphite"] .zd-content > ol > li:not(:hover):not(:focus-within),
130
+ html[data-theme-pack="graphite"] .zd-content > nav[data-doc-pager] > a:not(:hover),
131
+ html[data-theme-pack="graphite"] .zd-home-rule {
132
+ border-color: light-dark(#D2D8DC, #41464D);
133
+ }
134
+
135
+ /* ---- necessary control and field boundaries ---- */
136
+
137
+ html[data-theme-pack="graphite"] #desktop-sidebar button,
138
+ html[data-theme-pack="graphite"] aside[data-zd-mobile-sidebar] button,
139
+ html[data-theme-pack="graphite"] header[data-header] button,
140
+ html[data-theme-pack="graphite"] [data-nav-item-dropdown] > div > div,
141
+ html[data-theme-pack="graphite"] [data-version-menu],
142
+ html[data-theme-pack="graphite"] button[data-version-toggle]:not(:hover),
143
+ html[data-theme-pack="graphite"] button[data-language-toggle]:not(:hover),
144
+ html[data-theme-pack="graphite"] button[data-doc-history-trigger]:not(:hover),
145
+ html[data-theme-pack="graphite"] button[data-switcher-launcher]:not(:hover),
146
+ html[data-theme-pack="graphite"] dialog[data-search-dialog] > div,
147
+ html[data-theme-pack="graphite"] [data-site-nav] button,
148
+ html[data-theme-pack="graphite"] [data-nav-more-menu],
149
+ html[data-theme-pack="graphite"] [data-language-menu],
150
+ html[data-theme-pack="graphite"] [data-theme-pack-switcher] dialog,
151
+ html[data-theme-pack="graphite"] dialog[data-zd-ai-chat] input,
152
+ html[data-theme-pack="graphite"] dialog.zd-enlarge-dialog,
153
+ html[data-theme-pack="graphite"] dialog.zd-mermaid-dialog,
154
+ html[data-theme-pack="graphite"] .code-btn:not(:hover),
155
+ html[data-theme-pack="graphite"] .zd-desktop-sidebar-toggle,
156
+ html[data-theme-pack="graphite"] .zd-desktop-toc-toggle,
157
+ html[data-theme-pack="graphite"] kbd {
158
+ border-color: light-dark(#737D86, #858D96);
159
+ }
160
+
161
+ html[data-theme-pack="graphite"] #desktop-sidebar [data-sidebar-filter-region] > div,
162
+ html[data-theme-pack="graphite"] aside[data-zd-mobile-sidebar] [data-sidebar-filter-region] > div {
163
+ box-shadow: inset 0 0 0 1px light-dark(#737D86, #858D96);
164
+ }
165
+
166
+ /* ---- headings ---- */
167
+
168
+ html[data-theme-pack="graphite"] .zd-content h1,
169
+ html[data-theme-pack="graphite"] .zd-content h2,
170
+ html[data-theme-pack="graphite"] .zd-content h3,
171
+ html[data-theme-pack="graphite"] .zd-content h4,
172
+ html[data-theme-pack="graphite"] .zd-content h5,
173
+ html[data-theme-pack="graphite"] .zd-content h6 {
174
+ color: light-dark(#2E363C, #E0E3E6);
175
+ }
176
+
177
+ html[data-theme-pack="graphite"] .zd-content h2:where(:not(.zd-home-heading)):where(:not(.zd-compact-prose *)) {
178
+ border-image: linear-gradient(to right, color-mix(in srgb, light-dark(#737D86, #858D96) 65%, light-dark(#F2F3F2, #242629)), transparent) 1 !important;
179
+ }
180
+
181
+ html[data-theme-pack="graphite"] .zd-content h3:where(:not(.zd-compact-prose *)),
182
+ html[data-theme-pack="graphite"] .zd-content h4:where(:not(.zd-compact-prose *)) {
183
+ border-image: linear-gradient(to right, light-dark(#D2D8DC, #41464D), transparent) 1 !important;
184
+ }
185
+
186
+ /* ---- code ---- */
187
+
188
+ html[data-theme-pack="graphite"] .zd-content .code-block-title {
189
+ background-color: var(--zd-code-bg);
190
+ color: var(--zd-muted);
191
+ }
192
+
193
+ html[data-theme-pack="graphite"] pre.hi-root .line.highlighted,
194
+ html[data-theme-pack="graphite"] pre.hi-root [data-line-highlight="true"] {
195
+ background-color: light-dark(#E9E2DC, #383331);
196
+ box-shadow: inset 3px 0 0 var(--zd-accent);
197
+ }
198
+
199
+ html[data-theme-pack="graphite"] pre.hi-root .line .highlighted-word {
200
+ background-color: light-dark(#E1E5E4, #35383D);
201
+ }
202
+
203
+ html[data-theme-pack="graphite"] .zd-content th,
204
+ html[data-theme-pack="graphite"] .zd-content thead {
205
+ background-color: var(--zd-surface);
206
+ }
207
+
208
+ /* ---- current navigation: active fill, accent text, 3px marker ---- */
209
+
210
+ html[data-theme-pack="graphite"] #desktop-sidebar a[aria-current="page"],
211
+ html[data-theme-pack="graphite"] aside[data-zd-mobile-sidebar] a[aria-current="page"],
212
+ html[data-theme-pack="graphite"] #desktop-sidebar div:has(> a[aria-current="page"]),
213
+ html[data-theme-pack="graphite"] aside[data-zd-mobile-sidebar] div:has(> a[aria-current="page"]) {
214
+ background-color: light-dark(#E9E2DC, #383331);
215
+ color: var(--zd-accent);
216
+ }
217
+
218
+ html[data-theme-pack="graphite"] #desktop-sidebar a[aria-current="page"],
219
+ html[data-theme-pack="graphite"] aside[data-zd-mobile-sidebar] a[aria-current="page"] {
220
+ box-shadow: inset 3px 0 0 var(--zd-accent);
221
+ }
222
+
223
+ html[data-theme-pack="graphite"] #desktop-sidebar a[aria-current="page"] *,
224
+ html[data-theme-pack="graphite"] aside[data-zd-mobile-sidebar] a[aria-current="page"] *,
225
+ html[data-theme-pack="graphite"] #desktop-sidebar div:has(> a[aria-current="page"]) > button,
226
+ html[data-theme-pack="graphite"] aside[data-zd-mobile-sidebar] div:has(> a[aria-current="page"]) > button,
227
+ html[data-theme-pack="graphite"] #desktop-sidebar div:has(> a[aria-current="page"]) > button *,
228
+ html[data-theme-pack="graphite"] aside[data-zd-mobile-sidebar] div:has(> a[aria-current="page"]) > button * {
229
+ color: var(--zd-accent);
230
+ }
231
+
232
+ html[data-theme-pack="graphite"] #desktop-sidebar div:has(> a[aria-current="page"]) > button,
233
+ html[data-theme-pack="graphite"] aside[data-zd-mobile-sidebar] div:has(> a[aria-current="page"]) > button {
234
+ background-color: transparent;
235
+ border-color: light-dark(#737D86, #858D96);
236
+ }
237
+
238
+ html[data-theme-pack="graphite"] #desktop-sidebar a[aria-current="page"]:hover,
239
+ html[data-theme-pack="graphite"] aside[data-zd-mobile-sidebar] a[aria-current="page"]:hover,
240
+ html[data-theme-pack="graphite"] #desktop-sidebar a[aria-current="page"]:focus-visible,
241
+ html[data-theme-pack="graphite"] aside[data-zd-mobile-sidebar] a[aria-current="page"]:focus-visible,
242
+ html[data-theme-pack="graphite"] #desktop-sidebar div:has(> a[aria-current="page"]) > button:hover,
243
+ html[data-theme-pack="graphite"] aside[data-zd-mobile-sidebar] div:has(> a[aria-current="page"]) > button:hover,
244
+ html[data-theme-pack="graphite"] #desktop-sidebar div:has(> a[aria-current="page"]) > button:focus-visible,
245
+ html[data-theme-pack="graphite"] aside[data-zd-mobile-sidebar] div:has(> a[aria-current="page"]) > button:focus-visible {
246
+ background-color: light-dark(#E9E2DC, #383331);
247
+ color: var(--zd-accent-hover);
248
+ }
249
+
250
+ html[data-theme-pack="graphite"] [data-header-nav] a[aria-current="page"],
251
+ html[data-theme-pack="graphite"] [data-header-nav] a[aria-current="page"]:hover,
252
+ html[data-theme-pack="graphite"] [data-header-nav] a[aria-current="page"]:focus-visible {
253
+ background-color: light-dark(#E9E2DC, #383331);
254
+ color: var(--zd-accent);
255
+ box-shadow: inset 0 -3px 0 var(--zd-accent);
256
+ }
257
+
258
+ html[data-theme-pack="graphite"] [data-header-nav] a[aria-current="page"] * {
259
+ color: var(--zd-accent);
260
+ }
261
+
262
+ html[data-theme-pack="graphite"] nav[data-zd-toc] a {
263
+ padding-inline: 0.5rem;
264
+ }
265
+
266
+ html[data-theme-pack="graphite"] nav[data-zd-toc] a[aria-current="true"] {
267
+ background-color: light-dark(#E9E2DC, #383331);
268
+ color: var(--zd-accent);
269
+ box-shadow: inset 3px 0 0 var(--zd-accent);
270
+ }
271
+
272
+ /* ---- inactive navigation hover ---- */
273
+
274
+ html[data-theme-pack="graphite"] #desktop-sidebar [data-sidebar-tree-root] a:not([aria-current="page"]):hover,
275
+ html[data-theme-pack="graphite"] aside[data-zd-mobile-sidebar] [data-sidebar-tree-root] a:not([aria-current="page"]):hover {
276
+ background-color: light-dark(#E1E5E4, #35383D);
277
+ color: var(--zd-accent);
278
+ }
279
+
280
+ html[data-theme-pack="graphite"] [data-site-nav] a:hover {
281
+ color: var(--zd-accent);
282
+ }
283
+
284
+ /* ---- tag chips: line outline, bg fill, opaque muted count ---- */
285
+
286
+ html[data-theme-pack="graphite"] a[data-zd-tag-chip] > [data-zd-tag-chip-outline] {
287
+ background-color: light-dark(#D2D8DC, #41464D);
288
+ }
289
+
290
+ html[data-theme-pack="graphite"] a[data-zd-tag-chip] > [data-zd-tag-chip-label] {
291
+ background-color: var(--zd-bg);
292
+ color: var(--zd-fg);
293
+ }
294
+
295
+ html[data-theme-pack="graphite"] a[data-zd-tag-chip] [data-zd-tag-count],
296
+ html[data-theme-pack="graphite"] footer[data-footer] [data-zd-tag-count] {
297
+ opacity: 1;
298
+ color: var(--zd-muted);
299
+ }
300
+
301
+ html[data-theme-pack="graphite"] a[data-zd-tag-chip]:hover > [data-zd-tag-chip-outline],
302
+ html[data-theme-pack="graphite"] a[data-zd-tag-chip]:focus-visible > [data-zd-tag-chip-outline] {
303
+ background-color: var(--zd-accent);
304
+ }
305
+
306
+ html[data-theme-pack="graphite"] a[data-zd-tag-chip]:hover > [data-zd-tag-chip-label],
307
+ html[data-theme-pack="graphite"] a[data-zd-tag-chip]:focus-visible > [data-zd-tag-chip-label] {
308
+ background-color: light-dark(#E1E5E4, #35383D);
309
+ color: var(--zd-accent);
310
+ }
311
+
312
+ html[data-theme-pack="graphite"] a[data-zd-tag-chip]:hover [data-zd-tag-count],
313
+ html[data-theme-pack="graphite"] a[data-zd-tag-chip]:focus-visible [data-zd-tag-count],
314
+ html[data-theme-pack="graphite"] footer[data-footer] a:hover [data-zd-tag-count],
315
+ html[data-theme-pack="graphite"] footer[data-footer] a:focus-visible [data-zd-tag-count] {
316
+ color: var(--zd-accent);
317
+ }
318
+
319
+ /* ---- admonitions: soft fills, semantic title + stripe (labels/icons kept) ---- */
320
+
321
+ html[data-theme-pack="graphite"] [data-admonition="note"] {
322
+ background-color: light-dark(#E9E2DC, #383331);
323
+ border-left-color: var(--zd-accent);
324
+ }
325
+
326
+ html[data-theme-pack="graphite"] [data-admonition="note"] .admonition-title {
327
+ color: var(--zd-accent);
328
+ }
329
+
330
+ html[data-theme-pack="graphite"] [data-admonition="important"] {
331
+ background-color: light-dark(#E9E2DC, #383331);
332
+ border-left-color: var(--zd-accent);
333
+ }
334
+
335
+ html[data-theme-pack="graphite"] [data-admonition="important"] .admonition-title {
336
+ color: var(--zd-accent);
337
+ }
338
+
339
+ html[data-theme-pack="graphite"] [data-admonition="info"] {
340
+ background-color: light-dark(#E1E5E5, #303439);
341
+ border-left-color: var(--zd-info);
342
+ }
343
+
344
+ html[data-theme-pack="graphite"] [data-admonition="info"] .admonition-title {
345
+ color: var(--zd-info);
346
+ }
347
+
348
+ html[data-theme-pack="graphite"] [data-admonition="tip"] {
349
+ background-color: light-dark(#E2E5E2, #303534);
350
+ border-left-color: var(--zd-success);
351
+ }
352
+
353
+ html[data-theme-pack="graphite"] [data-admonition="tip"] .admonition-title {
354
+ color: var(--zd-success);
355
+ }
356
+
357
+ html[data-theme-pack="graphite"] [data-admonition="warning"] {
358
+ background-color: light-dark(#E6E4DE, #353431);
359
+ border-left-color: var(--zd-warning);
360
+ }
361
+
362
+ html[data-theme-pack="graphite"] [data-admonition="warning"] .admonition-title {
363
+ color: var(--zd-warning);
364
+ }
365
+
366
+ html[data-theme-pack="graphite"] [data-admonition="danger"] {
367
+ background-color: light-dark(#E8E3E2, #353234);
368
+ border-left-color: var(--zd-danger);
369
+ }
370
+
371
+ html[data-theme-pack="graphite"] [data-admonition="danger"] .admonition-title {
372
+ color: var(--zd-danger);
373
+ }
374
+
375
+ html[data-theme-pack="graphite"] [data-admonition="caution"] {
376
+ background-color: light-dark(#E8E3E2, #353234);
377
+ border-left-color: var(--zd-danger);
378
+ }
379
+
380
+ html[data-theme-pack="graphite"] [data-admonition="caution"] .admonition-title {
381
+ color: var(--zd-danger);
382
+ }
383
+
384
+ /* ---- keyboard focus: 2px accent outline, 3px offset (inset inside scrollers so it is never clipped) ---- */
385
+
386
+ html[data-theme-pack="graphite"] :focus-visible {
387
+ outline: 2px solid var(--zd-accent);
388
+ outline-offset: 3px;
389
+ }
390
+
391
+ html[data-theme-pack="graphite"] #desktop-sidebar :focus-visible,
392
+ html[data-theme-pack="graphite"] aside[data-zd-mobile-sidebar] :focus-visible,
393
+ html[data-theme-pack="graphite"] nav[data-zd-toc] :focus-visible,
394
+ html[data-theme-pack="graphite"] div[data-zd-mobile-toc] :focus-visible {
395
+ outline-offset: -2px;
396
+ }
397
+
398
+ html[data-theme-pack="graphite"] .zd-content a,
399
+ html[data-theme-pack="graphite"] .zd-content button {
400
+ text-underline-offset: 3px;
401
+ }
@@ -261,23 +261,58 @@ html[data-theme-pack="hollow"] .zd-content h1 {
261
261
  text-shadow: 0 0 22px light-dark(transparent, oklch(0.7 0.19 348 / 0.38));
262
262
  }
263
263
 
264
- /* h2: the SSR-inlined gradient bar is re-pointed at a fading pink
265
- rule (Decision 6.6's sole allowlisted !important carve-out —
266
- border-image only) */
264
+ /* top-only rule hierarchy: h2 carries a 2px fading pink rule, h3 a
265
+ quieter 1px muted rule, h4 no rule. The rules are top-anchored
266
+ background gradients; border-image none !important (Decision 6.6's
267
+ sole allowlisted carve-out) keeps the SSR-inlined gradient bar from
268
+ painting a second rule. */
267
269
  html[data-theme-pack="hollow"] .zd-content h2:where(:not(.zd-home-heading)):where(:not(.zd-compact-prose *)) {
268
- font-size: 1.5rem;
269
- }
270
- html[data-theme-pack="hollow"] .zd-content h2 {
271
- border-image: linear-gradient(
272
- to right,
273
- color-mix(
274
- in oklch,
275
- light-dark(oklch(0.52 0.2 350), oklch(0.78 0.17 348)) 62%,
276
- transparent
277
- ),
278
- transparent 72%
279
- )
280
- 1 !important;
270
+ border-image: none !important;
271
+ border-top-width: 0;
272
+ border-bottom-width: 0;
273
+ padding-top: 1.25rem;
274
+ padding-bottom: 0;
275
+ font-size: 1.75rem;
276
+ font-weight: 700;
277
+ line-height: 1.3;
278
+ background-image: linear-gradient(
279
+ to right,
280
+ light-dark(oklch(0.52 0.2 350), oklch(0.78 0.17 348)) 0%,
281
+ light-dark(oklch(0.52 0.2 350), oklch(0.78 0.17 348)) 32%,
282
+ color-mix(in oklch, light-dark(oklch(0.52 0.2 350), oklch(0.78 0.17 348)) 58%, transparent) 72%,
283
+ transparent 100%
284
+ );
285
+ background-size: 100% 2px;
286
+ background-repeat: no-repeat;
287
+ background-position: top left;
288
+ }
289
+ html[data-theme-pack="hollow"] .zd-content h3:where(:not(.zd-compact-prose *)) {
290
+ border-image: none !important;
291
+ border-top-width: 0;
292
+ border-bottom-width: 0;
293
+ padding-top: 0.875rem;
294
+ padding-bottom: 0;
295
+ font-size: 1.375rem;
296
+ font-weight: 600;
297
+ line-height: 1.4;
298
+ background-image: linear-gradient(
299
+ to right,
300
+ color-mix(in oklch, var(--zd-muted) 42%, transparent),
301
+ color-mix(in oklch, var(--zd-muted) 22%, transparent) 40%,
302
+ transparent 76%
303
+ );
304
+ background-size: 100% 1px;
305
+ background-repeat: no-repeat;
306
+ background-position: top left;
307
+ }
308
+ html[data-theme-pack="hollow"] .zd-content h4:where(:not(.zd-compact-prose *)) {
309
+ border-width: 0;
310
+ padding-top: 0;
311
+ padding-bottom: 0;
312
+ font-size: 1.2rem;
313
+ font-weight: 500;
314
+ line-height: 1.45;
315
+ background-image: none;
281
316
  }
282
317
 
283
318
  /* links: violet, quiet underline that ignites on hover */
@@ -204,20 +204,15 @@ html[data-theme-pack="manuscript"] nav[data-zd-toc] a {
204
204
  font-size: 0.95rem;
205
205
  }
206
206
 
207
- /* the signature: letterspaced small-capital subheads. The real h2/h3 carry
208
- an SSR-inlined `style="border-image:linear-gradient(...)"` bar: the h2
209
- replaces it with a hairline rule (border-image none !important is
210
- Decision 6.6's sole allowlisted carve-out); the h3 wants NO bar, which
211
- zeroing the class-level border-top-width achieves without !important
212
- (a zero-width border area leaves the inline border-image nothing to
213
- paint on). */
207
+ /* the signature: letterspaced small-capital subheads over a top-only rule
208
+ hierarchy. Document h2 carries a 2px ink rule, h3 a quieter 1px muted
209
+ rule, h4 no rule. The rules are top-anchored background gradients;
210
+ border-image none !important (Decision 6.6's sole allowlisted carve-out)
211
+ keeps the SSR-inlined `style="border-image:linear-gradient(...)"` from
212
+ painting a second bar. The unscoped rules keep the small caps (and the
213
+ compact-prose h3 voice) everywhere else. */
214
214
  html[data-theme-pack="manuscript"] .zd-content h2 {
215
- border-image: none !important;
216
- border-top-width: 1px;
217
- border-top-color: color-mix(in oklch, var(--zd-fg) 28%, transparent);
218
- padding-top: 1.35rem;
219
215
  font-variant-caps: small-caps;
220
- font-size: 1.55rem;
221
216
  }
222
217
  html[data-theme-pack="manuscript"] .zd-content h3 {
223
218
  border-top-width: 0;
@@ -225,6 +220,56 @@ html[data-theme-pack="manuscript"] .zd-content h3 {
225
220
  letter-spacing: 0.09em;
226
221
  font-size: 1.28rem;
227
222
  }
223
+ html[data-theme-pack="manuscript"] .zd-content h2:where(:not(.zd-home-heading)):where(:not(.zd-compact-prose *)) {
224
+ border-image: none !important;
225
+ border-top-width: 0;
226
+ border-bottom-width: 0;
227
+ padding-top: 1.25rem;
228
+ padding-bottom: 0;
229
+ font-size: 2rem;
230
+ font-weight: 600;
231
+ line-height: 1.3;
232
+ letter-spacing: 0.055em;
233
+ background-image: linear-gradient(
234
+ to right,
235
+ color-mix(in oklch, var(--zd-fg) 72%, var(--zd-accent)) 0%,
236
+ color-mix(in oklch, var(--zd-fg) 72%, var(--zd-accent)) 32%,
237
+ color-mix(in oklch, color-mix(in oklch, var(--zd-fg) 72%, var(--zd-accent)) 58%, transparent) 72%,
238
+ transparent 100%
239
+ );
240
+ background-size: 100% 2px;
241
+ background-repeat: no-repeat;
242
+ background-position: top left;
243
+ }
244
+ html[data-theme-pack="manuscript"] .zd-content h3:where(:not(.zd-compact-prose *)) {
245
+ border-image: none !important;
246
+ border-top-width: 0;
247
+ border-bottom-width: 0;
248
+ padding-top: 0.875rem;
249
+ padding-bottom: 0;
250
+ font-size: 1.5rem;
251
+ font-weight: 500;
252
+ line-height: 1.4;
253
+ letter-spacing: 0.045em;
254
+ background-image: linear-gradient(
255
+ to right,
256
+ color-mix(in oklch, var(--zd-muted) 42%, transparent),
257
+ color-mix(in oklch, var(--zd-muted) 22%, transparent) 40%,
258
+ transparent 76%
259
+ );
260
+ background-size: 100% 1px;
261
+ background-repeat: no-repeat;
262
+ background-position: top left;
263
+ }
264
+ html[data-theme-pack="manuscript"] .zd-content h4:where(:not(.zd-compact-prose *)) {
265
+ border-width: 0;
266
+ padding-top: 0;
267
+ padding-bottom: 0;
268
+ font-size: 1.25rem;
269
+ font-weight: 500;
270
+ line-height: 1.45;
271
+ background-image: none;
272
+ }
228
273
 
229
274
  /* rubricated drop cap on the opening paragraph. The prototype's `.lead + p`
230
275
  has no stable-DOM equivalent (the frontmatter-description <p> carries only
@@ -208,30 +208,63 @@ html[data-theme-pack="matcha"] .zd-content > p[data-doc-description] {
208
208
  line-height: 1.75;
209
209
  }
210
210
 
211
- /* h2 rule: a chashaku scoop of matcha, then the line dissolves like
212
- foam. `border-image: none !important` defeats the SSR-inlined
213
- `style="border-image:linear-gradient(...)"` (Decision 6.6's sole
214
- allowlisted carve-out); the scoop itself is a 1px background
215
- gradient so no border-image fight remains. */
216
- html[data-theme-pack="matcha"] .zd-content h2 {
211
+ /* h2 rule: a chashaku scoop of matcha, then the 2px line dissolves like
212
+ foam; h3 takes a quieter 1px muted rule and h4 none. The rules are
213
+ top-anchored background gradients; `border-image: none !important`
214
+ (Decision 6.6's sole allowlisted carve-out) defeats the SSR-inlined
215
+ `style="border-image:linear-gradient(...)"`. Mincho h2 uses the bundled
216
+ 700 face; the Zen Kaku h3/h4 use the bundled 500 face rather than a
217
+ synthetic 600. */
218
+ html[data-theme-pack="matcha"] .zd-content h2:where(:not(.zd-home-heading)):where(:not(.zd-compact-prose *)) {
217
219
  border-image: none !important;
218
220
  border-top-width: 0;
219
- padding-top: 1.35rem;
221
+ border-bottom-width: 0;
222
+ padding-top: 1.25rem;
223
+ padding-bottom: 0;
224
+ font-size: 2rem;
225
+ font-weight: 700;
226
+ line-height: 1.3;
220
227
  background-image: linear-gradient(
221
228
  to right,
222
229
  var(--zd-accent) 0,
223
- var(--zd-accent) 2.75rem,
224
- color-mix(in oklch, var(--zd-muted) 32%, transparent) 2.75rem,
230
+ var(--zd-accent) 5rem,
231
+ color-mix(in oklch, var(--zd-accent) 44%, transparent) 5rem,
232
+ color-mix(in oklch, var(--zd-accent) 30%, transparent) 70%,
225
233
  transparent 100%
226
234
  );
235
+ background-size: 100% 2px;
227
236
  background-repeat: no-repeat;
228
- background-size: 100% 1px;
237
+ background-position: top left;
229
238
  }
230
-
231
- /* h3: quiet, slightly tracked (weight 600 rides --zdc-doc-h3-weight) */
232
239
  html[data-theme-pack="matcha"] .zd-content h3:where(:not(.zd-compact-prose *)) {
233
- border-top-width: 1px;
240
+ border-image: none !important;
241
+ border-top-width: 0;
242
+ border-bottom-width: 0;
243
+ padding-top: 0.875rem;
244
+ padding-bottom: 0;
245
+ font-size: 1.375rem;
246
+ font-weight: 500;
247
+ line-height: 1.4;
248
+ background-image: linear-gradient(
249
+ to right,
250
+ color-mix(in oklch, var(--zd-muted) 42%, transparent),
251
+ color-mix(in oklch, var(--zd-muted) 22%, transparent) 40%,
252
+ transparent 76%
253
+ );
254
+ background-size: 100% 1px;
255
+ background-repeat: no-repeat;
256
+ background-position: top left;
234
257
  }
258
+ html[data-theme-pack="matcha"] .zd-content h4:where(:not(.zd-compact-prose *)) {
259
+ border-width: 0;
260
+ padding-top: 0;
261
+ padding-bottom: 0;
262
+ font-size: 1.2rem;
263
+ font-weight: 500;
264
+ line-height: 1.45;
265
+ background-image: none;
266
+ }
267
+
235
268
  html[data-theme-pack="matcha"] .zd-content h3 {
236
269
  letter-spacing: 0.01em;
237
270
  }