create-zudo-doc 0.2.21 → 0.2.22

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 (71) hide show
  1. package/dist/features/image-enlarge.d.ts +10 -2
  2. package/dist/features/image-enlarge.js +10 -2
  3. package/dist/scaffold.js +20 -22
  4. package/dist/zfb-config-gen.d.ts +16 -10
  5. package/dist/zfb-config-gen.js +34 -239
  6. package/package.json +1 -1
  7. package/templates/base/pages/lib/_body-end-islands.tsx +6 -13
  8. package/templates/base/pages/lib/_category-nav.tsx +30 -115
  9. package/templates/base/pages/lib/_category-tree-nav.tsx +38 -65
  10. package/templates/base/pages/lib/_compose-meta-title.ts +2 -6
  11. package/templates/base/pages/lib/_doc-body-end.tsx +3 -35
  12. package/templates/base/pages/lib/_doc-content-header.tsx +10 -111
  13. package/templates/base/pages/lib/_doc-history-area.tsx +19 -211
  14. package/templates/base/pages/lib/_doc-metainfo-area.tsx +10 -113
  15. package/templates/base/pages/lib/_doc-page-renderer.tsx +22 -183
  16. package/templates/base/pages/lib/_doc-page-shell.tsx +17 -251
  17. package/templates/base/pages/lib/_doc-pager.tsx +4 -74
  18. package/templates/base/pages/lib/_doc-route-entries.ts +43 -177
  19. package/templates/base/pages/lib/_doc-route-paths.ts +16 -101
  20. package/templates/base/pages/lib/_doc-tags-area.tsx +14 -77
  21. package/templates/base/pages/lib/_footer-with-defaults.tsx +37 -225
  22. package/templates/base/pages/lib/_frontmatter-preview-data.ts +5 -31
  23. package/templates/base/pages/lib/_head-with-defaults.tsx +13 -138
  24. package/templates/base/pages/lib/_header-with-defaults.tsx +24 -324
  25. package/templates/base/pages/lib/_inline-version-switcher.tsx +16 -78
  26. package/templates/base/pages/lib/_nav-data-prep.ts +32 -51
  27. package/templates/base/pages/lib/_nav-source-cache.ts +12 -57
  28. package/templates/base/pages/lib/_nav-source-docs.ts +33 -233
  29. package/templates/base/pages/lib/_search-widget-script.ts +2 -470
  30. package/templates/base/pages/lib/_search-widget.tsx +9 -195
  31. package/templates/base/pages/lib/_sidebar-prepaint.tsx +6 -59
  32. package/templates/base/pages/lib/_sidebar-with-defaults.tsx +16 -118
  33. package/templates/base/pages/lib/_site-tree-nav.tsx +29 -80
  34. package/templates/base/pages/lib/doc-page-props.ts +26 -44
  35. package/templates/base/pages/lib/locale-merge.ts +32 -145
  36. package/templates/base/pages/lib/route-enumerators.ts +52 -286
  37. package/templates/base/pages/robots.txt.tsx +2 -26
  38. package/templates/base/src/components/ai-chat-modal.tsx +9 -8
  39. package/templates/base/src/components/doc-history.tsx +9 -8
  40. package/templates/base/src/components/image-enlarge.tsx +11 -8
  41. package/templates/base/src/components/sidebar-toggle.tsx +6 -170
  42. package/templates/base/src/components/sidebar-tree.tsx +6 -548
  43. package/templates/base/src/components/site-tree-nav.tsx +6 -220
  44. package/templates/base/src/config/color-scheme-utils.ts +34 -158
  45. package/templates/base/src/config/i18n.ts +9 -0
  46. package/templates/base/src/config/z-index-tokens.ts +5 -4
  47. package/templates/base/src/styles/global.css +5 -579
  48. package/templates/base/src/utils/base.ts +1 -1
  49. package/templates/base/src/utils/docs.ts +47 -16
  50. package/templates/base/src/utils/github.ts +12 -9
  51. package/templates/base/src/utils/nav-scope.ts +13 -42
  52. package/templates/base/src/utils/sidebar.ts +18 -86
  53. package/templates/base/src/utils/slug.ts +10 -53
  54. package/templates/base/src/utils/smart-break.tsx +12 -120
  55. package/templates/base/src/utils/tags.ts +25 -68
  56. package/templates/features/bodyFootUtil/files/src/utils/github.ts +12 -9
  57. package/templates/features/designTokenPanel/files/src/lib/design-token-panel-bootstrap.ts +13 -39
  58. package/templates/features/docHistory/files/src/components/doc-history.tsx +8 -636
  59. package/templates/features/docHistory/files/src/types/doc-history.ts +7 -23
  60. package/templates/features/docTags/files/pages/lib/_tag-pages.tsx +35 -201
  61. package/templates/features/imageEnlarge/files/src/components/image-enlarge.tsx +8 -269
  62. package/templates/features/sidebarToggle/files/src/components/desktop-sidebar-toggle.tsx +6 -99
  63. package/templates/features/tagGovernance/files/scripts/tags-audit.ts +67 -515
  64. package/templates/features/versioning/files/pages/lib/_versions-page.tsx +21 -73
  65. package/templates/base/plugins/connect-adapter.mjs +0 -169
  66. package/templates/base/plugins/search-index-plugin.mjs +0 -66
  67. package/templates/base/scripts/gen-z-index.mjs +0 -157
  68. package/templates/base/src/components/mermaid-enlarge.tsx +0 -490
  69. package/templates/features/claudeResources/files/plugins/claude-resources-plugin.mjs +0 -47
  70. package/templates/features/docHistory/files/plugins/doc-history-plugin.mjs +0 -111
  71. package/templates/features/llmsTxt/files/plugins/llms-txt-plugin.mjs +0 -93
