@takazudo/zudo-doc 4.3.0 → 4.4.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 (144) hide show
  1. package/CHANGELOG.md +23 -0
  2. package/bin/zudo-doc.mjs +54 -13
  3. package/dist/auto-logo/index.d.ts +18 -0
  4. package/dist/auto-logo/index.js +33 -0
  5. package/dist/auto-logo/shapes.d.ts +32 -0
  6. package/dist/auto-logo/shapes.js +183 -0
  7. package/dist/auto-logo/standalone.d.ts +7 -0
  8. package/dist/auto-logo/standalone.js +35 -0
  9. package/dist/config.d.ts +8 -0
  10. package/dist/config.js +1 -0
  11. package/dist/content.css +4 -3
  12. package/dist/doc-content-header/index.js +1 -1
  13. package/dist/doc-history/index.js +1 -1
  14. package/dist/doc-page-shell/index.js +1 -1
  15. package/dist/doc-pager/index.js +2 -2
  16. package/dist/eject-logo/config-parse.d.ts +25 -0
  17. package/dist/eject-logo/config-parse.js +68 -0
  18. package/dist/eject-logo/config-rewriter.d.ts +22 -0
  19. package/dist/eject-logo/config-rewriter.js +68 -0
  20. package/dist/eject-logo/eject.d.ts +18 -0
  21. package/dist/eject-logo/eject.js +66 -0
  22. package/dist/eject-logo/index.d.ts +4 -0
  23. package/dist/eject-logo/index.js +16 -0
  24. package/dist/eject-logo/site-name.d.ts +21 -0
  25. package/dist/eject-logo/site-name.js +31 -0
  26. package/dist/header/header.js +14 -6
  27. package/dist/header/nav-class-tokens.d.ts +12 -0
  28. package/dist/header/nav-class-tokens.js +80 -0
  29. package/dist/header/nav-overflow-script.js +33 -16
  30. package/dist/home-page/index.d.ts +34 -5
  31. package/dist/home-page/index.js +95 -38
  32. package/dist/home-page/prepare-home-data.d.ts +9 -0
  33. package/dist/home-page/prepare-home-data.js +10 -3
  34. package/dist/i18n-defaults/index.js +3 -0
  35. package/dist/metainfo/doc-metainfo.js +35 -22
  36. package/dist/routes/index.js +2 -1
  37. package/dist/routes/locale-index.js +2 -1
  38. package/dist/safelist.css +1 -1
  39. package/dist/settings.d.ts +7 -0
  40. package/dist/sidebar-tree-island/index.js +3 -3
  41. package/dist/theme-cli/config-scanner.js +47 -0
  42. package/dist/theme-packs/academia/fonts/CourierPrime-400-latin.woff2 +0 -0
  43. package/dist/theme-packs/academia/fonts/CourierPrime-700-latin.woff2 +0 -0
  44. package/dist/theme-packs/academia/fonts/OFL.txt +94 -0
  45. package/dist/theme-packs/academia/fonts/SourceSerif4-italic-latin.woff2 +0 -0
  46. package/dist/theme-packs/academia/fonts/SourceSerif4-latin.woff2 +0 -0
  47. package/dist/theme-packs/academia/meta.json +37 -0
  48. package/dist/theme-packs/academia/pack.css +505 -0
  49. package/dist/theme-packs/bauhaus/fonts/ArchivoBlack-latin.woff2 +0 -0
  50. package/dist/theme-packs/bauhaus/fonts/Jost-latin.woff2 +0 -0
  51. package/dist/theme-packs/bauhaus/fonts/OFL.txt +95 -0
  52. package/dist/theme-packs/bauhaus/fonts/SpaceMono-400-latin.woff2 +0 -0
  53. package/dist/theme-packs/bauhaus/fonts/SpaceMono-700-latin.woff2 +0 -0
  54. package/dist/theme-packs/bauhaus/meta.json +38 -0
  55. package/dist/theme-packs/bauhaus/pack.css +614 -0
  56. package/dist/theme-packs/blueprint/fonts/IBMPlexMono-400-latin-ext.woff2 +0 -0
  57. package/dist/theme-packs/blueprint/fonts/IBMPlexMono-400-latin.woff2 +0 -0
  58. package/dist/theme-packs/blueprint/fonts/IBMPlexMono-500-latin-ext.woff2 +0 -0
  59. package/dist/theme-packs/blueprint/fonts/IBMPlexMono-500-latin.woff2 +0 -0
  60. package/dist/theme-packs/blueprint/fonts/Inter-latin-ext.woff2 +0 -0
  61. package/dist/theme-packs/blueprint/fonts/Inter-latin.woff2 +0 -0
  62. package/dist/theme-packs/blueprint/fonts/JosefinSans-latin.woff2 +0 -0
  63. package/dist/theme-packs/blueprint/fonts/OFL.txt +95 -0
  64. package/dist/theme-packs/blueprint/meta.json +38 -0
  65. package/dist/theme-packs/blueprint/pack.css +577 -0
  66. package/dist/theme-packs/botanica/fonts/CormorantGaramond-latin.woff2 +0 -0
  67. package/dist/theme-packs/botanica/fonts/CourierPrime-400-latin-ext.woff2 +0 -0
  68. package/dist/theme-packs/botanica/fonts/CourierPrime-400-latin.woff2 +0 -0
  69. package/dist/theme-packs/botanica/fonts/CourierPrime-700-latin-ext.woff2 +0 -0
  70. package/dist/theme-packs/botanica/fonts/CourierPrime-700-latin.woff2 +0 -0
  71. package/dist/theme-packs/botanica/fonts/CrimsonPro-latin-italic.woff2 +0 -0
  72. package/dist/theme-packs/botanica/fonts/CrimsonPro-latin.woff2 +0 -0
  73. package/dist/theme-packs/botanica/fonts/OFL.txt +95 -0
  74. package/dist/theme-packs/botanica/meta.json +38 -0
  75. package/dist/theme-packs/botanica/pack.css +546 -0
  76. package/dist/theme-packs/brutalist/meta.json +1 -1
  77. package/dist/theme-packs/brutalist/pack.css +10 -9
  78. package/dist/theme-packs/eink/fonts/CourierPrime-400-latin-ext.woff2 +0 -0
  79. package/dist/theme-packs/eink/fonts/CourierPrime-400-latin.woff2 +0 -0
  80. package/dist/theme-packs/eink/fonts/CourierPrime-700-latin-ext.woff2 +0 -0
  81. package/dist/theme-packs/eink/fonts/CourierPrime-700-latin.woff2 +0 -0
  82. package/dist/theme-packs/eink/fonts/EBGaramond-latin-italic.woff2 +0 -0
  83. package/dist/theme-packs/eink/fonts/EBGaramond-latin.woff2 +0 -0
  84. package/dist/theme-packs/eink/fonts/OFL.txt +94 -0
  85. package/dist/theme-packs/eink/meta.json +37 -0
  86. package/dist/theme-packs/eink/pack.css +490 -0
  87. package/dist/theme-packs/foundry/meta.json +1 -1
  88. package/dist/theme-packs/foundry/pack.css +2 -2
  89. package/dist/theme-packs/hearth/meta.json +1 -1
  90. package/dist/theme-packs/hearth/pack.css +1 -1
  91. package/dist/theme-packs/nocturne/pack.css +4 -0
  92. package/dist/theme-packs/observatory/meta.json +1 -1
  93. package/dist/theme-packs/observatory/pack.css +4 -1
  94. package/dist/theme-packs/onyx/pack.css +6 -0
  95. package/dist/theme-packs/phosphor/pack.css +4 -0
  96. package/dist/theme-packs/riso/fonts/ArchivoBlack-latin.woff2 +0 -0
  97. package/dist/theme-packs/riso/fonts/OFL.txt +95 -0
  98. package/dist/theme-packs/riso/fonts/SpaceGrotesk-latin.woff2 +0 -0
  99. package/dist/theme-packs/riso/fonts/SpaceMono-400-italic-latin.woff2 +0 -0
  100. package/dist/theme-packs/riso/fonts/SpaceMono-400-latin.woff2 +0 -0
  101. package/dist/theme-packs/riso/fonts/SpaceMono-700-latin.woff2 +0 -0
  102. package/dist/theme-packs/riso/meta.json +38 -0
  103. package/dist/theme-packs/riso/pack.css +602 -0
  104. package/dist/theme-packs/sakura/fonts/MPlus1Code-400-latin.woff2 +0 -0
  105. package/dist/theme-packs/sakura/fonts/MPlus1Code-500-latin.woff2 +0 -0
  106. package/dist/theme-packs/sakura/fonts/Nunito-latin.woff2 +0 -0
  107. package/dist/theme-packs/sakura/fonts/OFL.txt +95 -0
  108. package/dist/theme-packs/sakura/fonts/ShipporiMincho-600-latin.woff2 +0 -0
  109. package/dist/theme-packs/sakura/fonts/ShipporiMincho-700-latin.woff2 +0 -0
  110. package/dist/theme-packs/sakura/meta.json +38 -0
  111. package/dist/theme-packs/sakura/pack.css +473 -0
  112. package/dist/theme-packs/scandi/fonts/Manrope-latin.woff2 +0 -0
  113. package/dist/theme-packs/scandi/fonts/OFL.txt +94 -0
  114. package/dist/theme-packs/scandi/fonts/SplineSansMono-latin.woff2 +0 -0
  115. package/dist/theme-packs/scandi/meta.json +37 -0
  116. package/dist/theme-packs/scandi/pack.css +370 -0
  117. package/dist/theme-packs/sumi/meta.json +1 -1
  118. package/dist/theme-packs/sumi/pack.css +4 -1
  119. package/dist/theme-packs/swissgrid/pack.css +4 -0
  120. package/dist/theme-packs/tidepool/fonts/JetBrainsMono-latin-ext.woff2 +0 -0
  121. package/dist/theme-packs/tidepool/fonts/JetBrainsMono-latin.woff2 +0 -0
  122. package/dist/theme-packs/tidepool/fonts/OFL.txt +94 -0
  123. package/dist/theme-packs/tidepool/fonts/SpaceGrotesk-latin.woff2 +0 -0
  124. package/dist/theme-packs/tidepool/meta.json +37 -0
  125. package/dist/theme-packs/tidepool/pack.css +425 -0
  126. package/dist/theme-packs/timberline/fonts/Fraunces-italic-latin.woff2 +0 -0
  127. package/dist/theme-packs/timberline/fonts/Fraunces-latin.woff2 +0 -0
  128. package/dist/theme-packs/timberline/fonts/JetBrainsMono-latin.woff2 +0 -0
  129. package/dist/theme-packs/timberline/fonts/OFL.txt +95 -0
  130. package/dist/theme-packs/timberline/fonts/SourceSans3-italic-latin.woff2 +0 -0
  131. package/dist/theme-packs/timberline/fonts/SourceSans3-latin.woff2 +0 -0
  132. package/dist/theme-packs/timberline/meta.json +38 -0
  133. package/dist/theme-packs/timberline/pack.css +509 -0
  134. package/dist/theme-packs/washi/meta.json +1 -1
  135. package/dist/theme-packs/washi/pack.css +6 -26
  136. package/eject/doc-history/index.tsx +1 -1
  137. package/eject/doc-pager/index.tsx +2 -2
  138. package/eject/header/header.tsx +16 -8
  139. package/eject/header/nav-class-tokens.ts +115 -0
  140. package/eject/header/nav-overflow-script.ts +49 -16
  141. package/eject/sidebar-tree-island/index.tsx +4 -4
  142. package/package.json +16 -8
  143. package/routes-src/index.tsx +2 -1
  144. package/routes-src/locale-index.tsx +2 -1
