kitfly 0.1.2 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +46 -0
- package/README.md +63 -16
- package/VERSION +1 -1
- package/dist/_raw/content/deployment/preflight.md +134 -0
- package/dist/_raw/content/deployment/recipes/aws-s3.md +128 -0
- package/dist/_raw/content/deployment/recipes/cloudflare-pages.md +73 -0
- package/dist/_raw/content/deployment/recipes/cloudflare-r2.md +156 -0
- package/dist/_raw/content/deployment/recipes/fly-io.md +57 -0
- package/dist/_raw/content/deployment/recipes/github-pages.md +112 -0
- package/dist/_raw/content/deployment/recipes/netlify.md +99 -0
- package/dist/_raw/content/deployment/recipes/vercel.md +88 -0
- package/dist/_raw/content/deployment/secrets-and-env-vars.md +75 -0
- package/dist/_raw/content/deployment.md +128 -0
- package/dist/_raw/content/guide/approaches.md +182 -0
- package/dist/_raw/content/guide/features.md +121 -0
- package/dist/_raw/content/guide/getting-started.md +112 -0
- package/dist/_raw/content/guide/kitfly-overview.md +209 -0
- package/dist/_raw/content/reference/configuration.md +259 -0
- package/dist/_raw/content/reference/design-catalog.md +167 -0
- package/dist/_raw/content/reference/environment-variables.md +66 -0
- package/dist/_raw/content/reference/glossary.md +92 -0
- package/dist/_raw/content/reference/key-concepts.md +118 -0
- package/dist/_raw/content/reference/plugins.md +220 -0
- package/dist/_raw/content/reference/slides-authoring-guidelines.md +129 -0
- package/dist/_raw/content/reference/structure.md +166 -0
- package/dist/_raw/content/reference.md +20 -0
- package/dist/_raw/content/templates/crucible.md +192 -0
- package/dist/_raw/content/templates/handbook.md +83 -0
- package/dist/_raw/content/templates/minimal.md +138 -0
- package/dist/_raw/content/templates/overview.md +187 -0
- package/dist/_raw/content/templates/pipeline.md +151 -0
- package/dist/_raw/content/templates/productbook.md +187 -0
- package/dist/_raw/content/templates/runbook.md +193 -0
- package/dist/_raw/content/templates/servicebook.md +163 -0
- package/dist/_raw/docs/decisions/ADR-0001-minimalist-site-code.md +118 -0
- package/dist/_raw/docs/decisions/ADR-0002-ai-accessibility.md +153 -0
- package/dist/_raw/docs/decisions/ADR-0003-single-file-bundle.md +93 -0
- package/dist/_raw/docs/decisions/ADR-0004-bun-runtime.md +98 -0
- package/dist/_raw/docs/decisions/ADR-0005-plugin-contract-and-distribution.md +110 -0
- package/dist/_raw/docs/decisions/DDR-0001-viewport-locked-layout.md +111 -0
- package/dist/_raw/docs/decisions/DDR-0002-theme-system.md +131 -0
- package/dist/_raw/docs/decisions/DDR-0003-bounded-logo-slot.md +106 -0
- package/dist/_raw/docs/decisions/DDR-0004-slides-rendering-model.md +113 -0
- package/dist/_raw/docs/decisions/DDR-0005-deterministic-layout-boundary.md +107 -0
- package/dist/_raw/docs/userguide/cli/build.md +85 -0
- package/dist/_raw/docs/userguide/cli/bundle.md +81 -0
- package/dist/_raw/docs/userguide/cli/dev.md +92 -0
- package/dist/_raw/docs/userguide/cli/init.md +116 -0
- package/dist/_raw/docs/userguide/cli/servers.md +69 -0
- package/dist/_raw/docs/userguide/cli/stop.md +76 -0
- package/dist/_raw/docs/userguide/cli/update.md +78 -0
- package/dist/_raw/docs/userguide/cli/version.md +65 -0
- package/dist/_raw/docs/userguide/cli.md +34 -0
- package/dist/_raw/docs/userguide/sharing.md +94 -0
- package/dist/_raw/schemas/plugin-schemas-notes.md +71 -0
- package/dist/_raw/schemas.md +42 -0
- package/dist/assets/brand/kitfly-favicon-32.png +0 -0
- package/dist/assets/brand/kitfly-icon-64.png +0 -0
- package/dist/assets/brand/kitfly-logo-128.png +0 -0
- package/dist/assets/brand/kitfly-logo-512.png +0 -0
- package/dist/assets/brand/kitfly-logo.svg +12132 -0
- package/dist/assets/brand/kitfly-neon-128.png +0 -0
- package/dist/assets/brand/kitfly-neon-192.png +0 -0
- package/dist/assets/brand/kitfly-neon-256.png +0 -0
- package/dist/assets/brand/kitfly-neon.png +0 -0
- package/dist/assets/brand/palette.md +75 -0
- package/dist/content/deployment/index.html +11 -0
- package/dist/content/deployment/preflight.html +418 -0
- package/dist/content/deployment/recipes/aws-s3.html +421 -0
- package/dist/content/deployment/recipes/cloudflare-pages.html +372 -0
- package/dist/content/deployment/recipes/cloudflare-r2.html +443 -0
- package/dist/content/deployment/recipes/fly-io.html +356 -0
- package/dist/content/deployment/recipes/github-pages.html +414 -0
- package/dist/content/deployment/recipes/index.html +11 -0
- package/dist/content/deployment/recipes/netlify.html +394 -0
- package/dist/content/deployment/recipes/vercel.html +382 -0
- package/dist/content/deployment/secrets-and-env-vars.html +380 -0
- package/dist/content/deployment.html +426 -0
- package/dist/content/guide/approaches.html +501 -0
- package/dist/content/guide/features.html +436 -0
- package/dist/content/guide/getting-started.html +403 -0
- package/dist/content/guide/index.html +11 -0
- package/dist/content/guide/kitfly-overview.html +544 -0
- package/dist/content/index.html +11 -0
- package/dist/content/reference/configuration.html +580 -0
- package/dist/content/reference/design-catalog.html +449 -0
- package/dist/content/reference/environment-variables.html +367 -0
- package/dist/content/reference/glossary.html +368 -0
- package/dist/content/reference/index.html +11 -0
- package/dist/content/reference/key-concepts.html +399 -0
- package/dist/content/reference/plugins.html +491 -0
- package/dist/content/reference/slides-authoring-guidelines.html +418 -0
- package/dist/content/reference/structure.html +463 -0
- package/dist/content/reference.html +335 -0
- package/dist/content/templates/crucible.html +546 -0
- package/dist/content/templates/handbook.html +405 -0
- package/dist/content/templates/index.html +11 -0
- package/dist/content/templates/minimal.html +447 -0
- package/dist/content/templates/overview.html +558 -0
- package/dist/content/templates/pipeline.html +494 -0
- package/dist/content/templates/productbook.html +540 -0
- package/dist/content/templates/runbook.html +543 -0
- package/dist/content/templates/servicebook.html +523 -0
- package/dist/content-index.json +549 -0
- package/dist/docs/decisions/ADR-0001-minimalist-site-code.html +491 -0
- package/dist/docs/decisions/ADR-0002-ai-accessibility.html +434 -0
- package/dist/docs/decisions/ADR-0003-single-file-bundle.html +412 -0
- package/dist/docs/decisions/ADR-0004-bun-runtime.html +409 -0
- package/dist/docs/decisions/ADR-0005-plugin-contract-and-distribution.html +402 -0
- package/dist/docs/decisions/DDR-0001-viewport-locked-layout.html +459 -0
- package/dist/docs/decisions/DDR-0002-theme-system.html +452 -0
- package/dist/docs/decisions/DDR-0003-bounded-logo-slot.html +423 -0
- package/dist/docs/decisions/DDR-0004-slides-rendering-model.html +399 -0
- package/dist/docs/decisions/DDR-0005-deterministic-layout-boundary.html +422 -0
- package/dist/docs/decisions/index.html +11 -0
- package/dist/docs/userguide/cli/build.html +408 -0
- package/dist/docs/userguide/cli/bundle.html +419 -0
- package/dist/docs/userguide/cli/dev.html +428 -0
- package/dist/docs/userguide/cli/index.html +11 -0
- package/dist/docs/userguide/cli/init.html +436 -0
- package/dist/docs/userguide/cli/servers.html +393 -0
- package/dist/docs/userguide/cli/stop.html +408 -0
- package/dist/docs/userguide/cli/update.html +406 -0
- package/dist/docs/userguide/cli/version.html +406 -0
- package/dist/docs/userguide/cli.html +386 -0
- package/dist/docs/userguide/index.html +11 -0
- package/dist/docs/userguide/sharing.html +465 -0
- package/dist/index.html +387 -0
- package/dist/llms.txt +18 -0
- package/dist/provenance.json +7 -0
- package/dist/schemas/index.html +11 -0
- package/dist/schemas/plugin-registry.schema.html +327 -0
- package/dist/schemas/plugin-schemas-notes.html +364 -0
- package/dist/schemas/plugin.schema.html +327 -0
- package/dist/schemas/plugins.schema.html +327 -0
- package/dist/schemas/v0/common.schema.html +386 -0
- package/dist/schemas/v0/index.html +11 -0
- package/dist/schemas/v0/plugin-registry.schema.html +547 -0
- package/dist/schemas/v0/plugin.schema.html +497 -0
- package/dist/schemas/v0/plugins.schema.html +406 -0
- package/dist/schemas/v0/site.schema.html +541 -0
- package/dist/schemas/v0/theme.schema.html +615 -0
- package/dist/schemas.html +351 -0
- package/dist/styles.css +1262 -0
- package/package.json +4 -2
- package/plugins-dist/callouts.css +32 -0
- package/plugins-dist/callouts.js +46 -0
- package/plugins-dist/slides-visuals.css +390 -0
- package/plugins-dist/slides-visuals.js +689 -0
- package/registry/plugins.yaml +35 -0
- package/schemas/README.md +10 -0
- package/schemas/plugin-registry.schema.json +5 -0
- package/schemas/plugin-schemas-notes.md +71 -0
- package/schemas/plugin.schema.json +5 -0
- package/schemas/plugins.schema.json +5 -0
- package/schemas/v0/common.schema.json +64 -0
- package/schemas/v0/plugin-registry.schema.json +225 -0
- package/schemas/v0/plugin.schema.json +175 -0
- package/schemas/v0/plugins.schema.json +84 -0
- package/schemas/v0/site.schema.json +56 -9
- package/schemas/v0/theme.schema.json +105 -22
- package/scripts/build.ts +158 -3
- package/scripts/bundle.ts +261 -95
- package/scripts/dev.ts +301 -11
- package/src/__tests__/build.test.ts +220 -1
- package/src/__tests__/bundle.test.ts +31 -0
- package/src/__tests__/cli.test.ts +14 -3
- package/src/__tests__/dev-plugin-errors.test.ts +20 -0
- package/src/__tests__/fixtures/fences/slides-visuals/invalid/bad-list-indent.md +5 -0
- package/src/__tests__/fixtures/fences/slides-visuals/invalid/blank-line.md +5 -0
- package/src/__tests__/fixtures/fences/slides-visuals/invalid/compare-object-items.md +9 -0
- package/src/__tests__/fixtures/fences/slides-visuals/invalid/flow-branching-no-source.md +5 -0
- package/src/__tests__/fixtures/fences/slides-visuals/invalid/flow-converging-no-target.md +6 -0
- package/src/__tests__/fixtures/fences/slides-visuals/invalid/indented-fence.md +4 -0
- package/src/__tests__/fixtures/fences/slides-visuals/invalid/staircase-empty-steps.md +3 -0
- package/src/__tests__/fixtures/fences/slides-visuals/invalid/stat-grid-missing-fields.md +5 -0
- package/src/__tests__/fixtures/fences/slides-visuals/invalid/timeline-horizontal-no-events.md +2 -0
- package/src/__tests__/fixtures/fences/slides-visuals/invalid/unknown-type.md +3 -0
- package/src/__tests__/fixtures/fences/slides-visuals/valid/compare.md +10 -0
- package/src/__tests__/fixtures/fences/slides-visuals/valid/comparison-table.md +14 -0
- package/src/__tests__/fixtures/fences/slides-visuals/valid/flow-branching-no-split.md +7 -0
- package/src/__tests__/fixtures/fences/slides-visuals/valid/flow-branching.md +8 -0
- package/src/__tests__/fixtures/fences/slides-visuals/valid/flow-converging-no-merge.md +7 -0
- package/src/__tests__/fixtures/fences/slides-visuals/valid/flow-converging.md +8 -0
- package/src/__tests__/fixtures/fences/slides-visuals/valid/funnel.md +7 -0
- package/src/__tests__/fixtures/fences/slides-visuals/valid/kpi.md +5 -0
- package/src/__tests__/fixtures/fences/slides-visuals/valid/layer-cake.md +6 -0
- package/src/__tests__/fixtures/fences/slides-visuals/valid/pyramid.md +6 -0
- package/src/__tests__/fixtures/fences/slides-visuals/valid/quadrant-grid.md +8 -0
- package/src/__tests__/fixtures/fences/slides-visuals/valid/scorecard.md +13 -0
- package/src/__tests__/fixtures/fences/slides-visuals/valid/staircase-down.md +7 -0
- package/src/__tests__/fixtures/fences/slides-visuals/valid/staircase.md +8 -0
- package/src/__tests__/fixtures/fences/slides-visuals/valid/stat-grid.md +8 -0
- package/src/__tests__/fixtures/fences/slides-visuals/valid/timeline-horizontal.md +9 -0
- package/src/__tests__/fixtures/fences/slides-visuals/valid/timeline-vertical.md +10 -0
- package/src/__tests__/init.test.ts +35 -0
- package/src/__tests__/plugin-loader.test.ts +221 -0
- package/src/__tests__/shared.test.ts +451 -0
- package/src/__tests__/slides-visuals-fence-contract.test.ts +28 -0
- package/src/__tests__/slides-visuals-runtime-regressions.bun.test.ts +147 -0
- package/src/__tests__/styles.test.ts +35 -0
- package/src/cli.ts +9 -4
- package/src/plugin-loader.ts +245 -0
- package/src/shared.ts +650 -7
- package/src/site/styles.css +331 -0
- package/src/site/template.html +66 -5
- package/src/templates/deck.ts +186 -0
- package/src/templates/driver.ts +11 -1
- package/src/templates/minimal.ts +1 -0
|
@@ -0,0 +1,558 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8">
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
6
|
+
<title>Templates Overview - Kitfly Docs</title>
|
|
7
|
+
<link rel="icon" type="image/png" sizes="32x32" href="../../assets/brand/kitfly-favicon-32.png">
|
|
8
|
+
<link rel="icon" type="image/png" sizes="64x64" href="../../assets/brand/kitfly-neon-256.png">
|
|
9
|
+
<link rel="stylesheet" href="../../styles.css">
|
|
10
|
+
<style id="kitfly-theme">
|
|
11
|
+
:root { --color-bg: #ffffff;
|
|
12
|
+
--color-bg-sidebar: #f5f7f8;
|
|
13
|
+
--color-text: #374151;
|
|
14
|
+
--color-text-muted: #6b7280;
|
|
15
|
+
--color-border: #e5e7eb;
|
|
16
|
+
--color-link: #007182;
|
|
17
|
+
--color-link-hover: #0a6172;
|
|
18
|
+
--color-accent: #152F46;
|
|
19
|
+
--color-code-bg: #f5f7f8;
|
|
20
|
+
--color-logo: #152F46;
|
|
21
|
+
--sidebar-width: 280px;
|
|
22
|
+
--font-sans: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
|
|
23
|
+
--font-headings: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
|
|
24
|
+
--font-mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace; }
|
|
25
|
+
html { font-size: 16px; }
|
|
26
|
+
@media (prefers-color-scheme: dark) {
|
|
27
|
+
:root:not([data-theme="light"]) { --color-bg: #0d1117;
|
|
28
|
+
--color-bg-sidebar: #152F46;
|
|
29
|
+
--color-text: #e5e7eb;
|
|
30
|
+
--color-text-muted: #9ca3af;
|
|
31
|
+
--color-border: #374151;
|
|
32
|
+
--color-link: #709EA6;
|
|
33
|
+
--color-link-hover: #8fb5bc;
|
|
34
|
+
--color-accent: #f9fafb;
|
|
35
|
+
--color-code-bg: #152F46;
|
|
36
|
+
--color-logo: #f9fafb; }
|
|
37
|
+
}
|
|
38
|
+
[data-theme="dark"] { --color-bg: #0d1117;
|
|
39
|
+
--color-bg-sidebar: #152F46;
|
|
40
|
+
--color-text: #e5e7eb;
|
|
41
|
+
--color-text-muted: #9ca3af;
|
|
42
|
+
--color-border: #374151;
|
|
43
|
+
--color-link: #709EA6;
|
|
44
|
+
--color-link-hover: #8fb5bc;
|
|
45
|
+
--color-accent: #f9fafb;
|
|
46
|
+
--color-code-bg: #152F46;
|
|
47
|
+
--color-logo: #f9fafb; }
|
|
48
|
+
[data-theme="light"] { --color-bg: #ffffff;
|
|
49
|
+
--color-bg-sidebar: #f5f7f8;
|
|
50
|
+
--color-text: #374151;
|
|
51
|
+
--color-text-muted: #6b7280;
|
|
52
|
+
--color-border: #e5e7eb;
|
|
53
|
+
--color-link: #007182;
|
|
54
|
+
--color-link-hover: #0a6172;
|
|
55
|
+
--color-accent: #152F46;
|
|
56
|
+
--color-code-bg: #f5f7f8;
|
|
57
|
+
--color-logo: #152F46;
|
|
58
|
+
--sidebar-width: 280px;
|
|
59
|
+
--font-sans: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
|
|
60
|
+
--font-headings: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
|
|
61
|
+
--font-mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace; }
|
|
62
|
+
</style>
|
|
63
|
+
<!-- Syntax highlighting - Prism.js -->
|
|
64
|
+
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/prismjs@1/themes/prism.min.css" id="prism-light">
|
|
65
|
+
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/prismjs@1/themes/prism-okaidia.min.css" id="prism-dark" disabled>
|
|
66
|
+
|
|
67
|
+
<script>
|
|
68
|
+
// Apply saved theme immediately to prevent flash
|
|
69
|
+
(function() {
|
|
70
|
+
const saved = localStorage.getItem('theme');
|
|
71
|
+
if (saved) {
|
|
72
|
+
document.documentElement.setAttribute('data-theme', saved);
|
|
73
|
+
}
|
|
74
|
+
// Set Prism theme based on saved or system preference
|
|
75
|
+
const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
|
|
76
|
+
const isDark = saved === 'dark' || (!saved && prefersDark);
|
|
77
|
+
if (isDark) {
|
|
78
|
+
document.getElementById('prism-light')?.setAttribute('disabled', '');
|
|
79
|
+
document.getElementById('prism-dark')?.removeAttribute('disabled');
|
|
80
|
+
}
|
|
81
|
+
})();
|
|
82
|
+
</script>
|
|
83
|
+
</head>
|
|
84
|
+
<body class="mode-docs">
|
|
85
|
+
<div class="mobile-header">
|
|
86
|
+
<button class="nav-toggle" onclick="toggleNav()" aria-label="Toggle navigation">
|
|
87
|
+
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
|
88
|
+
<path d="M3 12h18M3 6h18M3 18h18"/>
|
|
89
|
+
</svg>
|
|
90
|
+
</button>
|
|
91
|
+
<a href="../../" class="mobile-logo" title="Home" data-initial="K">
|
|
92
|
+
<img src="../../assets/brand/kitfly-neon-256.png" alt="Kitfly" class="logo-img logo-icon" onerror="this.onerror=null;this.style.display='none';this.parentElement.classList.add('logo-fallback')"/>
|
|
93
|
+
</a>
|
|
94
|
+
<button class="mobile-theme-toggle" onclick="toggleTheme()" title="Toggle theme" aria-label="Toggle theme">
|
|
95
|
+
<svg class="icon-sun" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
|
96
|
+
<circle cx="12" cy="12" r="5"/>
|
|
97
|
+
<path d="M12 1v2M12 21v2M4.22 4.22l1.42 1.42M18.36 18.36l1.42 1.42M1 12h2M21 12h2M4.22 19.78l1.42-1.42M18.36 5.64l1.42-1.42"/>
|
|
98
|
+
</svg>
|
|
99
|
+
<svg class="icon-moon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
|
100
|
+
<path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z"/>
|
|
101
|
+
</svg>
|
|
102
|
+
</button>
|
|
103
|
+
</div>
|
|
104
|
+
<div class="layout">
|
|
105
|
+
<nav class="sidebar">
|
|
106
|
+
<div class="sidebar-header">
|
|
107
|
+
<div class="logo logo-icon">
|
|
108
|
+
<a href="/" class="logo-icon" data-initial="K">
|
|
109
|
+
<img src="../../assets/brand/kitfly-neon-256.png" alt="Kitfly" class="logo-img" onerror="this.onerror=null;this.style.display='none';this.parentElement.classList.add('logo-fallback')"/>
|
|
110
|
+
</a>
|
|
111
|
+
<span class="logo-text">
|
|
112
|
+
<a href="/" class="brand">Kitfly</a>
|
|
113
|
+
<a href="../../" class="product">Kitfly Docs</a>
|
|
114
|
+
</span>
|
|
115
|
+
</div>
|
|
116
|
+
<div class="header-tools">
|
|
117
|
+
<button class="theme-toggle" onclick="toggleTheme()" title="Toggle theme" aria-label="Toggle theme">
|
|
118
|
+
<svg class="icon-sun" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
|
119
|
+
<circle cx="12" cy="12" r="5"/>
|
|
120
|
+
<path d="M12 1v2M12 21v2M4.22 4.22l1.42 1.42M18.36 18.36l1.42 1.42M1 12h2M21 12h2M4.22 19.78l1.42-1.42M18.36 5.64l1.42-1.42"/>
|
|
121
|
+
</svg>
|
|
122
|
+
<svg class="icon-moon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
|
123
|
+
<path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z"/>
|
|
124
|
+
</svg>
|
|
125
|
+
</button>
|
|
126
|
+
<div class="sidebar-meta">
|
|
127
|
+
<span class="meta-version">v0.2.1</span>
|
|
128
|
+
<span class="meta-branch">HEAD</span>
|
|
129
|
+
</div>
|
|
130
|
+
</div>
|
|
131
|
+
</div>
|
|
132
|
+
<div class="sidebar-nav">
|
|
133
|
+
<ul><li><a href="../../index.html" class="nav-home">Home</a></li><li><span class="nav-section">Guide</span><ul><li><a href="../../content/guide/approaches.html">approaches</a></li><li><a href="../../content/guide/features.html">features</a></li><li><a href="../../content/guide/getting-started.html">getting-started</a></li><li><a href="../../content/guide/kitfly-overview.html">kitfly-overview</a></li></ul></li><li><span class="nav-section">Templates</span><ul><li><a href="../../content/templates/crucible.html">crucible</a></li><li><a href="../../content/templates/handbook.html">handbook</a></li><li><a href="../../content/templates/minimal.html">minimal</a></li><li><a href="../../content/templates/overview.html" class="active">overview</a></li><li><a href="../../content/templates/pipeline.html">pipeline</a></li><li><a href="../../content/templates/productbook.html">productbook</a></li><li><a href="../../content/templates/runbook.html">runbook</a></li><li><a href="../../content/templates/servicebook.html">servicebook</a></li></ul></li><li><a href="../../content/reference.html" class="nav-section">Reference</a><ul><li><a href="../../content/reference/configuration.html">configuration</a></li><li><a href="../../content/reference/design-catalog.html">design-catalog</a></li><li><a href="../../content/reference/environment-variables.html">environment-variables</a></li><li><a href="../../content/reference/glossary.html">glossary</a></li><li><a href="../../content/reference/key-concepts.html">key-concepts</a></li><li><a href="../../content/reference/plugins.html">plugins</a></li><li><a href="../../content/reference/slides-authoring-guidelines.html">slides-authoring-guidelines</a></li><li><a href="../../content/reference/structure.html">structure</a></li></ul></li><li><a href="../../content/deployment.html" class="nav-section">Deployment</a><ul><li><a href="../../content/deployment/preflight.html">preflight</a></li><li><details><summary class="nav-group">recipes</summary><ul><li><a href="../../content/deployment/recipes/aws-s3.html">aws-s3</a></li><li><a href="../../content/deployment/recipes/cloudflare-pages.html">cloudflare-pages</a></li><li><a href="../../content/deployment/recipes/cloudflare-r2.html">cloudflare-r2</a></li><li><a href="../../content/deployment/recipes/fly-io.html">fly-io</a></li><li><a href="../../content/deployment/recipes/github-pages.html">github-pages</a></li><li><a href="../../content/deployment/recipes/netlify.html">netlify</a></li><li><a href="../../content/deployment/recipes/vercel.html">vercel</a></li></ul></details></li><li><a href="../../content/deployment/secrets-and-env-vars.html">secrets-and-env-vars</a></li></ul></li><li><span class="nav-section">User Guide</span><ul><li><details><summary class="nav-group"><a href="../../docs/userguide/cli.html">cli</a></summary><ul><li><a href="../../docs/userguide/cli/build.html">build</a></li><li><a href="../../docs/userguide/cli/bundle.html">bundle</a></li><li><a href="../../docs/userguide/cli/dev.html">dev</a></li><li><a href="../../docs/userguide/cli/init.html">init</a></li><li><a href="../../docs/userguide/cli/servers.html">servers</a></li><li><a href="../../docs/userguide/cli/stop.html">stop</a></li><li><a href="../../docs/userguide/cli/update.html">update</a></li><li><a href="../../docs/userguide/cli/version.html">version</a></li></ul></details></li><li><a href="../../docs/userguide/sharing.html">sharing</a></li></ul></li><li><span class="nav-section">Decisions</span><ul><li><a href="../../docs/decisions/ADR-0001-minimalist-site-code.html">ADR-0001-minimalist-site-code</a></li><li><a href="../../docs/decisions/ADR-0002-ai-accessibility.html">ADR-0002-ai-accessibility</a></li><li><a href="../../docs/decisions/ADR-0003-single-file-bundle.html">ADR-0003-single-file-bundle</a></li><li><a href="../../docs/decisions/ADR-0004-bun-runtime.html">ADR-0004-bun-runtime</a></li><li><a href="../../docs/decisions/ADR-0005-plugin-contract-and-distribution.html">ADR-0005-plugin-contract-and-distribution</a></li><li><a href="../../docs/decisions/DDR-0001-viewport-locked-layout.html">DDR-0001-viewport-locked-layout</a></li><li><a href="../../docs/decisions/DDR-0002-theme-system.html">DDR-0002-theme-system</a></li><li><a href="../../docs/decisions/DDR-0003-bounded-logo-slot.html">DDR-0003-bounded-logo-slot</a></li><li><a href="../../docs/decisions/DDR-0004-slides-rendering-model.html">DDR-0004-slides-rendering-model</a></li><li><a href="../../docs/decisions/DDR-0005-deterministic-layout-boundary.html">DDR-0005-deterministic-layout-boundary</a></li></ul></li><li><a href="../../schemas.html" class="nav-section">Schemas</a><ul><li><a href="../../schemas/plugin-registry.schema.html">plugin-registry.schema</a></li><li><a href="../../schemas/plugin-schemas-notes.html">plugin-schemas-notes</a></li><li><a href="../../schemas/plugin.schema.html">plugin.schema</a></li><li><a href="../../schemas/plugins.schema.html">plugins.schema</a></li><li><details><summary class="nav-group">v0</summary><ul><li><a href="../../schemas/v0/common.schema.html">common.schema</a></li><li><a href="../../schemas/v0/plugin-registry.schema.html">plugin-registry.schema</a></li><li><a href="../../schemas/v0/plugin.schema.html">plugin.schema</a></li><li><a href="../../schemas/v0/plugins.schema.html">plugins.schema</a></li><li><a href="../../schemas/v0/site.schema.html">site.schema</a></li><li><a href="../../schemas/v0/theme.schema.html">theme.schema</a></li></ul></details></li></ul></li></ul>
|
|
134
|
+
</div>
|
|
135
|
+
</nav>
|
|
136
|
+
<main class="content">
|
|
137
|
+
<article class="prose">
|
|
138
|
+
<nav class="breadcrumbs"><a href="../../content/guide/approaches.html">Content</a><span class="separator">›</span><a href="../../content/templates/crucible.html">Templates</a><span class="separator">›</span><span>overview</span></nav>
|
|
139
|
+
|
|
140
|
+
<h1 id="templates">Templates</h1>
|
|
141
|
+
<p>Templates provide starting points for new kitfly sites. Each template creates a folder structure, configuration, and starter content appropriate for a specific use case.</p>
|
|
142
|
+
<h2 id="the-layering-model">The Layering Model</h2>
|
|
143
|
+
<p>Templates follow a simple inheritance pattern:</p>
|
|
144
|
+
<pre><code>minimal (base)
|
|
145
|
+
├── handbook (team documentation)
|
|
146
|
+
├── runbook (operational procedures)
|
|
147
|
+
├── pipeline (data pipeline operations)
|
|
148
|
+
├── productbook (product & domain knowledge)
|
|
149
|
+
├── servicebook (professional services catalog)
|
|
150
|
+
└── crucible (information architecture SSOT)
|
|
151
|
+
</code></pre>
|
|
152
|
+
<p>Every template <strong>extends <code>minimal</code></strong>, which provides the essential files every site needs. Specialized templates add sections and starter content on top.</p>
|
|
153
|
+
<h2 id="what-templates-create">What Templates Create</h2>
|
|
154
|
+
<p>When you run <code>kitfly init</code>, the template generates:</p>
|
|
155
|
+
<table>
|
|
156
|
+
<thead>
|
|
157
|
+
<tr>
|
|
158
|
+
<th>Component</th>
|
|
159
|
+
<th>Source</th>
|
|
160
|
+
<th>Purpose</th>
|
|
161
|
+
</tr>
|
|
162
|
+
</thead>
|
|
163
|
+
<tbody><tr>
|
|
164
|
+
<td><code>site.yaml</code></td>
|
|
165
|
+
<td>Template</td>
|
|
166
|
+
<td>Site configuration with sections defined</td>
|
|
167
|
+
</tr>
|
|
168
|
+
<tr>
|
|
169
|
+
<td><code>index.md</code></td>
|
|
170
|
+
<td>Template</td>
|
|
171
|
+
<td>Home page with navigation to sections</td>
|
|
172
|
+
</tr>
|
|
173
|
+
<tr>
|
|
174
|
+
<td><code>content/</code></td>
|
|
175
|
+
<td>Template</td>
|
|
176
|
+
<td>Folder structure with starter files</td>
|
|
177
|
+
</tr>
|
|
178
|
+
<tr>
|
|
179
|
+
<td><code>.gitignore</code></td>
|
|
180
|
+
<td><code>minimal</code></td>
|
|
181
|
+
<td>Standard ignores for builds, deps, OS files</td>
|
|
182
|
+
</tr>
|
|
183
|
+
<tr>
|
|
184
|
+
<td><code>README.md</code></td>
|
|
185
|
+
<td><code>minimal</code></td>
|
|
186
|
+
<td>Project readme with dev commands</td>
|
|
187
|
+
</tr>
|
|
188
|
+
<tr>
|
|
189
|
+
<td><code>CUSTOMIZING.md</code></td>
|
|
190
|
+
<td>Specialized templates</td>
|
|
191
|
+
<td>How to customize (AI + human friendly)</td>
|
|
192
|
+
</tr>
|
|
193
|
+
<tr>
|
|
194
|
+
<td><code>assets/brand/</code></td>
|
|
195
|
+
<td><code>minimal</code></td>
|
|
196
|
+
<td>Placeholder for logo, favicon</td>
|
|
197
|
+
</tr>
|
|
198
|
+
</tbody></table>
|
|
199
|
+
<h3 id="the-customizing-guide">The Customizing Guide</h3>
|
|
200
|
+
<p>Specialized templates include <code>CUSTOMIZING.md</code> — an onboarding document that helps both humans and AI assistants understand:</p>
|
|
201
|
+
<ul>
|
|
202
|
+
<li><strong>Structure</strong>: What each section is for, naming conventions</li>
|
|
203
|
+
<li><strong>Adding content</strong>: Where to put new files, how to create sections</li>
|
|
204
|
+
<li><strong>Linking</strong>: How to cross-reference within the site</li>
|
|
205
|
+
<li><strong>Limitations</strong>: Content must live in the site folder; external files linked via URL</li>
|
|
206
|
+
</ul>
|
|
207
|
+
<h3 id="provenance-record">Provenance Record</h3>
|
|
208
|
+
<p>Every generated site includes provenance metadata (in <code>CUSTOMIZING.md</code> header):</p>
|
|
209
|
+
<pre><code class="language-yaml">---
|
|
210
|
+
template: runbook
|
|
211
|
+
template_version: 1
|
|
212
|
+
created: 2026-02-04
|
|
213
|
+
kitfly_version: 0.1.0
|
|
214
|
+
---
|
|
215
|
+
</code></pre>
|
|
216
|
+
<p>This tracks:</p>
|
|
217
|
+
<ul>
|
|
218
|
+
<li><strong>template</strong>: Which template was used</li>
|
|
219
|
+
<li><strong>template_version</strong>: Version of that template's structure</li>
|
|
220
|
+
<li><strong>created</strong>: When the site was initialized</li>
|
|
221
|
+
<li><strong>kitfly_version</strong>: Kitfly version at creation time</li>
|
|
222
|
+
</ul>
|
|
223
|
+
<p>Provenance helps when upgrading sites or understanding what conventions were in place at creation time.</p>
|
|
224
|
+
<h2 id="the-kitfly-metadata-folder">The <code>.kitfly/</code> Metadata Folder</h2>
|
|
225
|
+
<p>Sites can have a <code>.kitfly/</code> folder for kitfly-specific metadata (gitignored by default).</p>
|
|
226
|
+
<h3 id="all-sites-manifestjson">All Sites: <code>manifest.json</code></h3>
|
|
227
|
+
<p>Every site gets a manifest tracking creation metadata:</p>
|
|
228
|
+
<pre><code class="language-json">{
|
|
229
|
+
"template": "runbook",
|
|
230
|
+
"templateVersion": 1,
|
|
231
|
+
"created": "2026-02-04T14:30:00Z",
|
|
232
|
+
"kitflyVersion": "0.1.0",
|
|
233
|
+
"standalone": false
|
|
234
|
+
}
|
|
235
|
+
</code></pre>
|
|
236
|
+
<h3 id="standalone-sites-provenancejson">Standalone Sites: <code>provenance.json</code></h3>
|
|
237
|
+
<p>Standalone sites additionally track copied files with SHA256 hashes:</p>
|
|
238
|
+
<pre><code class="language-json">{
|
|
239
|
+
"kitflyVersion": "0.1.0",
|
|
240
|
+
"createdAt": "2026-02-04T14:30:00Z",
|
|
241
|
+
"template": "runbook",
|
|
242
|
+
"files": [
|
|
243
|
+
{ "path": "scripts/dev.ts", "sourceHash": "a1b2c3..." },
|
|
244
|
+
{ "path": "src/engine.ts", "sourceHash": "d4e5f6..." }
|
|
245
|
+
]
|
|
246
|
+
}
|
|
247
|
+
</code></pre>
|
|
248
|
+
<p><strong>Why hashes?</strong> For future <code>kitfly update</code> support:</p>
|
|
249
|
+
<ul>
|
|
250
|
+
<li>Compare hashes to detect user modifications</li>
|
|
251
|
+
<li>Safely update unmodified files</li>
|
|
252
|
+
<li>Warn before overwriting customized code</li>
|
|
253
|
+
<li>Track version gaps that need bridging</li>
|
|
254
|
+
</ul>
|
|
255
|
+
<h3 id="future-updatesjson">Future: <code>updates.json</code></h3>
|
|
256
|
+
<p>When <code>kitfly update</code> ships (v0.2.x), we'll track update history:</p>
|
|
257
|
+
<pre><code class="language-json">{
|
|
258
|
+
"updates": [
|
|
259
|
+
{
|
|
260
|
+
"date": "2026-03-15T10:00:00Z",
|
|
261
|
+
"fromVersion": "0.1.0",
|
|
262
|
+
"toVersion": "0.2.0",
|
|
263
|
+
"filesUpdated": ["scripts/dev.ts", "src/theme.ts"],
|
|
264
|
+
"filesSkipped": ["scripts/build.ts"]
|
|
265
|
+
}
|
|
266
|
+
]
|
|
267
|
+
}
|
|
268
|
+
</code></pre>
|
|
269
|
+
<p>This enables rollback awareness and audit trails for managed sites.</p>
|
|
270
|
+
<h2 id="choosing-a-template">Choosing a Template</h2>
|
|
271
|
+
<table>
|
|
272
|
+
<thead>
|
|
273
|
+
<tr>
|
|
274
|
+
<th>Template</th>
|
|
275
|
+
<th>Best For</th>
|
|
276
|
+
<th>Sections</th>
|
|
277
|
+
</tr>
|
|
278
|
+
</thead>
|
|
279
|
+
<tbody><tr>
|
|
280
|
+
<td><code>minimal</code></td>
|
|
281
|
+
<td>Custom structures, experimentation</td>
|
|
282
|
+
<td>None predefined — you define your own</td>
|
|
283
|
+
</tr>
|
|
284
|
+
<tr>
|
|
285
|
+
<td><code>handbook</code></td>
|
|
286
|
+
<td>Team docs, onboarding, knowledge bases</td>
|
|
287
|
+
<td>Overview, Guides, Reference</td>
|
|
288
|
+
</tr>
|
|
289
|
+
<tr>
|
|
290
|
+
<td><code>runbook</code></td>
|
|
291
|
+
<td>Operations, procedures, incidents</td>
|
|
292
|
+
<td>Procedures, Troubleshooting, Reference, Incidents</td>
|
|
293
|
+
</tr>
|
|
294
|
+
<tr>
|
|
295
|
+
<td><code>pipeline</code></td>
|
|
296
|
+
<td>Data pipeline operations</td>
|
|
297
|
+
<td>Pipeline, Sources, Destinations, Operations, Troubleshooting, Reference</td>
|
|
298
|
+
</tr>
|
|
299
|
+
<tr>
|
|
300
|
+
<td><code>productbook</code></td>
|
|
301
|
+
<td>Product + domain docs for complex engagements</td>
|
|
302
|
+
<td>Product, Domain, Planning, Operations, Guides, Reference</td>
|
|
303
|
+
</tr>
|
|
304
|
+
<tr>
|
|
305
|
+
<td><code>servicebook</code></td>
|
|
306
|
+
<td>Professional services, consulting catalogs</td>
|
|
307
|
+
<td>Offerings, Methodology, Delivery, Verticals, Case Studies, Reference</td>
|
|
308
|
+
</tr>
|
|
309
|
+
<tr>
|
|
310
|
+
<td><code>crucible</code></td>
|
|
311
|
+
<td>Information architecture SSOT, ecosystem standards</td>
|
|
312
|
+
<td>Specs, Schemas, Config, Policies, Guides, Reference</td>
|
|
313
|
+
</tr>
|
|
314
|
+
</tbody></table>
|
|
315
|
+
<h2 id="usage">Usage</h2>
|
|
316
|
+
<pre><code class="language-bash"># Create with default template (minimal)
|
|
317
|
+
kitfly init my-site
|
|
318
|
+
|
|
319
|
+
# Create with specific template
|
|
320
|
+
kitfly init my-docs --template handbook
|
|
321
|
+
|
|
322
|
+
# Add branding
|
|
323
|
+
kitfly init my-docs --template handbook --brand "Acme Corp"
|
|
324
|
+
|
|
325
|
+
# Create standalone (includes kitfly site code)
|
|
326
|
+
kitfly init my-docs --template handbook --standalone
|
|
327
|
+
|
|
328
|
+
# Add AI assistance instrumentation
|
|
329
|
+
kitfly init my-docs --template runbook --ai-assist
|
|
330
|
+
|
|
331
|
+
# Skip git initialization
|
|
332
|
+
kitfly init my-docs --template handbook --no-git
|
|
333
|
+
</code></pre>
|
|
334
|
+
<h2 id="lifecycle-operations">Lifecycle Operations</h2>
|
|
335
|
+
<p>Kitfly focuses on <strong>creation</strong> only:</p>
|
|
336
|
+
<table>
|
|
337
|
+
<thead>
|
|
338
|
+
<tr>
|
|
339
|
+
<th>Operation</th>
|
|
340
|
+
<th>Support</th>
|
|
341
|
+
<th>Notes</th>
|
|
342
|
+
</tr>
|
|
343
|
+
</thead>
|
|
344
|
+
<tbody><tr>
|
|
345
|
+
<td>Create</td>
|
|
346
|
+
<td><code>kitfly init</code></td>
|
|
347
|
+
<td>Full template system</td>
|
|
348
|
+
</tr>
|
|
349
|
+
<tr>
|
|
350
|
+
<td>Read</td>
|
|
351
|
+
<td><code>kitfly dev</code></td>
|
|
352
|
+
<td>Preview any markdown folder</td>
|
|
353
|
+
</tr>
|
|
354
|
+
<tr>
|
|
355
|
+
<td>Update</td>
|
|
356
|
+
<td><code>kitfly update</code></td>
|
|
357
|
+
<td>Planned for v0.2.x</td>
|
|
358
|
+
</tr>
|
|
359
|
+
<tr>
|
|
360
|
+
<td>Delete</td>
|
|
361
|
+
<td>Not supported</td>
|
|
362
|
+
<td>Use <code>rm -rf</code> - sites are just folders</td>
|
|
363
|
+
</tr>
|
|
364
|
+
</tbody></table>
|
|
365
|
+
<p><strong>Why no delete?</strong> Sites are self-contained folders with no external references. Deleting is simply removing the folder. There's no registry or metadata outside the site to clean up.</p>
|
|
366
|
+
<h2 id="template-details">Template Details</h2>
|
|
367
|
+
<ul>
|
|
368
|
+
<li><a href="minimal">Minimal</a> — The base layer every site inherits</li>
|
|
369
|
+
<li><a href="handbook">Handbook</a> — Team documentation structure</li>
|
|
370
|
+
<li><a href="runbook">Runbook</a> — Operational procedures and checklists</li>
|
|
371
|
+
<li><a href="pipeline">Pipeline</a> — Data pipeline stages, sources, and destinations</li>
|
|
372
|
+
<li><a href="productbook">Productbook</a> — Product and domain knowledge for greenfield engagements</li>
|
|
373
|
+
<li><a href="servicebook">Servicebook</a> — Professional services catalog with methodology and delivery</li>
|
|
374
|
+
<li><a href="crucible">Crucible</a> — Information architecture SSOT with specs, schemas, and governance</li>
|
|
375
|
+
</ul>
|
|
376
|
+
|
|
377
|
+
</article>
|
|
378
|
+
<aside class="toc"><span class="toc-title">On this page</span><ul><li><a href="#the-layering-model">The Layering Model</a></li><li><a href="#what-templates-create">What Templates Create</a></li><li class="toc-h3"><a href="#the-customizing-guide">The Customizing Guide</a></li><li class="toc-h3"><a href="#provenance-record">Provenance Record</a></li><li><a href="#choosing-a-template">Choosing a Template</a></li><li><a href="#usage">Usage</a></li><li><a href="#lifecycle-operations">Lifecycle Operations</a></li><li><a href="#template-details">Template Details</a></li></ul></aside>
|
|
379
|
+
</main>
|
|
380
|
+
</div>
|
|
381
|
+
|
|
382
|
+
<footer class="site-footer">
|
|
383
|
+
<div class="footer-content">
|
|
384
|
+
<div class="footer-left">
|
|
385
|
+
<span class="footer-version">v0.2.1</span>
|
|
386
|
+
<span class="footer-separator">·</span>
|
|
387
|
+
<span class="footer-commit" title="Commit: 30dfc01">Published 2026-02-15</span>
|
|
388
|
+
</div>
|
|
389
|
+
<div class="footer-center">
|
|
390
|
+
<span class="footer-copyright"><a href="https://3leaps.net" class="footer-link">© 2026 3 Leaps, LLC</a></span>
|
|
391
|
+
<span class="footer-separator">·</span><a href="/" class="footer-link">Kitfly</a>
|
|
392
|
+
</div>
|
|
393
|
+
<div class="footer-right">
|
|
394
|
+
<a href="https://kitfly.dev" class="footer-link">Built with Kitfly</a>
|
|
395
|
+
</div>
|
|
396
|
+
</div>
|
|
397
|
+
</footer>
|
|
398
|
+
<!-- Syntax highlighting - Prism.js -->
|
|
399
|
+
<script src="https://cdn.jsdelivr.net/npm/prismjs@1/components/prism-core.min.js"></script>
|
|
400
|
+
<script src="https://cdn.jsdelivr.net/npm/prismjs@1/plugins/autoloader/prism-autoloader.min.js"></script>
|
|
401
|
+
<!-- Mermaid diagram support -->
|
|
402
|
+
<script type="module">
|
|
403
|
+
import mermaid from 'https://cdn.jsdelivr.net/npm/mermaid@11/dist/mermaid.esm.min.mjs';
|
|
404
|
+
|
|
405
|
+
function getMermaidTheme() {
|
|
406
|
+
const theme = document.documentElement.getAttribute('data-theme');
|
|
407
|
+
const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
|
|
408
|
+
const isDark = theme === 'dark' || (!theme && prefersDark);
|
|
409
|
+
return isDark ? 'dark' : 'neutral';
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
mermaid.initialize({
|
|
413
|
+
startOnLoad: true,
|
|
414
|
+
theme: getMermaidTheme()
|
|
415
|
+
});
|
|
416
|
+
|
|
417
|
+
// Re-render mermaid diagrams when theme changes
|
|
418
|
+
window.reinitMermaid = async function() {
|
|
419
|
+
mermaid.initialize({ startOnLoad: false, theme: getMermaidTheme() });
|
|
420
|
+
const diagrams = document.querySelectorAll('.mermaid');
|
|
421
|
+
for (const el of diagrams) {
|
|
422
|
+
const code = el.getAttribute('data-mermaid-source');
|
|
423
|
+
if (code) {
|
|
424
|
+
el.innerHTML = code;
|
|
425
|
+
el.removeAttribute('data-processed');
|
|
426
|
+
}
|
|
427
|
+
}
|
|
428
|
+
await mermaid.run({ nodes: diagrams });
|
|
429
|
+
};
|
|
430
|
+
</script>
|
|
431
|
+
|
|
432
|
+
<script>
|
|
433
|
+
function toggleTheme() {
|
|
434
|
+
const html = document.documentElement;
|
|
435
|
+
const current = html.getAttribute('data-theme');
|
|
436
|
+
const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
|
|
437
|
+
|
|
438
|
+
let next;
|
|
439
|
+
if (current === 'dark') {
|
|
440
|
+
next = 'light';
|
|
441
|
+
} else if (current === 'light') {
|
|
442
|
+
next = 'dark';
|
|
443
|
+
} else {
|
|
444
|
+
// No explicit theme set, toggle from system preference
|
|
445
|
+
next = prefersDark ? 'light' : 'dark';
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
html.setAttribute('data-theme', next);
|
|
449
|
+
localStorage.setItem('theme', next);
|
|
450
|
+
|
|
451
|
+
// Switch Prism theme
|
|
452
|
+
const prismLight = document.getElementById('prism-light');
|
|
453
|
+
const prismDark = document.getElementById('prism-dark');
|
|
454
|
+
if (next === 'dark') {
|
|
455
|
+
prismLight?.setAttribute('disabled', '');
|
|
456
|
+
prismDark?.removeAttribute('disabled');
|
|
457
|
+
} else {
|
|
458
|
+
prismLight?.removeAttribute('disabled');
|
|
459
|
+
prismDark?.setAttribute('disabled', '');
|
|
460
|
+
}
|
|
461
|
+
|
|
462
|
+
// Re-render mermaid diagrams with new theme
|
|
463
|
+
if (window.reinitMermaid) {
|
|
464
|
+
window.reinitMermaid();
|
|
465
|
+
}
|
|
466
|
+
}
|
|
467
|
+
|
|
468
|
+
// Slides mode hash routing
|
|
469
|
+
(function initSlidesMode() {
|
|
470
|
+
const shell = document.querySelector('.slides-shell');
|
|
471
|
+
if (!shell) return;
|
|
472
|
+
|
|
473
|
+
const slides = Array.from(document.querySelectorAll('.slide'));
|
|
474
|
+
if (!slides.length) return;
|
|
475
|
+
|
|
476
|
+
const prevBtn = document.querySelector('.slide-prev');
|
|
477
|
+
const nextBtn = document.querySelector('.slide-next');
|
|
478
|
+
const counter = document.querySelector('.slide-counter');
|
|
479
|
+
const progressBar = document.querySelector('.slide-progress-bar');
|
|
480
|
+
const navLinks = Array.from(document.querySelectorAll('.sidebar-nav a[href^="#slide-"]'));
|
|
481
|
+
let current = 0;
|
|
482
|
+
|
|
483
|
+
function setActive(n) {
|
|
484
|
+
current = Math.max(0, Math.min(n, slides.length - 1));
|
|
485
|
+
slides.forEach((slide, idx) => slide.classList.toggle('active', idx === current));
|
|
486
|
+
navLinks.forEach((link) => {
|
|
487
|
+
const active = link.getAttribute('href') === '#' + slides[current].id;
|
|
488
|
+
link.classList.toggle('active', active);
|
|
489
|
+
});
|
|
490
|
+
if (counter) counter.textContent = (current + 1) + ' / ' + slides.length;
|
|
491
|
+
if (progressBar) progressBar.style.width = (((current + 1) / slides.length) * 100) + '%';
|
|
492
|
+
if (prevBtn) prevBtn.disabled = current === 0;
|
|
493
|
+
if (nextBtn) nextBtn.disabled = current === slides.length - 1;
|
|
494
|
+
history.replaceState(null, '', '#' + slides[current].id);
|
|
495
|
+
}
|
|
496
|
+
|
|
497
|
+
function setFromHash() {
|
|
498
|
+
const hash = window.location.hash || '';
|
|
499
|
+
const idx = slides.findIndex((s) => '#' + s.id === hash);
|
|
500
|
+
if (idx >= 0) setActive(idx);
|
|
501
|
+
else setActive(0);
|
|
502
|
+
}
|
|
503
|
+
|
|
504
|
+
prevBtn?.addEventListener('click', () => setActive(current - 1));
|
|
505
|
+
nextBtn?.addEventListener('click', () => setActive(current + 1));
|
|
506
|
+
|
|
507
|
+
document.addEventListener('keydown', (e) => {
|
|
508
|
+
if (e.key === 'ArrowRight' || e.key === ' ') {
|
|
509
|
+
e.preventDefault();
|
|
510
|
+
setActive(current + 1);
|
|
511
|
+
} else if (e.key === 'ArrowLeft') {
|
|
512
|
+
e.preventDefault();
|
|
513
|
+
setActive(current - 1);
|
|
514
|
+
} else if (e.key === 'Home') {
|
|
515
|
+
e.preventDefault();
|
|
516
|
+
setActive(0);
|
|
517
|
+
} else if (e.key === 'End') {
|
|
518
|
+
e.preventDefault();
|
|
519
|
+
setActive(slides.length - 1);
|
|
520
|
+
}
|
|
521
|
+
});
|
|
522
|
+
|
|
523
|
+
window.addEventListener('hashchange', setFromHash);
|
|
524
|
+
setFromHash();
|
|
525
|
+
})();
|
|
526
|
+
|
|
527
|
+
// Copy code button
|
|
528
|
+
document.querySelectorAll('.prose pre code').forEach(block => {
|
|
529
|
+
const button = document.createElement('button');
|
|
530
|
+
button.className = 'copy-button';
|
|
531
|
+
button.textContent = 'Copy';
|
|
532
|
+
button.onclick = async () => {
|
|
533
|
+
await navigator.clipboard.writeText(block.textContent);
|
|
534
|
+
button.textContent = 'Copied!';
|
|
535
|
+
setTimeout(() => button.textContent = 'Copy', 2000);
|
|
536
|
+
};
|
|
537
|
+
block.parentElement.appendChild(button);
|
|
538
|
+
});
|
|
539
|
+
|
|
540
|
+
// Mobile nav toggle
|
|
541
|
+
function toggleNav() {
|
|
542
|
+
document.querySelector('.sidebar').classList.toggle('open');
|
|
543
|
+
}
|
|
544
|
+
|
|
545
|
+
// Close nav when clicking outside on mobile
|
|
546
|
+
document.addEventListener('click', (e) => {
|
|
547
|
+
const sidebar = document.querySelector('.sidebar');
|
|
548
|
+
const toggle = document.querySelector('.nav-toggle');
|
|
549
|
+
if (sidebar.classList.contains('open') &&
|
|
550
|
+
!sidebar.contains(e.target) &&
|
|
551
|
+
!toggle.contains(e.target)) {
|
|
552
|
+
sidebar.classList.remove('open');
|
|
553
|
+
}
|
|
554
|
+
});
|
|
555
|
+
</script>
|
|
556
|
+
|
|
557
|
+
</body>
|
|
558
|
+
</html>
|