@@ -1,220 +1,6 @@
1
- "use client";
2
-
3
- // Use preact hook entrypoints directly the "react" → "preact/compat" alias
4
- // lets us consume React-typed components in this Preact app (configured
5
- // project-wide). Same pattern as src/components/sidebar-tree.tsx.
6
- import { useState } from "preact/hooks";
7
- import type { NavNode } from "@/utils/docs";
8
- import { INDENT, connectorLeft, ConnectorLines, CategoryLinkIcon } from "./tree-nav-shared";
9
- import { ChevronRight } from "@takazudo/zudo-doc/icons";
10
-
11
- // site-tree-nav uses wider padding than the narrow sidebar
12
- const SITE_BASE_PAD = "clamp(0.5rem, 0.8vw, 1rem)";
13
-
14
- function padLeft(depth: number): string {
15
- if (depth === 0) return SITE_BASE_PAD;
16
- return `calc(${depth} * ${INDENT} + 1.25rem + 5px)`;
17
- }
18
-
19
- function reorderTree(tree: NavNode[], order: string[]): NavNode[] {
20
- const map = new Map(tree.map((node) => [node.slug, node]));
21
- const ordered: NavNode[] = [];
22
- for (const slug of order) {
23
- const node = map.get(slug);
24
- if (node) {
25
- ordered.push(node);
26
- map.delete(slug);
27
- }
28
- }
29
- // append unmatched nodes at end
30
- for (const node of map.values()) {
31
- ordered.push(node);
32
- }
33
- return ordered;
34
- }
35
-
36
- interface SiteTreeNavProps {
37
- tree: NavNode[];
38
- ariaLabel?: string;
39
- categoryOrder?: string[];
40
- categoryIgnore?: string[];
41
- }
42
-
43
- export default function SiteTreeNav({
44
- tree,
45
- ariaLabel = "Site index",
46
- categoryOrder,
47
- categoryIgnore,
48
- }: SiteTreeNavProps) {
49
- let processedTree = tree;
50
- if (categoryIgnore) {
51
- const ignoreSet = new Set(categoryIgnore);
52
- processedTree = processedTree.filter((node) => !ignoreSet.has(node.slug));
53
- }
54
- if (categoryOrder) {
55
- processedTree = reorderTree(processedTree, categoryOrder);
56
- }
57
- return (
58
- <nav
59
- aria-label={ariaLabel}
60
- data-site-nav
61
- className="grid gap-vsp-md"
62
- style={{
63
- gridTemplateColumns: "repeat(auto-fill, minmax(min(18rem, 100%), 1fr))",
64
- }}
65
- >
66
- {processedTree.map((node) => (
67
- <div key={node.slug} className="min-w-0 border border-muted pl-hsp-sm py-vsp-2xs">
68
- {node.children.length > 0 ? (
69
- <CategoryNode node={node} depth={0} isLast={true} />
70
- ) : (
71
- <LeafNode node={node} depth={0} isLast={true} />
72
- )}
73
- </div>
74
- ))}
75
- </nav>
76
- );
77
- }
78
-
79
- function NodeList({ nodes, depth }: { nodes: NavNode[]; depth: number }) {
80
- return (
81
- <>
82
- {nodes.map((node, index) => {
83
- const isLast = index === nodes.length - 1;
84
- return node.children.length > 0 ? (
85
- <CategoryNode
86
- key={node.slug}
87
- node={node}
88
- depth={depth}
89
- isLast={isLast}
90
- />
91
- ) : (
92
- <LeafNode
93
- key={node.slug}
94
- node={node}
95
- depth={depth}
96
- isLast={isLast}
97
- />
98
- );
99
- })}
100
- </>
101
- );
102
- }
103
-
104
- function CategoryNode({
105
- node,
106
- depth,
107
- isLast,
108
- }: {
109
- node: NavNode;
110
- depth: number;
111
- isLast: boolean;
112
- }) {
113
- const [open, setOpen] = useState(true);
114
- const toggle = () => setOpen((prev) => !prev);
115
- const paddingLeft = padLeft(depth);
116
-
117
- return (
118
- <div className={`${depth >= 1 && !isLast ? "relative" : ""}`}>
119
- {depth >= 1 && !isLast && open && (
120
- <div
121
- className="absolute border-l border-dashed border-muted z-local-1"
122
- style={{
123
- left: connectorLeft(depth),
124
- top: 0,
125
- bottom: 0,
126
- }}
127
- />
128
- )}
129
- <div className="relative">
130
- <ConnectorLines
131
- depth={depth}
132
- isLast={isLast}
133
- widthScale={2}
134
- topPad="calc(0.15rem + var(--spacing-vsp-xs))"
135
- />
136
- <div
137
- className="flex w-full items-center justify-between text-small font-semibold pt-[0.15rem] text-fg"
138
- style={{ paddingLeft }}
139
- >
140
- {node.href ? (
141
- <a
142
- href={node.href}
143
- className="flex-1 flex items-start gap-hsp-xs py-vsp-xs text-fg hover:text-accent hover:underline focus:underline"
144
- >
145
- {depth === 0 && (
146
- <span className="flex h-[1lh] items-center">
147
- <CategoryLinkIcon className="w-[18px] 2xl:w-[24px]" />
148
- </span>
149
- )}
150
- {node.label}
151
- </a>
152
- ) : (
153
- <button
154
- type="button"
155
- onClick={toggle}
156
- className="flex-1 py-vsp-xs text-left hover:text-accent hover:underline focus:underline"
157
- >
158
- {node.label}
159
- </button>
160
- )}
161
- <button
162
- type="button"
163
- onClick={toggle}
164
- className="aspect-square flex items-center justify-center w-[1.75rem] border-y border-l border-muted hover:underline focus:underline"
165
- aria-expanded={open}
166
- aria-label={open ? `Collapse ${node.label}` : `Expand ${node.label}`}
167
- >
168
- <ChevronRight className={`h-icon-xs w-icon-xs transition-transform duration-150 ${open ? "rotate-90" : ""} text-muted`} />
169
- </button>
170
- </div>
171
- </div>
172
- {open && (
173
- <div>
174
- <NodeList nodes={node.children} depth={depth + 1} />
175
- </div>
176
- )}
177
- </div>
178
- );
179
- }
180
-
181
- function LeafNode({
182
- node,
183
- depth,
184
- isLast,
185
- }: {
186
- node: NavNode;
187
- depth: number;
188
- isLast: boolean;
189
- }) {
190
- if (!node.href) return null;
191
- const isRoot = depth === 0;
192
- const paddingLeft = padLeft(depth);
193
-
194
- const topPad = isRoot
195
- ? "calc(var(--spacing-vsp-xs) + 0.15rem)"
196
- : "var(--spacing-vsp-2xs)";
197
-
198
- return (
199
- <div>
200
- <div className="relative">
201
- <ConnectorLines depth={depth} isLast={isLast} widthScale={2} topPad={topPad} />
202
- <a
203
- href={node.href}
204
- className={isRoot
205
- ? "flex items-start gap-hsp-xs py-[calc(var(--spacing-vsp-xs)+0.15rem)] text-small font-semibold text-fg hover:text-accent hover:underline focus:underline"
206
- : `block py-vsp-2xs ${isLast ? "pb-vsp-xs" : ""} text-small text-fg hover:text-accent hover:underline focus:underline`
207
- }
208
- style={{ paddingLeft }}
209
- >
210
- {isRoot && (
211
- <span className="flex h-[1lh] items-center">
212
- <CategoryLinkIcon className="w-[18px] 2xl:w-[24px]" />
213
- </span>
214
- )}
215
- {node.label}
216
- </a>
217
- </div>
218
- </div>
219
- );
220
- }
1
+ // Thin re-export shim. SiteTreeNav moved into the package
2
+ // (`@takazudo/zudo-doc/site-tree-nav-island`) as part of the package-first
3
+ // migration (#2344, S2). Host code using `@/components/site-tree-nav`
4
+ // still resolves correctly; the implementation lives in the package.
5
+ export { SiteTreeNav } from "@takazudo/zudo-doc/site-tree-nav-island";
6
+ export type { SiteTreeNavProps } from "@takazudo/zudo-doc/site-tree-nav-island";
@@ -1,64 +1,39 @@
1
- import { colorSchemes, type ColorScheme, type ColorRef } from "./color-schemes";
1
+ /**
2
+ * Project-side color-scheme helpers.
3
+ *
4
+ * The MECHANISM (palette→CSS injection logic) now lives in the package:
5
+ * `@takazudo/zudo-doc/color-scheme-utils`. This file re-exports those
6
+ * mechanism symbols and adds project-specific thin wrappers that read from
7
+ * this project's `colorSchemes` map and `settings`. The DATA (palette values,
8
+ * scheme names) stays in `./color-schemes` and `./settings`.
9
+ *
10
+ * S9a package-first migration — zudolab/zudo-doc#2333.
11
+ */
12
+
13
+ export {
14
+ type ColorRef,
15
+ type ColorScheme,
16
+ SEMANTIC_DEFAULTS,
17
+ SEMANTIC_CSS_NAMES,
18
+ resolveColor,
19
+ resolveSemanticColors,
20
+ schemeToCssPairs,
21
+ generateCssCustomProperties as generateCssCustomPropertiesFromScheme,
22
+ generateLightDarkCssProperties as generateLightDarkCssPropertiesFromSchemes,
23
+ } from "@takazudo/zudo-doc/color-scheme-utils";
24
+ import {
25
+ generateCssCustomProperties as _generateCssCustomProperties,
26
+ generateLightDarkCssProperties as _generateLightDarkCssProperties,
27
+ } from "@takazudo/zudo-doc/color-scheme-utils";
28
+
29
+ import { colorSchemes } from "./color-schemes";
2
30
  import { settings } from "./settings";