@@ -0,0 +1,602 @@
1
+ /* ============================================================
2
+ Riso — zudo-doc theme pack (ADR docs/adr/theme-packs.md;
3
+ epic Theme Batch 5, sub-issue #3061)
4
+
5
+ Risograph duotone print: warm off-white paper and exactly TWO
6
+ inks — classic riso ink-blue and fluorescent coral. Duotone
7
+ surface tints (every panel is one ink screened over the paper),
8
+ solid misregistration offset shadows on cards, headings and the
9
+ switcher (print-craft, never a blur), and a subtle paper grain
10
+ laid down with repeating-linear-gradients (text backdrops stay
11
+ effectively solid). Dark mode is the negative plate: deep
12
+ blue-black paper, both inks brightened, prose printed in the
13
+ paper cream. Space Grotesk carries prose and chrome, Archivo
14
+ Black is the poster-punch display face (h1 + logo), Space Mono
15
+ sets the code.
16
+
17
+ Two-ink discipline: every accent in this file resolves to the
18
+ blue ink, the coral ink, or a paper neutral. Dense coral reads
19
+ as print-red/plum; blue over cream paper drifts teal; blue+coral
20
+ overprint gives the amber/brown utility tones — all standard
21
+ riso press behavior, so the syntax ladder and the state colors
22
+ stay inside the two-ink story. Fluorescent coral is an AA trap
23
+ as TEXT ink, so it appears only in surfaces/marks/offsets
24
+ (shadows, underline decorations, slabs, selection flag); every
25
+ text-adjacent or functional coral (focus ring, state bars,
26
+ danger/caution titles) is darkened to the AA print-red.
27
+
28
+ NO dot rasters anywhere — the dropped `halftone` concept owns
29
+ ben-day dots; riso's ground is linear grain only.
30
+
31
+ Every rule below is scoped under html[data-theme-pack="riso"] —
32
+ this is what makes the runtime pack swap atomic (Decision 3) and
33
+ lets the validator prove a pack can never leak styles while
34
+ inactive (Decision 6.7). The @font-face blocks are the sole
35
+ exception (at-rules can't be selector-scoped).
36
+
37
+ Helper values (the closed token manifest has no pack-local
38
+ custom properties, so these are inlined at each use site):
39
+ coral fluoro (marks only) light-dark(#ff5b41, #ff7a5f)
40
+ print-red (AA coral text) light-dark(#a8250f, #ff7a5f)
41
+ blue 2nd-pass shadow light-dark(#c5d2d3, #264c62)
42
+ ink hairline light-dark(rgb(29 51 69 / 0.18),
43
+ rgb(241 233 216 / 0.2))
44
+ grain ink fleck light-dark(rgb(29 51 69 / 0.03),
45
+ rgb(241 233 216 / 0.03))
46
+ grain coral fleck light-dark(rgb(255 91 65 / 0.02),
47
+ rgb(255 122 95 / 0.025))
48
+ Composite tints below are pre-resolved srgb mixes of the two
49
+ inks over the paper (culori pre-check, all pairs >= 4.6:1 —
50
+ see the #3061 work log for the full table).
51
+
52
+ Real-DOM notes: pager = `.zd-content > nav[data-doc-pager]`
53
+ (never bare `.zd-content > nav` — NavCardGrid also renders one);
54
+ TOC active = `nav[data-zd-toc] a[aria-current="true"]`; mobile
55
+ drawer/TOC are separate hooks (`aside[data-zd-mobile-sidebar]`,
56
+ `div[data-zd-mobile-toc]`), styled below.
57
+ ============================================================ */
58
+
59
+ /* ---- Space Grotesk — geometric grotesque for prose + chrome.
60
+ Variable 300-700, latin subset (stray latin-ext glyphs fall
61
+ back to the system stack). ---- */
62
+
63
+ @font-face {
64
+ font-family: "Space Grotesk";
65
+ font-style: normal;
66
+ font-weight: 300 700;
67
+ font-display: swap;
68
+ src: url("./fonts/SpaceGrotesk-latin.woff2") format("woff2");
69
+ unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
70
+ U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191,
71
+ U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
72
+ }
73
+
74
+ /* ---- Archivo Black — single-weight poster grotesque for the
75
+ display voice (h1, logo). 400 only; --zdc-doc-title-weight
76
+ stays 400 so no synthetic bold distorts it. ---- */
77
+
78
+ @font-face {
79
+ font-family: "Archivo Black";
80
+ font-style: normal;
81
+ font-weight: 400;
82
+ font-display: swap;
83
+ src: url("./fonts/ArchivoBlack-latin.woff2") format("woff2");
84
+ unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
85
+ U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191,
86
+ U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
87
+ }
88
+
89
+ /* ---- Space Mono — the code face. Static 400 + real 700 (bold
90
+ keywords/callables) + true italic 400 (comments and types
91
+ read italic in this pack). ---- */
92
+
93
+ @font-face {
94
+ font-family: "Space Mono";
95
+ font-style: normal;
96
+ font-weight: 400;
97
+ font-display: swap;
98
+ src: url("./fonts/SpaceMono-400-latin.woff2") format("woff2");
99
+ unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
100
+ U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191,
101
+ U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
102
+ }
103
+
104
+ @font-face {
105
+ font-family: "Space Mono";
106
+ font-style: italic;
107
+ font-weight: 400;
108
+ font-display: swap;
109
+ src: url("./fonts/SpaceMono-400-italic-latin.woff2") format("woff2");
110
+ unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
111
+ U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191,
112
+ U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
113
+ }
114
+
115
+ @font-face {
116
+ font-family: "Space Mono";
117
+ font-style: normal;
118
+ font-weight: 700;
119
+ font-display: swap;
120
+ src: url("./fonts/SpaceMono-700-latin.woff2") format("woff2");
121
+ unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
122
+ U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191,
123
+ U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
124
+ }
125
+
126
+ html[data-theme-pack="riso"] {
127
+ /* Tier-2 semantic roles — both modes always via light-dark().
128
+ Light: warm riso paper + deep two-ink overprint text. Dark:
129
+ the negative plate — blue-black paper, cream "paper ink". */
130
+ --zd-bg: light-dark(#f9f3e5, #101d28);
131
+ --zd-fg: light-dark(#1d3345, #f1e9d8);
132
+ /* selection: the fluorescent coral flag with deep overprint text —
133
+ the one place fluoro carries text, because the pair itself is the
134
+ checked contrast (5.75:1 / 6.99:1). */
135
+ --zd-selection-bg: light-dark(#ff5b41, #ff7a5f);
136
+ --zd-selection-fg: light-dark(#2a1206, #26120a);
137
+ --zd-surface: light-dark(#f1e8d4, #16242f);
138
+ --zd-muted: light-dark(#54646e, #9cadb7);
139
+ --zd-accent: light-dark(#0d5c94, #58b8e8);
140
+ --zd-accent-hover: light-dark(#094672, #8ad0f2);
141
+ /* code panel: blue ink screened 9% over the paper (pre-resolved) */
142
+ --zd-code-bg: light-dark(#e4e5de, #152531);
143
+ --zd-code-fg: light-dark(#1d3345, #eee6d4);
144
+ /* states, two-ink logic: success = dense blue drifting teal on
145
+ cream; danger = print-red (dense coral); warning = blue+coral
146
+ overprint amber; info = thinned blue ink. */
147
+ --zd-success: light-dark(#0e5f5a, #5ec4c4);
148
+ --zd-danger: light-dark(#a8250f, #ff7a5f);
149
+ --zd-warning: light-dark(#7e4a06, #e8ab62);
150
+ --zd-info: light-dark(#3a657b, #93c3da);
151
+
152
+ /* syntax — all 9 roles, both modes, built from the two inks +
153
+ paper neutrals: blue ladder (keyword-adjacent structure inks),
154
+ coral ladder (dense coral = red, denser = plum), overprint
155
+ brown for types, faded ink for comments. Weight/italic on the
156
+ .hi-* bridge classes below adds a second axis of distinction. */
157
+ --zd-syntax-comment: light-dark(#4d5c66, #93a4ad);
158
+ --zd-syntax-string: light-dark(#0d5e6e, #66d4cf);
159
+ --zd-syntax-number: light-dark(#93264d, #f298bd);
160
+ --zd-syntax-keyword: light-dark(#a02310, #ff8d72);
161
+ --zd-syntax-callable: light-dark(#0b5b9b, #5aaef5);
162
+ --zd-syntax-type: light-dark(#7c4a12, #e2ae7a);
163
+ --zd-syntax-name: light-dark(#22384a, #ece4d2);
164
+ --zd-syntax-inserted: light-dark(#175070, #9bd3ef);
165
+ --zd-syntax-deleted: light-dark(#7e1c0a, #ff9d8a);
166
+
167
+ /* mermaid + chat + overlay + search-match — kept on the two inks */
168
+ --zd-mermaid-node-bg: light-dark(#e6e7df, #1a3343);
169
+ --zd-mermaid-text: light-dark(#1d3345, #f1e9d8);
170
+ --zd-mermaid-line: light-dark(#0d5c94, #58b8e8);
171
+ --zd-mermaid-label-bg: light-dark(#f9f3e5, #101d28);
172
+ --zd-mermaid-note-bg: light-dark(#f9e7d8, #2d282f);
173
+ --zd-chat-user-bg: light-dark(#0d5c94, #58b8e8);
174
+ --zd-chat-user-text: light-dark(#f9f3e5, #101d28);
175
+ --zd-chat-assistant-bg: light-dark(#f1e8d4, #16242f);
176
+ --zd-chat-assistant-text: light-dark(#1d3345, #f1e9d8);
177
+ --zd-image-overlay-bg: light-dark(rgb(20 34 48 / 0.85), rgb(6 14 20 / 0.85));
178
+ --zd-image-overlay-fg: light-dark(#f7f1e4, #f7f1e4);
179
+ --zd-matched-keyword-bg: light-dark(#ff5b41, #ff7a5f);
180
+ --zd-matched-keyword-fg: light-dark(#2a1206, #26120a);
181
+
182
+ /* fonts — self-hosted OFL trio (Decision 5) */
183
+ --font-sans: "Space Grotesk", system-ui, sans-serif;
184
+ --font-mono: "Space Mono", ui-monospace, monospace;
185
+ --font-display: "Archivo Black", "Space Grotesk", system-ui, sans-serif;
186
+
187
+ /* Tier-3 component seams — poster display title (Archivo Black is
188
+ 400-only), Space Grotesk headings, near-square print corners. */
189
+ --zdc-doc-title-font: var(--font-display);
190
+ --zdc-doc-title-weight: 400;
191
+ --zdc-doc-title-tracking: 0.01em;
192
+ --zdc-doc-h2-weight: 700;
193
+ --zdc-doc-h2-tracking: -0.01em;
194
+ --zdc-doc-h3-weight: 700;
195
+ --zdc-doc-h4-weight: 600;
196
+ --zdc-doc-prose-font: var(--font-sans);
197
+ --zdc-doc-link-decoration: underline;
198
+ --zdc-admonition-radius: 0 2px 2px 0;
199
+ --zdc-admonition-border-width: 4px;
200
+ --zdc-card-radius: 2px;
201
+ --zdc-nav-active-indicator-color: var(--zd-accent);
202
+ --zdc-nav-active-weight: 700;
203
+ }
204
+
205
+ /* ---- paper grain: two low-alpha linear fleck passes (one per
206
+ ink) at odd angles. Alphas are grain-worst-case checked —
207
+ both layers stacked still leave every text pair >= 4.6:1.
208
+ Linear only: no dot rasters in riso. ---- */
209
+
210
+ html[data-theme-pack="riso"] body {
211
+ background-image:
212
+ repeating-linear-gradient(
213
+ 63deg,
214
+ light-dark(rgb(29 51 69 / 0.03), rgb(241 233 216 / 0.03)) 0 1px,
215
+ transparent 1px 7px
216
+ ),
217
+ repeating-linear-gradient(
218
+ -37deg,
219
+ light-dark(rgb(255 91 65 / 0.02), rgb(255 122 95 / 0.025)) 0 1px,
220
+ transparent 1px 11px
221
+ );
222
+ }
223
+
224
+ /* focus ring: functional mark, so AA print-red, not fluoro (the
225
+ fluoro coral sits under 3:1 against the light paper) */
226
+ html[data-theme-pack="riso"] :focus-visible {
227
+ outline: 2px solid light-dark(#a8250f, #ff7a5f);
228
+ outline-offset: 2px;
229
+ }
230
+
231
+ /* ---- header: heavy blue rule; logo becomes two misregistered
232
+ ink squares + the display face ---- */
233
+
234
+ html[data-theme-pack="riso"] header[data-header] {
235
+ border-bottom: 3px solid var(--zd-accent);
236
+ }
237
+ html[data-theme-pack="riso"] [data-header-logo] {
238
+ display: inline-flex;
239
+ align-items: center;
240
+ gap: 0.55rem;
241
+ font-family: var(--font-display);
242
+ font-weight: 400;
243
+ letter-spacing: 0.01em;
244
+ }
245
+ html[data-theme-pack="riso"] [data-header-logo]::before {
246
+ content: "";
247
+ width: 0.7em;
248
+ height: 0.7em;
249
+ flex-shrink: 0;
250
+ background: var(--zd-accent);
251
+ box-shadow: 0.16em 0.16em 0 0 light-dark(#ff5b41, #ff7a5f);
252
+ }
253
+ html[data-theme-pack="riso"] [data-nav-item]:hover {
254
+ text-decoration-line: underline;
255
+ text-decoration-color: light-dark(#ff5b41, #ff7a5f);
256
+ text-decoration-thickness: 3px;
257
+ text-underline-offset: 5px;
258
+ }
259
+
260
+ /* ---- sidebar: blue hairline rail, blue-wash hover, two-ink
261
+ active chip (blue fill, paper text, coral registration bar).
262
+ a[data-nav-active] intentionally matches the mobile drawer
263
+ links too — the hook is not #desktop-sidebar-scoped. ---- */
264
+
265
+ html[data-theme-pack="riso"] #desktop-sidebar {
266
+ border-right: 2px solid light-dark(rgb(13 92 148 / 0.35), rgb(88 184 232 / 0.35));
267
+ }
268
+ /* :not([data-nav-active]) is load-bearing, not cosmetic: the bare ID
269
+ selector would out-rank the active chip below and repaint its blue
270
+ fill with the pale wash on hover — leaving paper-colored text on a
271
+ paper-colored wash (invisible). Narrow, single-hook :not — not a
272
+ broad recolor chain. */
273
+ html[data-theme-pack="riso"] #desktop-sidebar a:hover:not([data-nav-active]) {
274
+ text-decoration: none;
275
+ background: light-dark(#e6e7df, #1a3343);
276
+ }
277
+ html[data-theme-pack="riso"] a[data-nav-active] {
278
+ background: var(--zd-accent);
279
+ color: var(--zd-bg);
280
+ font-weight: 700;
281
+ box-shadow: inset 4px 0 0 0 light-dark(#ff5b41, #ff7a5f);
282
+ border-radius: 2px;
283
+ }
284
+
285
+ /* mobile drawer: solid paper panel behind the tree (keeps the
286
+ grain out of the overlay), blue plate edge */
287
+ html[data-theme-pack="riso"] aside[data-zd-mobile-sidebar] {
288
+ background-color: var(--zd-bg);
289
+ border-right: 2px solid var(--zd-accent);
290
+ }
291
+
292
+ /* ---- content: misregistered two-ink headings ---- */
293
+
294
+ /* h1: poster face (via --zdc-doc-title-font) with the classic riso
295
+ misregistration — a solid fluoro-coral pass offset behind the ink */
296
+ html[data-theme-pack="riso"] .zd-content h1 {
297
+ text-shadow: 0.045em 0.045em 0 light-dark(#ff5b41, #ff7a5f);
298
+ border-bottom: 3px solid var(--zd-accent);
299
+ padding-bottom: 0.5rem;
300
+ }
301
+
302
+ /* h2: blue plate rule with a coral slab printed 2px off-register.
303
+ border-image none !important defeats the SSR-inlined gradient bar
304
+ (Decision 6.6's sole allowlisted carve-out). The ::before margins
305
+ pull the slab up over the border, then restore the text position
306
+ (-(0.75rem + 2px) up, slab is 4px tall, +(0.75rem - 2px) down). */
307
+ html[data-theme-pack="riso"] .zd-content h2 {
308
+ border-image: none !important;
309
+ border-top-width: 4px;
310
+ border-top-style: solid;
311
+ border-top-color: var(--zd-accent);
312
+ padding-top: 0.75rem;
313
+ }
314
+ html[data-theme-pack="riso"] .zd-content h2::before {
315
+ content: "";
316
+ display: block;
317
+ width: 4.5rem;
318
+ height: 4px;
319
+ background: light-dark(#ff5b41, #ff7a5f);
320
+ margin-top: calc(-0.75rem - 2px);
321
+ margin-bottom: calc(0.75rem - 2px);
322
+ }
323
+
324
+ /* h3: two misregistered ink squares as the marker (blue pass +
325
+ coral pass), no rule above */
326
+ html[data-theme-pack="riso"] .zd-content h3 {
327
+ border-image: none !important;
328
+ border-top-width: 0;
329
+ }
330
+ html[data-theme-pack="riso"] .zd-content h3::before {
331
+ content: "";
332
+ display: inline-block;
333
+ width: 0.5em;
334
+ height: 0.5em;
335
+ background: var(--zd-accent);
336
+ box-shadow: 0.16em 0.16em 0 0 light-dark(#ff5b41, #ff7a5f);
337
+ margin-right: 0.55em;
338
+ }
339
+
340
+ /* h4: quiet blue-ink subhead, no bar */
341
+ html[data-theme-pack="riso"] .zd-content h4 {
342
+ border-image: none !important;
343
+ border-top-width: 0;
344
+ color: var(--zd-accent);
345
+ }
346
+
347
+ /* links: blue ink text (token) under a fluoro-coral underline —
348
+ the two inks touching is the pack's smallest signature */
349
+ html[data-theme-pack="riso"] .zd-content a {
350
+ text-decoration-color: light-dark(#ff5b41, #ff7a5f);
351
+ text-decoration-thickness: 2px;
352
+ text-underline-offset: 3px;
353
+ }
354
+ html[data-theme-pack="riso"] .zd-content a:hover {
355
+ color: var(--zd-accent-hover);
356
+ }
357
+
358
+ /* blockquote: coral plate edge over a thin coral screen */
359
+ html[data-theme-pack="riso"] .zd-content blockquote {
360
+ border-left: 4px solid light-dark(#ff5b41, #ff7a5f);
361
+ background-color: light-dark(#f9eadb, #26252d);
362
+ border-radius: 0 2px 2px 0;
363
+ }
364
+ html[data-theme-pack="riso"] .zd-content hr {
365
+ border-top: 2px solid var(--zd-accent);
366
+ }
367
+
368
+ /* ---- code: blue-plate panel with a solid second-pass blue shadow
369
+ (offset, never blurred); real Space Mono 700/italic carry
370
+ the weight/style axis of the syntax ladder ---- */
371
+
372
+ html[data-theme-pack="riso"] pre.hi-root {
373
+ border: 2px solid var(--zd-accent);
374
+ border-radius: 2px;
375
+ box-shadow: 6px 6px 0 0 light-dark(#c5d2d3, #264c62);
376
+ }
377
+ html[data-theme-pack="riso"] .hi-kw {
378
+ font-weight: 700;
379
+ }
380
+ html[data-theme-pack="riso"] .hi-fn {
381
+ font-weight: 700;
382
+ }
383
+ html[data-theme-pack="riso"] .hi-com {
384
+ font-style: italic;
385
+ }
386
+ html[data-theme-pack="riso"] .hi-ty {
387
+ font-style: italic;
388
+ }
389
+ html[data-theme-pack="riso"] .zd-content code:not(pre code) {
390
+ background-color: var(--zd-code-bg);
391
+ border: 1px solid light-dark(rgb(13 92 148 / 0.28), rgb(88 184 232 / 0.3));
392
+ border-radius: 2px;
393
+ }
394
+
395
+ /* ---- tables: blue plate rule under heads, paper hairlines,
396
+ thin blue screen on even rows ---- */
397
+
398
+ html[data-theme-pack="riso"] .zd-content th {
399
+ border-bottom: 3px solid var(--zd-accent);
400
+ }
401
+ html[data-theme-pack="riso"] .zd-content td {
402
+ border-bottom: 1px solid light-dark(rgb(29 51 69 / 0.18), rgb(241 233 216 / 0.2));
403
+ }
404
+ html[data-theme-pack="riso"] .zd-content tbody tr:nth-child(even) {
405
+ background-color: light-dark(#edebe1, #162937);
406
+ }
407
+
408
+ /* ---- admonitions: 7 variants from two inks + paper neutrals.
409
+ Distinction = ink x screen density x border style x icon:
410
+ note/tip = blue (solid vs double), info = neutral,
411
+ warning/danger/caution/important = coral family (fluoro
412
+ border / red + offset shadow / red double / blue-on-coral).
413
+ Backgrounds are pre-resolved ink-over-paper mixes; titles
414
+ are AA print inks (fluoro never carries title text). ---- */
415
+
416
+ html[data-theme-pack="riso"] [data-admonition] .admonition-title {
417
+ text-transform: uppercase;
418
+ font-size: 0.74rem;
419
+ letter-spacing: 0.12em;
420
+ }
421
+
422
+ html[data-theme-pack="riso"] [data-admonition="note"] {
423
+ border-left-color: var(--zd-accent);
424
+ background-color: light-dark(#e1e4dd, #1c3647);
425
+ }
426
+ html[data-theme-pack="riso"] [data-admonition="note"] .admonition-title {
427
+ color: light-dark(#0a4a78, #7cc6ee);
428
+ }
429
+ html[data-theme-pack="riso"] [data-admonition="note"] .admonition-title::before {
430
+ content: "✎ ";
431
+ }
432
+
433
+ html[data-theme-pack="riso"] [data-admonition="tip"] {
434
+ /* 6px double = two clean 2px ink passes; 4px would collapse the
435
+ double-line read into a smudge */
436
+ border-left-width: 6px;
437
+ border-left-style: double;
438
+ border-left-color: var(--zd-accent);
439
+ background-color: light-dark(#edebe1, #162937);
440
+ }
441
+ html[data-theme-pack="riso"] [data-admonition="tip"] .admonition-title {
442
+ color: light-dark(#0d5c94, #58b8e8);
443
+ }
444
+ html[data-theme-pack="riso"] [data-admonition="tip"] .admonition-title::before {
445
+ content: "◉ ";
446
+ }
447
+
448
+ html[data-theme-pack="riso"] [data-admonition="info"] {
449
+ border-left-color: var(--zd-muted);
450
+ background-color: light-dark(#ece8db, #212e39);
451
+ }
452
+ html[data-theme-pack="riso"] [data-admonition="info"] .admonition-title {
453
+ color: light-dark(#43535c, #b3c5cf);
454
+ }
455
+ html[data-theme-pack="riso"] [data-admonition="info"] .admonition-title::before {
456
+ content: "○ ";
457
+ }
458
+
459
+ html[data-theme-pack="riso"] [data-admonition="warning"] {
460
+ border-left-color: light-dark(#ff5b41, #ff7a5f);
461
+ background-color: light-dark(#ede0ca, #2e3130);
462
+ }
463
+ html[data-theme-pack="riso"] [data-admonition="warning"] .admonition-title {
464
+ color: light-dark(#7e4a06, #f0b878);
465
+ }
466
+ html[data-theme-pack="riso"] [data-admonition="warning"] .admonition-title::before {
467
+ content: "▲ ";
468
+ }
469
+
470
+ html[data-theme-pack="riso"] [data-admonition="danger"] {
471
+ border-left-color: light-dark(#a8250f, #ff7a5f);
472
+ background-color: light-dark(#fadbcb, #403033);
473
+ box-shadow: 5px 5px 0 0 light-dark(#ff5b41, #ff7a5f);
474
+ }
475
+ html[data-theme-pack="riso"] [data-admonition="danger"] .admonition-title {
476
+ color: light-dark(#991d0a, #ff9781);
477
+ }
478
+ html[data-theme-pack="riso"] [data-admonition="danger"] .admonition-title::before {
479
+ content: "✖ ";
480
+ }
481
+
482
+ html[data-theme-pack="riso"] [data-admonition="important"] {
483
+ border-left-color: var(--zd-accent);
484
+ background-color: light-dark(#f9e7d8, #2d282f);
485
+ }
486
+ html[data-theme-pack="riso"] [data-admonition="important"] .admonition-title {
487
+ color: light-dark(#0a4a78, #8fd0f5);
488
+ }
489
+ html[data-theme-pack="riso"] [data-admonition="important"] .admonition-title::before {
490
+ content: "※ ";
491
+ }
492
+
493
+ html[data-theme-pack="riso"] [data-admonition="caution"] {
494
+ border-left-width: 6px;
495
+ border-left-style: double;
496
+ border-left-color: light-dark(#a8250f, #ff7a5f);
497
+ background-color: light-dark(#fae1d1, #362c31);
498
+ }
499
+ html[data-theme-pack="riso"] [data-admonition="caution"] .admonition-title {
500
+ color: light-dark(#a8250f, #ffa48f);
501
+ }
502
+ html[data-theme-pack="riso"] [data-admonition="caution"] .admonition-title::before {
503
+ content: "⚠︎ ";
504
+ }
505
+
506
+ /* ---- pager: print cards with the coral pass sitting off-register
507
+ at rest (the misregistration signature lives here, not just
508
+ on hover). Solid paper fill keeps the grain out. ---- */
509
+
510
+ html[data-theme-pack="riso"] .zd-content > nav[data-doc-pager] > a {
511
+ border: 2px solid var(--zd-accent);
512
+ background-color: var(--zd-bg);
513
+ box-shadow: 5px 5px 0 0 light-dark(#ff5b41, #ff7a5f);
514
+ }
515
+ html[data-theme-pack="riso"] .zd-content > nav[data-doc-pager] > a:hover {
516
+ border-color: var(--zd-accent-hover);
517
+ box-shadow: 7px 7px 0 0 light-dark(#ff5b41, #ff7a5f);
518
+ }
519
+ html[data-theme-pack="riso"] .zd-content > nav[data-doc-pager] > a div {
520
+ text-transform: uppercase;
521
+ font-size: 0.68rem;
522
+ letter-spacing: 0.14em;
523
+ }
524
+ html[data-theme-pack="riso"] .zd-content > nav[data-doc-pager] > a p {
525
+ font-weight: 700;
526
+ }
527
+
528
+ /* ---- TOC: hairline ink rail; active entry = AA print-red bar laid
529
+ back against the rail (foundry's pull-back trick keeps text
530
+ position stable: -pad + 3px border + (pad - 3px) = 0),
531
+ state doubled by weight so the bar is never the sole cue ---- */
532
+
533
+ html[data-theme-pack="riso"] nav[data-zd-toc] ul {
534
+ border-left: 1px solid light-dark(rgb(29 51 69 / 0.22), rgb(241 233 216 / 0.22));
535
+ }
536
+ html[data-theme-pack="riso"] nav[data-zd-toc] a:hover {
537
+ color: var(--zd-fg);
538
+ text-decoration-line: underline;
539
+ text-decoration-color: light-dark(#ff5b41, #ff7a5f);
540
+ text-decoration-thickness: 2px;
541
+ }
542
+ html[data-theme-pack="riso"] nav[data-zd-toc] a[aria-current="true"] {
543
+ background: none;
544
+ color: var(--zd-fg);
545
+ font-weight: 700;
546
+ margin-left: calc(-1 * var(--spacing-hsp-lg, 1rem));
547
+ padding-left: calc(var(--spacing-hsp-lg, 1rem) - 3px);
548
+ border-left: 3px solid light-dark(#a8250f, #ff7a5f);
549
+ }
550
+
551
+ /* mobile TOC: framed print chip on a solid surface */
552
+ html[data-theme-pack="riso"] div[data-zd-mobile-toc] {
553
+ border: 2px solid var(--zd-accent);
554
+ border-radius: 2px;
555
+ background-color: var(--zd-surface);
556
+ }
557
+
558
+ /* ---- footer: blue plate rule; ink links, coral underlines ---- */
559
+
560
+ html[data-theme-pack="riso"] footer[data-footer] {
561
+ border-top: 3px solid var(--zd-accent);
562
+ }
563
+ html[data-theme-pack="riso"] footer[data-footer] a {
564
+ color: var(--zd-fg);
565
+ text-decoration-color: light-dark(#ff5b41, #ff7a5f);
566
+ }
567
+ html[data-theme-pack="riso"] footer[data-footer] a:hover {
568
+ color: var(--zd-accent);
569
+ }
570
+
571
+ /* ---- theme-pack switcher: framed print chips, coral pass
572
+ off-register behind card and launcher ---- */
573
+
574
+ html[data-theme-pack="riso"] div[data-switcher-card] {
575
+ border: 2px solid var(--zd-accent);
576
+ border-radius: 2px;
577
+ background-color: var(--zd-surface);
578
+ box-shadow: 8px 8px 0 0 light-dark(#ff5b41, #ff7a5f);
579
+ }
580
+ html[data-theme-pack="riso"] div[data-switcher-card] button {
581
+ border-radius: 2px;
582
+ }
583
+ html[data-theme-pack="riso"] button[data-switcher-launcher] {
584
+ border: 2px solid var(--zd-accent);
585
+ border-radius: 2px;
586
+ background-color: var(--zd-bg);
587
+ box-shadow: 4px 4px 0 0 light-dark(#ff5b41, #ff7a5f);
588
+ }
589
+ html[data-theme-pack="riso"] button[data-switcher-launcher]:hover {
590
+ color: var(--zd-accent);
591
+ border-color: var(--zd-accent-hover);
592
+ }
593
+
594
+ /* browse-all dialog: same framed-chip treatment */
595
+ html[data-theme-pack="riso"] dialog[aria-labelledby="zd-theme-pack-dialog-title"] {
596
+ border: 2px solid var(--zd-accent);
597
+ border-radius: 2px;
598
+ box-shadow: 10px 10px 0 0 light-dark(#ff5b41, #ff7a5f);
599
+ }
600
+ html[data-theme-pack="riso"] dialog[aria-labelledby="zd-theme-pack-dialog-title"] button {
601
+ border-radius: 2px;
602
+ }