3
31
 
4
- /** Default mapping: semantic token name → palette index */
5
- export const SEMANTIC_DEFAULTS: Record<string, number> = {
6
- surface: 0,
7
- muted: 8,
8
- accent: 5,
9
- accentHover: 14,
10
- codeBg: 10,
11
- codeFg: 11,
12
- success: 2,
13
- danger: 1,
14
- warning: 3,
15
- info: 4,
16
- mermaidNodeBg: 9,
17
- mermaidText: 11,
18
- mermaidLine: 8,
19
- mermaidLabelBg: 10,
20
- mermaidNoteBg: 0,
21
- chatUserBg: 5,
22
- chatUserText: 9,
23
- chatAssistantBg: 9,
24
- chatAssistantText: 11,
25
- imageOverlayBg: 0,
26
- imageOverlayFg: 11,
27
- matchedKeywordBg: 3,
28
- matchedKeywordFg: 15,
29
- };
30
-
31
- export const SEMANTIC_CSS_NAMES: Record<string, string> = {
32
- surface: "--zd-surface",
33
- muted: "--zd-muted",
34
- accent: "--zd-accent",
35
- accentHover: "--zd-accent-hover",
36
- codeBg: "--zd-code-bg",
37
- codeFg: "--zd-code-fg",
38
- success: "--zd-success",
39
- danger: "--zd-danger",
40
- warning: "--zd-warning",
41
- info: "--zd-info",
42
- mermaidNodeBg: "--zd-mermaid-node-bg",
43
- mermaidText: "--zd-mermaid-text",
44
- mermaidLine: "--zd-mermaid-line",
45
- mermaidLabelBg: "--zd-mermaid-label-bg",
46
- mermaidNoteBg: "--zd-mermaid-note-bg",
47
- chatUserBg: "--zd-chat-user-bg",
48
- chatUserText: "--zd-chat-user-text",
49
- chatAssistantBg: "--zd-chat-assistant-bg",
50
- chatAssistantText: "--zd-chat-assistant-text",
51
- imageOverlayBg: "--zd-image-overlay-bg",
52
- imageOverlayFg: "--zd-image-overlay-fg",
53
- matchedKeywordBg: "--zd-matched-keyword-bg",
54
- matchedKeywordFg: "--zd-matched-keyword-fg",
55
- };
56
-
57
32
  export const lightDarkPairings = [
58
33
  { light: "Default Light", dark: "Default Dark", label: "Default" },
59
34
  ];
60
35
 
61
- export function getActiveScheme(): ColorScheme {
36
+ export function getActiveScheme() {
62
37
  const scheme = colorSchemes[settings.colorScheme];
63
38
  if (!scheme) {
64
39
  throw new Error(`Unknown color scheme: "${settings.colorScheme}". Available: ${Object.keys(colorSchemes).join(", ")}`);
@@ -66,93 +41,12 @@ export function getActiveScheme(): ColorScheme {
66
41
  return scheme;
67
42
  }
68
43
 
69
- /** Resolve a ColorRef to a concrete color string.
70
- * - number → palette[value]
71
- * - string → used as-is
72
- * - undefined → fallback */
73
- export function resolveColor(
74
- value: ColorRef | undefined,
75
- palette: string[],
76
- fallback: string,
77
- ): string {
78
- if (value === undefined) return fallback;
79
- if (typeof value === "number") return palette[value] ?? fallback;
80
- return value;
81
- }
82
-
83
- /** Resolve semantic colors with fallbacks to default palette slots */
84
- export function resolveSemanticColors(scheme: ColorScheme) {
85
- const p = scheme.palette;
86
- return {
87
- surface: resolveColor(scheme.semantic?.surface, p, p[0]),
88
- muted: resolveColor(scheme.semantic?.muted, p, p[8]),
89
- accent: resolveColor(scheme.semantic?.accent, p, p[5]),
90
- accentHover: resolveColor(scheme.semantic?.accentHover, p, p[14]),
91
- codeBg: resolveColor(scheme.semantic?.codeBg, p, p[10]),
92
- codeFg: resolveColor(scheme.semantic?.codeFg, p, p[11]),
93
- success: resolveColor(scheme.semantic?.success, p, p[2]),
94
- danger: resolveColor(scheme.semantic?.danger, p, p[1]),
95
- warning: resolveColor(scheme.semantic?.warning, p, p[3]),
96
- info: resolveColor(scheme.semantic?.info, p, p[4]),
97
- mermaidNodeBg: resolveColor(scheme.semantic?.mermaidNodeBg, p, p[9]),
98
- mermaidText: resolveColor(scheme.semantic?.mermaidText, p, p[11]),
99
- mermaidLine: resolveColor(scheme.semantic?.mermaidLine, p, p[8]),
100
- mermaidLabelBg: resolveColor(scheme.semantic?.mermaidLabelBg, p, p[10]),
101
- mermaidNoteBg: resolveColor(scheme.semantic?.mermaidNoteBg, p, p[0]),
102
- chatUserBg: resolveColor(scheme.semantic?.chatUserBg, p, p[5]),
103
- chatUserText: resolveColor(scheme.semantic?.chatUserText, p, p[9]),
104
- chatAssistantBg: resolveColor(scheme.semantic?.chatAssistantBg, p, p[9]),
105
- chatAssistantText: resolveColor(scheme.semantic?.chatAssistantText, p, p[11]),
106
- imageOverlayBg: resolveColor(scheme.semantic?.imageOverlayBg, p, p[0]),
107
- imageOverlayFg: resolveColor(scheme.semantic?.imageOverlayFg, p, p[11]),
108
- matchedKeywordBg: resolveColor(scheme.semantic?.matchedKeywordBg, p, p[3]),
109
- matchedKeywordFg: resolveColor(scheme.semantic?.matchedKeywordFg, p, p[15]),
110
- };
111
- }
112
-
113
- export function schemeToCssPairs(scheme: ColorScheme): [string, string][] {
114
- const p = scheme.palette;
115
- const sem = resolveSemanticColors(scheme);
116
- return [
117
- ["--zd-bg", resolveColor(scheme.background, p, p[0])],
118
- ["--zd-fg", resolveColor(scheme.foreground, p, p[15])],
119
- ["--zd-cursor", resolveColor(scheme.cursor, p, p[6])], // intentionally inert/vestigial: exposed in the design-token panel but no CSS rule consumes it (no caret-color wiring); mirrors shikiTheme's status
120
- ["--zd-sel-bg", resolveColor(scheme.selectionBg, p, resolveColor(scheme.background, p, p[0]))],
121
- ["--zd-sel-fg", resolveColor(scheme.selectionFg, p, resolveColor(scheme.foreground, p, p[15]))],
122
- ...p.map((color, i) => [`--zd-${i}`, color] as [string, string]),
123
- ["--zd-surface", sem.surface],
124
- ["--zd-muted", sem.muted],
125
- ["--zd-accent", sem.accent],
126
- ["--zd-accent-hover", sem.accentHover],
127
- ["--zd-code-bg", sem.codeBg],
128
- ["--zd-code-fg", sem.codeFg],
129
- ["--zd-success", sem.success],
130
- ["--zd-danger", sem.danger],
131
- ["--zd-warning", sem.warning],
132
- ["--zd-info", sem.info],
133
- ["--zd-mermaid-node-bg", sem.mermaidNodeBg],
134
- ["--zd-mermaid-text", sem.mermaidText],
135
- ["--zd-mermaid-line", sem.mermaidLine],
136
- ["--zd-mermaid-label-bg", sem.mermaidLabelBg],
137
- ["--zd-mermaid-note-bg", sem.mermaidNoteBg],
138
- ["--zd-chat-user-bg", sem.chatUserBg],
139
- ["--zd-chat-user-text", sem.chatUserText],
140
- ["--zd-chat-assistant-bg", sem.chatAssistantBg],
141
- ["--zd-chat-assistant-text", sem.chatAssistantText],
142
- ["--zd-image-overlay-bg", sem.imageOverlayBg],
143
- ["--zd-image-overlay-fg", sem.imageOverlayFg],
144
- ["--zd-matched-keyword-bg", sem.matchedKeywordBg],
145
- ["--zd-matched-keyword-fg", sem.matchedKeywordFg],
146
- ];
147
- }
148
-
44
+ /** Generate `:root { --zd-* }` CSS for the project's active single scheme. */
149
45
  export function generateCssCustomProperties(): string {
150
- const scheme = getActiveScheme();
151
- const pairs = schemeToCssPairs(scheme);
152
- const lines = [":root {", ...pairs.map(([prop, value]) => ` ${prop}: ${value};`), "}"];
153
- return lines.join("\n");
46
+ return _generateCssCustomProperties(getActiveScheme());
154
47
  }
155
48
 
49
+ /** Generate `:root { --zd-*: light-dark(…) }` CSS for the project's configured light/dark pair. */
156
50
  export function generateLightDarkCssProperties(): string {
157
51
  if (!settings.colorMode) {
158
52
  throw new Error("colorMode is not configured");
@@ -162,23 +56,5 @@ export function generateLightDarkCssProperties(): string {
162
56
  const dark = colorSchemes[darkScheme];
163
57
  if (!light) throw new Error(`Unknown light scheme: "${lightScheme}"`);
164
58
  if (!dark) throw new Error(`Unknown dark scheme: "${darkScheme}"`);
165
-
166
- const lightPairs = schemeToCssPairs(light);
167
- const darkPairs = schemeToCssPairs(dark);
168
-
169
- if (lightPairs.length !== darkPairs.length) {
170
- throw new Error(`Light scheme has ${lightPairs.length} properties but dark scheme has ${darkPairs.length}`);
171
- }
172
-
173
- const lines = [":root {", " color-scheme: light dark;"];
174
- for (let i = 0; i < lightPairs.length; i++) {
175
- const lightPair = lightPairs[i];
176
- const darkPair = darkPairs[i];
177
- if (!lightPair || !darkPair) continue;
178
- const [prop, lightVal] = lightPair;
179
- const darkVal = darkPair[1];
180
- lines.push(` ${prop}: light-dark(${lightVal}, ${darkVal});`);
181
- }
182
- lines.push("}");
183
- return lines.join("\n");
59
+ return _generateLightDarkCssProperties(light, dark);
184
60
  }
@@ -74,6 +74,9 @@ const translations: Record<string, Record<string, string>> = {
74
74
  "search.placeholder": "Type to search...",
75
75
  "search.shortcutHint": "to open search from anywhere",
76
76
  "search.resultCount": "{count} results",
77
+ "search.unavailable": "Search unavailable",
78
+ "search.loadingIndex": "Loading search index…",
79
+ "search.noResults": "No results found.",
77
80
  "code.copy": "Copy code",
78
81
  "code.copied": "Copied!",
79
82
  "code.wrapToggle": "Toggle word wrap",
@@ -134,6 +137,9 @@ const translations: Record<string, Record<string, string>> = {
134
137
  "search.placeholder": "検索したい単語を入力",
135
138
  "search.shortcutHint": "いつでも検索バーを開ける",
136
139
  "search.resultCount": "{count} 件",
140
+ "search.unavailable": "検索を利用できません",
141
+ "search.loadingIndex": "検索インデックスを読み込み中…",
142
+ "search.noResults": "検索結果が見つかりませんでした。",
137
143
  "code.copy": "コードをコピー",
138
144
  "code.copied": "コピーしました!",
139
145
  "code.wrapToggle": "折り返し切替",
@@ -194,6 +200,9 @@ const translations: Record<string, Record<string, string>> = {
194
200
  "search.placeholder": "Suchbegriff eingeben...",
195
201
  "search.shortcutHint": "Suche von überall öffnen",
196
202
  "search.resultCount": "{count} Ergebnisse",
203
+ "search.unavailable": "Suche nicht verfügbar",
204
+ "search.loadingIndex": "Suchindex wird geladen…",
205
+ "search.noResults": "Keine Ergebnisse gefunden.",
197
206
  "code.copy": "Code kopieren",
198
207
  "code.copied": "Kopiert!",
199
208
  "code.wrapToggle": "Zeilenumbruch umschalten",
@@ -1,10 +1,11 @@
1
1
  // z-index design tokens — single source of truth.
2
2
  //
3
3
  // This file is the ONE place z-index tiers are defined. The CSS `@theme` block
4
- // in `src/styles/global.css` is GENERATED from this list by
5
- // `scripts/gen-z-index.mjs` (run `pnpm gen:z-index`); never hand-edit the
6
- // generated block. `pnpm check:z-index` re-runs the generator into a buffer and
7
- // fails on drift, so the committed CSS can never silently diverge from this list.
4
+ // in `src/styles/global.css` is GENERATED from this list by the
5
+ // `gen-z-index` bin from `@takazudo/zudo-doc` (run `pnpm gen:z-index`); never
6
+ // hand-edit the generated block. `pnpm check:z-index` re-runs the generator
7
+ // into a buffer and fails on drift, so the committed CSS can never silently
8
+ // diverge from this list.
8
9
  //
9
10
  // Strategy (from zudolab/zudo-css-wisdom z-index-strategy): semantic single-
10
11
  // namespace tokens — names describe ROLES, never magnitudes. One flat ordered