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,118 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "ADR-0001: Minimalist Site Code"
|
|
3
|
+
description: "Defines thresholds for the site code that kitfly copies to user projects"
|
|
4
|
+
author: "devlead"
|
|
5
|
+
supervised_by: "@3leapsdave"
|
|
6
|
+
date: "2026-02-04"
|
|
7
|
+
status: "accepted"
|
|
8
|
+
tags: ["adr", "architecture", "minimalism", "site-code"]
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
# ADR-0001: Minimalist Site Code
|
|
12
|
+
|
|
13
|
+
## Status
|
|
14
|
+
|
|
15
|
+
Accepted
|
|
16
|
+
|
|
17
|
+
## Context
|
|
18
|
+
|
|
19
|
+
When users run `kitfly init`, they receive a complete, standalone site with rendering code. This code becomes **theirs** — they can modify it, version it, and maintain it.
|
|
20
|
+
|
|
21
|
+
The site code must be:
|
|
22
|
+
|
|
23
|
+
- **Small**: Understandable in an afternoon
|
|
24
|
+
- **Reviewable**: A security-conscious user can audit it
|
|
25
|
+
- **Modifiable**: Users can customize without fear
|
|
26
|
+
- **Maintainable**: One dependency, no churn
|
|
27
|
+
|
|
28
|
+
This ADR defines what belongs in site code vs. what stays in the kitfly CLI.
|
|
29
|
+
|
|
30
|
+
## Decision
|
|
31
|
+
|
|
32
|
+
### Site Code Thresholds
|
|
33
|
+
|
|
34
|
+
The site code that `kitfly init` copies should stay within these bounds:
|
|
35
|
+
|
|
36
|
+
| Metric | Target | Hard Limit |
|
|
37
|
+
| ---------------------- | ---------- | ---------- |
|
|
38
|
+
| Total lines (scripts/) | ~500 | 800 |
|
|
39
|
+
| Dependencies | 1 (marked) | 2 |
|
|
40
|
+
| Files copied | ~10 | 15 |
|
|
41
|
+
|
|
42
|
+
### What Belongs in Site Code
|
|
43
|
+
|
|
44
|
+
| Component | Purpose | Approximate Size |
|
|
45
|
+
| ------------------------ | -------------------------------- | ---------------- |
|
|
46
|
+
| `scripts/dev.ts` | Dev server with hot reload | ~400 lines |
|
|
47
|
+
| `scripts/build.ts` | Static site generation | ~350 lines |
|
|
48
|
+
| `scripts/bundle.ts` | Single-file HTML output | ~250 lines |
|
|
49
|
+
| `src/theme.ts` | Theme loading and CSS generation | ~150 lines |
|
|
50
|
+
| `src/engine.ts` | Path utilities | ~20 lines |
|
|
51
|
+
| `src/site/template.html` | HTML template | ~150 lines |
|
|
52
|
+
| `src/site/styles.css` | Default styles | ~400 lines |
|
|
53
|
+
|
|
54
|
+
**Rule of thumb**: If it can be done with CSS, vanilla JS under 50 lines, or a marked plugin, it belongs in site code.
|
|
55
|
+
|
|
56
|
+
### What Stays in Kitfly CLI
|
|
57
|
+
|
|
58
|
+
| Component | Purpose | Reason |
|
|
59
|
+
| ------------------------ | ------------------- | --------------------- |
|
|
60
|
+
| `src/cli.ts` | CLI entry point | Users don't need this |
|
|
61
|
+
| `src/commands/init.ts` | Project scaffolding | Meta-tooling |
|
|
62
|
+
| `src/commands/update.ts` | Site code updates | Meta-tooling |
|
|
63
|
+
| `content/` | Kitfly's own docs | Not user content |
|
|
64
|
+
| `assets/brand/` | Kitfly branding | Users have their own |
|
|
65
|
+
|
|
66
|
+
### Feature Evaluation
|
|
67
|
+
|
|
68
|
+
Before adding any feature to site code:
|
|
69
|
+
|
|
70
|
+
1. **Check the line budget** — Will this exceed 800 lines?
|
|
71
|
+
2. **Check the dependency count** — Does this require a new dependency?
|
|
72
|
+
3. **Check the complexity** — Can a user understand this in an afternoon?
|
|
73
|
+
4. **Check the necessity** — Is this core rendering, or CLI convenience?
|
|
74
|
+
|
|
75
|
+
Features that fail these checks should:
|
|
76
|
+
|
|
77
|
+
- Stay in the kitfly CLI (not copied to user sites)
|
|
78
|
+
- Be implemented as optional user customization
|
|
79
|
+
- Trigger a discussion about whether we're solving the right problem
|
|
80
|
+
|
|
81
|
+
### Migration Path
|
|
82
|
+
|
|
83
|
+
If site code grows beyond thresholds:
|
|
84
|
+
|
|
85
|
+
1. **Refactor first** — Can we simplify?
|
|
86
|
+
2. **Extract to CLI** — Move non-essential features to kitfly CLI
|
|
87
|
+
3. **Document the tradeoff** — If complexity is unavoidable, explain why
|
|
88
|
+
|
|
89
|
+
Users who need more should migrate to Astro, VitePress, or similar. Their content is just markdown — migration is straightforward.
|
|
90
|
+
|
|
91
|
+
## Consequences
|
|
92
|
+
|
|
93
|
+
### Positive
|
|
94
|
+
|
|
95
|
+
- Users receive code they can actually understand
|
|
96
|
+
- Security review is feasible (small surface area)
|
|
97
|
+
- Modifications don't require framework knowledge
|
|
98
|
+
- One `bun install` and they're running
|
|
99
|
+
|
|
100
|
+
### Negative
|
|
101
|
+
|
|
102
|
+
- Some features require discipline to implement minimally
|
|
103
|
+
- Visual sophistication bounded by CSS capabilities
|
|
104
|
+
- Power users may want more than we provide
|
|
105
|
+
|
|
106
|
+
### Neutral
|
|
107
|
+
|
|
108
|
+
- Feature requests require threshold evaluation
|
|
109
|
+
- "Can we add X?" becomes a structured conversation
|
|
110
|
+
|
|
111
|
+
## Compliance
|
|
112
|
+
|
|
113
|
+
All changes to files under `scripts/`, `src/site/`, `src/engine.ts`, or `src/theme.ts` must consider this ADR. These files are copied to user projects.
|
|
114
|
+
|
|
115
|
+
## References
|
|
116
|
+
|
|
117
|
+
- [Kitfly Overview](../../content/guide/kitfly-overview.md) — Product philosophy
|
|
118
|
+
- Handbook ADR-0001 — Original minimalist thresholds
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "ADR-0002: AI Accessibility for Published Sites"
|
|
3
|
+
description: "Standard for making kitfly sites consumable by AI agents"
|
|
4
|
+
author: "devlead"
|
|
5
|
+
supervised_by: "@3leapsdave"
|
|
6
|
+
date: "2026-02-04"
|
|
7
|
+
status: "accepted"
|
|
8
|
+
tags: ["adr", "architecture", "ai", "accessibility", "llms"]
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
# ADR-0002: AI Accessibility for Published Sites
|
|
12
|
+
|
|
13
|
+
## Status
|
|
14
|
+
|
|
15
|
+
Accepted
|
|
16
|
+
|
|
17
|
+
## Context
|
|
18
|
+
|
|
19
|
+
Kitfly sites are primarily viewed by humans in browsers. However, AI agents increasingly need to consume documentation:
|
|
20
|
+
|
|
21
|
+
- Agents browsing deployed sites on cloud storage or intranets
|
|
22
|
+
- LLMs researching documentation during coding tasks
|
|
23
|
+
- Automated documentation indexing and search
|
|
24
|
+
|
|
25
|
+
HTML parsing is inefficient for AI agents. They prefer:
|
|
26
|
+
|
|
27
|
+
- Structured metadata for discovery
|
|
28
|
+
- Raw markdown for content consumption
|
|
29
|
+
- Predictable paths for programmatic access
|
|
30
|
+
|
|
31
|
+
## Decision
|
|
32
|
+
|
|
33
|
+
### Standard Files Generated
|
|
34
|
+
|
|
35
|
+
Every `kitfly build` generates these AI accessibility files:
|
|
36
|
+
|
|
37
|
+
#### 1. `content-index.json`
|
|
38
|
+
|
|
39
|
+
Machine-readable index of all pages:
|
|
40
|
+
|
|
41
|
+
```json
|
|
42
|
+
{
|
|
43
|
+
"version": "0.1.0",
|
|
44
|
+
"generated": "2026-02-04T12:00:00Z",
|
|
45
|
+
"title": "Site Title",
|
|
46
|
+
"baseUrl": "/",
|
|
47
|
+
"rawMarkdownPath": "/_raw",
|
|
48
|
+
"pages": [
|
|
49
|
+
{
|
|
50
|
+
"path": "/guide/getting-started",
|
|
51
|
+
"htmlPath": "/guide/getting-started.html",
|
|
52
|
+
"rawPath": "/_raw/guide/getting-started.md",
|
|
53
|
+
"title": "Getting Started",
|
|
54
|
+
"section": "Guide",
|
|
55
|
+
"source": "content/guide/getting-started.md",
|
|
56
|
+
"description": "Optional description from frontmatter"
|
|
57
|
+
}
|
|
58
|
+
]
|
|
59
|
+
}
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
#### 2. `llms.txt`
|
|
63
|
+
|
|
64
|
+
Following the emerging [llms.txt convention](https://llmstxt.org/):
|
|
65
|
+
|
|
66
|
+
```
|
|
67
|
+
# llms.txt - AI agent guidance for Site Title
|
|
68
|
+
name: Site Title
|
|
69
|
+
version: 0.1.0
|
|
70
|
+
generated: 2026-02-04T12:00:00Z
|
|
71
|
+
|
|
72
|
+
content-index: /content-index.json
|
|
73
|
+
raw-markdown: /_raw/{path}.md
|
|
74
|
+
preferred-format: markdown
|
|
75
|
+
|
|
76
|
+
sections: Guide, Reference
|
|
77
|
+
total-pages: 10
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
#### 3. `_raw/` Directory
|
|
81
|
+
|
|
82
|
+
Raw markdown files mirroring the site structure:
|
|
83
|
+
|
|
84
|
+
```
|
|
85
|
+
_raw/
|
|
86
|
+
├── guide/
|
|
87
|
+
│ ├── getting-started.md
|
|
88
|
+
│ └── features.md
|
|
89
|
+
└── reference/
|
|
90
|
+
└── configuration.md
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
### Bundle Format
|
|
94
|
+
|
|
95
|
+
Single-file bundles embed accessibility data as hidden JSON:
|
|
96
|
+
|
|
97
|
+
```html
|
|
98
|
+
<script type="application/json" id="kitfly-content-index">
|
|
99
|
+
{ ... content index ... }
|
|
100
|
+
</script>
|
|
101
|
+
<script type="application/json" id="kitfly-raw-markdown">
|
|
102
|
+
{ "guide/getting-started": "# Getting Started\n...", ... }
|
|
103
|
+
</script>
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
### Opt-Out for Size-Sensitive Use Cases
|
|
107
|
+
|
|
108
|
+
The `--no-raw` flag disables raw markdown for smaller output:
|
|
109
|
+
|
|
110
|
+
```bash
|
|
111
|
+
kitfly build --no-raw # No _raw/ directory
|
|
112
|
+
kitfly bundle --no-raw # No embedded raw markdown
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
Content index and llms.txt are always generated (minimal overhead).
|
|
116
|
+
|
|
117
|
+
## Agent Consumption Pattern
|
|
118
|
+
|
|
119
|
+
An AI agent discovering a kitfly site:
|
|
120
|
+
|
|
121
|
+
1. Fetch `/llms.txt` to understand the site
|
|
122
|
+
2. Fetch `/content-index.json` for full page inventory
|
|
123
|
+
3. Fetch raw markdown from `/_raw/{path}.md` for content
|
|
124
|
+
4. Fall back to HTML parsing only if raw unavailable
|
|
125
|
+
|
|
126
|
+
## Consequences
|
|
127
|
+
|
|
128
|
+
### Positive
|
|
129
|
+
|
|
130
|
+
- Agents can efficiently consume kitfly sites
|
|
131
|
+
- Raw markdown preserves frontmatter and original formatting
|
|
132
|
+
- Structured index enables smart navigation
|
|
133
|
+
- Standard paths work across all kitfly sites
|
|
134
|
+
- Minimal size overhead (JSON index + optional raw copies)
|
|
135
|
+
|
|
136
|
+
### Negative
|
|
137
|
+
|
|
138
|
+
- Slightly larger build output (mitigated by `--no-raw`)
|
|
139
|
+
- Raw markdown exposes source (acceptable for docs)
|
|
140
|
+
|
|
141
|
+
### Neutral
|
|
142
|
+
|
|
143
|
+
- Agents may still parse HTML for sites without llms.txt
|
|
144
|
+
- Convention is emerging, not yet universal
|
|
145
|
+
|
|
146
|
+
## Compliance
|
|
147
|
+
|
|
148
|
+
All kitfly builds must generate `content-index.json` and `llms.txt`. Raw markdown is on by default but can be disabled.
|
|
149
|
+
|
|
150
|
+
## References
|
|
151
|
+
|
|
152
|
+
- [llms.txt specification](https://llmstxt.org/)
|
|
153
|
+
- [ADR-0001: Minimalist Site Code](ADR-0001-minimalist-site-code.md)
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "ADR-0003: Single-File Bundle Output"
|
|
3
|
+
description: "Kitfly produces a self-contained HTML file as an alternative to static site build"
|
|
4
|
+
author: "deliverylead"
|
|
5
|
+
supervised_by: "@3leapsdave"
|
|
6
|
+
date: "2026-02-09"
|
|
7
|
+
status: "accepted"
|
|
8
|
+
tags: ["adr", "bundle", "architecture", "sharing"]
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
# ADR-0003: Single-File Bundle Output
|
|
12
|
+
|
|
13
|
+
## Status
|
|
14
|
+
|
|
15
|
+
Accepted
|
|
16
|
+
|
|
17
|
+
## Context
|
|
18
|
+
|
|
19
|
+
Documentation is often shared outside of web hosting — via email, Slack uploads, shared drives, or USB handoff. Traditional static site generators produce a directory of HTML, CSS, JS, and images that require a web server or careful relative-path handling to open locally.
|
|
20
|
+
|
|
21
|
+
Kitfly needed a sharing model that works without any infrastructure: one file, any browser, no server.
|
|
22
|
+
|
|
23
|
+
## Decision
|
|
24
|
+
|
|
25
|
+
Implement `kitfly bundle` as a first-class output mode alongside `kitfly build`. The bundle produces a **single self-contained HTML file** with all dependencies inlined.
|
|
26
|
+
|
|
27
|
+
### What Gets Inlined
|
|
28
|
+
|
|
29
|
+
| Asset | Inlining Strategy |
|
|
30
|
+
| ------------------------------ | ------------------------------------------- |
|
|
31
|
+
| CSS (styles.css) | `<style>` block in `<head>` |
|
|
32
|
+
| Theme CSS | Generated `<style id="kitfly-theme">` block |
|
|
33
|
+
| Images (PNG, JPG, SVG, GIF) | Base64 data URIs in `<img src>` |
|
|
34
|
+
| Brand logo + favicon | Base64 data URIs |
|
|
35
|
+
| Prism.js (syntax highlighting) | Full JS inlined in `<script>` |
|
|
36
|
+
| Mermaid (diagrams) | Full JS inlined in `<script>` |
|
|
37
|
+
| Dark mode toggle | Inline `<script>` |
|
|
38
|
+
| All page content | Inline HTML sections with `id` anchors |
|
|
39
|
+
|
|
40
|
+
### Navigation Model
|
|
41
|
+
|
|
42
|
+
The bundle uses **hash-based navigation** rather than page-per-file:
|
|
43
|
+
|
|
44
|
+
- Each content page becomes a `<section id="slug">` within the single document
|
|
45
|
+
- Sidebar links use `href="#slug"` anchors
|
|
46
|
+
- JavaScript shows/hides sections on hash change
|
|
47
|
+
- The sidebar hierarchy uses the same `buildSectionNav()` function as the static build, with a hash-link adapter: `makeHref = (urlPath) => '#' + slugify(urlPath)`
|
|
48
|
+
|
|
49
|
+
This ensures nav structure parity between `build` and `bundle` output.
|
|
50
|
+
|
|
51
|
+
### Raw Markdown
|
|
52
|
+
|
|
53
|
+
By default, raw `.md` source is embedded in the bundle as hidden `<script type="text/markdown">` blocks, accessible to AI agents. The `--no-raw` flag omits them to reduce file size.
|
|
54
|
+
|
|
55
|
+
### File Size
|
|
56
|
+
|
|
57
|
+
Typical documentation produces 100KB–1MB bundles. Image-heavy sites are larger due to base64 overhead (~33% per image). The tradeoff is acceptable because the primary use case is sharing, not serving at scale.
|
|
58
|
+
|
|
59
|
+
## Consequences
|
|
60
|
+
|
|
61
|
+
### Positive
|
|
62
|
+
|
|
63
|
+
- **Zero-infrastructure sharing**: Email, Slack, Google Drive — recipients open in any browser
|
|
64
|
+
- **Offline by default**: No network requests, no CDN dependencies
|
|
65
|
+
- **Point-in-time snapshot**: Bundle captures exact state of docs at build time
|
|
66
|
+
- **Same navigation as build**: `buildSectionNav()` shared between both output modes
|
|
67
|
+
- **AI-accessible**: Raw markdown available inside the bundle
|
|
68
|
+
|
|
69
|
+
### Negative
|
|
70
|
+
|
|
71
|
+
- Large bundles with many images (base64 adds ~33% overhead)
|
|
72
|
+
- No incremental loading — entire document loads at once
|
|
73
|
+
- Hash navigation doesn't support deep-linking from external URLs (fine for the sharing use case)
|
|
74
|
+
- Prism + Mermaid JS inlining adds ~500KB to every bundle
|
|
75
|
+
|
|
76
|
+
### Neutral
|
|
77
|
+
|
|
78
|
+
- Bundle and build share `collectFiles()`, `loadConfig()`, and `buildSectionNav()` from `shared.ts` — shared code stays in one place
|
|
79
|
+
- Bundle is a separate script (`scripts/bundle.ts`) rather than a mode flag on `scripts/build.ts`, keeping each focused
|
|
80
|
+
|
|
81
|
+
## Alternatives Considered
|
|
82
|
+
|
|
83
|
+
### PDF export
|
|
84
|
+
|
|
85
|
+
Widely shareable but loses interactivity (dark mode, collapsible nav, syntax highlighting themes). Would require a headless browser dependency (Puppeteer/Playwright). May be added later as a third output mode.
|
|
86
|
+
|
|
87
|
+
### MHTML / Web Archive
|
|
88
|
+
|
|
89
|
+
Browser-native single-file formats. Rejected because support is inconsistent (Safari doesn't support MHTML, Chrome's implementation has quirks) and generation requires browser automation.
|
|
90
|
+
|
|
91
|
+
### ZIP of static files
|
|
92
|
+
|
|
93
|
+
Solves the single-artifact problem but requires recipients to extract before viewing. Adds friction compared to double-clicking an HTML file.
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "ADR-0004: Bun Runtime"
|
|
3
|
+
description: "Kitfly uses Bun as its runtime instead of Node.js"
|
|
4
|
+
author: "deliverylead"
|
|
5
|
+
supervised_by: "@3leapsdave"
|
|
6
|
+
date: "2026-02-09"
|
|
7
|
+
status: "accepted"
|
|
8
|
+
tags: ["adr", "runtime", "architecture", "tooling"]
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
# ADR-0004: Bun Runtime
|
|
12
|
+
|
|
13
|
+
## Status
|
|
14
|
+
|
|
15
|
+
Accepted
|
|
16
|
+
|
|
17
|
+
## Context
|
|
18
|
+
|
|
19
|
+
Kitfly is a TypeScript CLI tool and static site generator. It needs a JavaScript runtime that can:
|
|
20
|
+
|
|
21
|
+
1. Execute TypeScript directly (no transpilation step)
|
|
22
|
+
2. Run fast — dev server startup, build times, and test execution should feel instant
|
|
23
|
+
3. Provide a built-in test runner (reduce dev dependencies)
|
|
24
|
+
4. Support the Node.js API surface used by kitfly (fs, path, http)
|
|
25
|
+
|
|
26
|
+
The project has a strict minimalism goal (ADR-0001): single production dependency (`marked`), minimal toolchain complexity.
|
|
27
|
+
|
|
28
|
+
## Decision
|
|
29
|
+
|
|
30
|
+
Use **Bun** as the primary runtime for development, testing, and production execution.
|
|
31
|
+
|
|
32
|
+
### What Bun Provides
|
|
33
|
+
|
|
34
|
+
| Capability | Replaces |
|
|
35
|
+
| --------------------------- | ---------------------------------------------------------- |
|
|
36
|
+
| Native TypeScript execution | `tsc` compilation step, `ts-node`, `tsx` |
|
|
37
|
+
| Built-in test runner | Separate test framework install (jest/mocha for execution) |
|
|
38
|
+
| Fast startup (~25ms) | Node.js cold start (~100-200ms) |
|
|
39
|
+
| Built-in package manager | npm/yarn/pnpm (for install speed) |
|
|
40
|
+
| `Bun.serve()` HTTP server | Express, Koa, or manual `http.createServer` |
|
|
41
|
+
|
|
42
|
+
### Runtime Boundary
|
|
43
|
+
|
|
44
|
+
Kitfly's source code uses standard Node.js APIs (`node:fs/promises`, `node:path`, `node:http`) rather than Bun-specific APIs where possible. The main Bun-specific usage is:
|
|
45
|
+
|
|
46
|
+
- `Bun.serve()` in the dev server (`scripts/dev.ts`)
|
|
47
|
+
- `bun run` as the script executor
|
|
48
|
+
- `bun test` via vitest (which uses Bun's runtime)
|
|
49
|
+
|
|
50
|
+
### User Requirement
|
|
51
|
+
|
|
52
|
+
Users must have Bun installed to run `kitfly`. This is documented in getting-started and enforced at CLI startup. Bun installation is a single command on all major platforms:
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
curl -fsSL https://bun.sh/install | bash
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
### Test Runner
|
|
59
|
+
|
|
60
|
+
Tests use **vitest** running on the Bun runtime. This provides:
|
|
61
|
+
|
|
62
|
+
- vitest's assertion API and test organization
|
|
63
|
+
- Bun's fast execution speed
|
|
64
|
+
- Watch mode for development (`bun test:watch`)
|
|
65
|
+
|
|
66
|
+
## Consequences
|
|
67
|
+
|
|
68
|
+
### Positive
|
|
69
|
+
|
|
70
|
+
- **No build step**: TypeScript executes directly — `bun run src/cli.ts` just works
|
|
71
|
+
- **Fast iteration**: Dev server starts in under 100ms, full test suite runs in ~500ms (427 tests)
|
|
72
|
+
- **Fewer dependencies**: No need for `ts-node`, `tsx`, or a separate transpiler
|
|
73
|
+
- **Aligned with minimalism**: Bun's built-in capabilities reduce the toolchain surface
|
|
74
|
+
|
|
75
|
+
### Negative
|
|
76
|
+
|
|
77
|
+
- **Bun is a user prerequisite**: Users who only have Node.js installed need to install Bun first
|
|
78
|
+
- **Ecosystem maturity**: Bun is newer than Node.js — edge cases in compatibility exist (though kitfly's API surface is well-supported)
|
|
79
|
+
- **CI consideration**: CI environments need Bun installed (GitHub Actions: `oven-sh/setup-bun`)
|
|
80
|
+
|
|
81
|
+
### Neutral
|
|
82
|
+
|
|
83
|
+
- The standard Node.js API usage means a future port to Node.js (with a TypeScript loader) is feasible if needed
|
|
84
|
+
- Bun's package manager is used for `bun install` but `package.json` remains standard — compatible with npm/yarn if users prefer for dependency management
|
|
85
|
+
|
|
86
|
+
## Alternatives Considered
|
|
87
|
+
|
|
88
|
+
### Node.js + tsx
|
|
89
|
+
|
|
90
|
+
Node.js with `tsx` for TypeScript execution. Viable but slower startup, requires additional dev dependency, and doesn't provide a built-in test runner or fast HTTP server.
|
|
91
|
+
|
|
92
|
+
### Deno
|
|
93
|
+
|
|
94
|
+
Native TypeScript support and built-in tooling. Rejected because Deno's module resolution (URL imports, import maps) would complicate the project structure and `kitfly init` copy model. Bun's Node.js compatibility is more aligned with kitfly's design.
|
|
95
|
+
|
|
96
|
+
### Node.js + esbuild compilation
|
|
97
|
+
|
|
98
|
+
Compile TypeScript to JavaScript, ship compiled output. Rejected because it adds a build step to the development workflow and contradicts the "edit and run" simplicity goal.
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "ADR-0005: Plugin Contract and Distribution Strategy"
|
|
3
|
+
description: "Defines plugin contract stability, versioning policy, and in-repo-first distribution with extraction path"
|
|
4
|
+
author: "devlead"
|
|
5
|
+
supervised_by: "@3leapsdave"
|
|
6
|
+
date: "2026-02-11"
|
|
7
|
+
status: "proposed"
|
|
8
|
+
tags: ["adr", "plugins", "architecture", "versioning", "supply-chain"]
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
# ADR-0005: Plugin Contract and Distribution Strategy
|
|
12
|
+
|
|
13
|
+
## Status
|
|
14
|
+
|
|
15
|
+
Proposed
|
|
16
|
+
|
|
17
|
+
## Context
|
|
18
|
+
|
|
19
|
+
Kitfly v0.2.0 introduces optional plugin capabilities to support advanced use cases (starting with slides and live-slide extensions) without bloating core site code.
|
|
20
|
+
|
|
21
|
+
As of M1.1, basic slide **shape primitives** remain core CSS. Plugin scope starts at higher-level figures/widgets and engine integrations where deterministic core CSS stops.
|
|
22
|
+
|
|
23
|
+
Two operational choices must be explicit:
|
|
24
|
+
|
|
25
|
+
1. **Contract stability**: plugin authors and site operators need a clear, versioned interface that remains predictable.
|
|
26
|
+
2. **Repository strategy**: plugins can live in the main repo or a separate repo; we need a pragmatic default and a low-risk migration path.
|
|
27
|
+
|
|
28
|
+
## Decision
|
|
29
|
+
|
|
30
|
+
### 1. Treat plugin contract as versioned API
|
|
31
|
+
|
|
32
|
+
Kitfly will define a versioned plugin contract (`plugin.schema.json` + hook semantics) as a compatibility boundary.
|
|
33
|
+
|
|
34
|
+
Contract rules:
|
|
35
|
+
|
|
36
|
+
- Contract version is explicit (e.g. `contract: "1"`).
|
|
37
|
+
- Breaking changes require a new major contract version.
|
|
38
|
+
- Backward-compatible additions are allowed within a contract major version.
|
|
39
|
+
- Deprecations must include migration guidance before removal.
|
|
40
|
+
|
|
41
|
+
### 2. Start plugins in-repo for v0.2.0
|
|
42
|
+
|
|
43
|
+
For v0.2.0 delivery speed, first-party plugins are developed in the main kitfly repository under a dedicated plugin path and registry/config structure.
|
|
44
|
+
|
|
45
|
+
Why now:
|
|
46
|
+
|
|
47
|
+
- Faster iteration while contract and hooks are stabilizing.
|
|
48
|
+
- Lower coordination overhead across core + plugin changes.
|
|
49
|
+
- Simpler QA and dogfooding in a single branch/CI surface.
|
|
50
|
+
|
|
51
|
+
### 3. Keep extraction path explicit
|
|
52
|
+
|
|
53
|
+
In-repo is not permanent by requirement. Plugin layout, manifest format, and loader/registry interfaces must remain portable so plugins can move to `kitfly-plugins` later with minimal disruption.
|
|
54
|
+
|
|
55
|
+
Extraction trigger signals:
|
|
56
|
+
|
|
57
|
+
- plugin maintenance cadence diverges from core,
|
|
58
|
+
- external contribution volume rises,
|
|
59
|
+
- plugin release/security pipeline becomes materially heavier.
|
|
60
|
+
|
|
61
|
+
### 4. Security and policy baseline
|
|
62
|
+
|
|
63
|
+
Distribution policy applies regardless of repo location:
|
|
64
|
+
|
|
65
|
+
- version pinning required,
|
|
66
|
+
- checksum verification required,
|
|
67
|
+
- SRI required for CDN assets,
|
|
68
|
+
- untrusted third-party plugins denied by default unless explicit opt-in.
|
|
69
|
+
|
|
70
|
+
## Consequences
|
|
71
|
+
|
|
72
|
+
### Positive
|
|
73
|
+
|
|
74
|
+
- Contract clarity reduces integration breakage and support ambiguity.
|
|
75
|
+
- In-repo startup reduces delivery friction for v0.2.0.
|
|
76
|
+
- Future repo split remains available without contract rewrite.
|
|
77
|
+
|
|
78
|
+
### Negative
|
|
79
|
+
|
|
80
|
+
- Core repo grows in scope and review surface in the short term.
|
|
81
|
+
- Requires discipline to prevent plugin internals from leaking into core assumptions.
|
|
82
|
+
|
|
83
|
+
### Neutral
|
|
84
|
+
|
|
85
|
+
- Repo location is an implementation detail; contract/API stability is the true long-term commitment.
|
|
86
|
+
|
|
87
|
+
## Compatibility Policy (Initial)
|
|
88
|
+
|
|
89
|
+
- Contract v1 supported throughout v0.2.x.
|
|
90
|
+
- If contract v2 is introduced, v1 support remains for at least one minor release.
|
|
91
|
+
- Compatibility matrix (kitfly version ↔ contract version) must be documented in plugin docs.
|
|
92
|
+
|
|
93
|
+
## Alternatives Considered
|
|
94
|
+
|
|
95
|
+
### Separate plugin repo immediately
|
|
96
|
+
|
|
97
|
+
Pros: cleaner ownership and release boundaries from day one.
|
|
98
|
+
Cons: slower early iteration and more cross-repo coordination while contracts are still fluid.
|
|
99
|
+
|
|
100
|
+
Decision: defer split until signals justify it.
|
|
101
|
+
|
|
102
|
+
### No formal contract versioning
|
|
103
|
+
|
|
104
|
+
Rejected: too much ambiguity and high breakage risk once plugins exist in the wild.
|
|
105
|
+
|
|
106
|
+
## References
|
|
107
|
+
|
|
108
|
+
- [DDR-0005: Deterministic Layout Boundary](DDR-0005-deterministic-layout-boundary.md)
|
|
109
|
+
- [Design Catalog: Shapes and Figures](../../content/reference/design-catalog.md)
|
|
110
|
+
- [ADR-0001: Minimalist Site Code](ADR-0001-minimalist-site-code.md)
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "DDR-0001: Viewport-Locked Layout with Fixed Footer Ribbon"
|
|
3
|
+
description: "Defines the kitfly page layout model: fixed chrome (header/footer) with scrollable middle band"
|
|
4
|
+
author: "uxdev"
|
|
5
|
+
supervised_by: "@3leapsdave"
|
|
6
|
+
date: "2026-02-06"
|
|
7
|
+
status: "accepted"
|
|
8
|
+
tags: ["ddr", "layout", "css", "ux"]
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
# DDR-0001: Viewport-Locked Layout with Fixed Footer Ribbon
|
|
12
|
+
|
|
13
|
+
## Status
|
|
14
|
+
|
|
15
|
+
Accepted
|
|
16
|
+
|
|
17
|
+
## Context
|
|
18
|
+
|
|
19
|
+
Kitfly sites use a three-column layout: sidebar navigation, main content, and a table-of-contents panel. The original footer was appended to the content flow with `margin-left` to offset past the sidebar, which caused several problems:
|
|
20
|
+
|
|
21
|
+
- Footer only covered the content pane, not the full viewport width
|
|
22
|
+
- Sidebar navigation extended below the footer, breaking visual hierarchy
|
|
23
|
+
- Footer position depended on content length — short pages had it mid-screen, long pages required scrolling to find it
|
|
24
|
+
- On mobile the footer needed separate margin overrides per breakpoint
|
|
25
|
+
|
|
26
|
+
## Decision
|
|
27
|
+
|
|
28
|
+
Adopt a **viewport-locked layout** where fixed chrome (footer ribbon, and mobile header) occupies known height at viewport edges, and the middle band (sidebar + content + TOC) fills the remaining space between them.
|
|
29
|
+
|
|
30
|
+
### Layout Model
|
|
31
|
+
|
|
32
|
+
```
|
|
33
|
+
┌──────────────────────────────────────────────────┐
|
|
34
|
+
│ (mobile header — 768px and below only) │
|
|
35
|
+
├────────────┬─────────────────────────┬───────────┤
|
|
36
|
+
│ │ │ │
|
|
37
|
+
│ SIDEBAR │ CONTENT │ TOC │
|
|
38
|
+
│ fixed │ scrollable │ fixed │
|
|
39
|
+
│ left │ center │ right │
|
|
40
|
+
│ 280px │ flex: 1 │ 200px │
|
|
41
|
+
│ │ │ │
|
|
42
|
+
│ top: 0 │ margin-left: sidebar │ top: 6r │
|
|
43
|
+
│ bottom: │ padding-bottom: │ │
|
|
44
|
+
│ footer │ footer + 1rem │ │
|
|
45
|
+
│ │ │ │
|
|
46
|
+
├────────────┴─────────────────────────┴───────────┤
|
|
47
|
+
│ FOOTER RIBBON │
|
|
48
|
+
│ position: fixed; bottom: 0; left: 0; right: 0 │
|
|
49
|
+
│ height: var(--footer-height) z-index: 300 │
|
|
50
|
+
│ full-width — spans all columns │
|
|
51
|
+
└──────────────────────────────────────────────────┘
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
### CSS Variables
|
|
55
|
+
|
|
56
|
+
| Variable | Value | Purpose |
|
|
57
|
+
| ----------------- | --------- | -------------------- |
|
|
58
|
+
| `--sidebar-width` | `280px` | Sidebar column width |
|
|
59
|
+
| `--footer-height` | `2.25rem` | Footer ribbon height |
|
|
60
|
+
|
|
61
|
+
### Z-Index Stack
|
|
62
|
+
|
|
63
|
+
| Layer | Z-Index | Element |
|
|
64
|
+
| -------------- | ------- | --------------------------- |
|
|
65
|
+
| Footer ribbon | 300 | `.site-footer` |
|
|
66
|
+
| Mobile header | 200 | `.mobile-header` |
|
|
67
|
+
| Mobile sidebar | 100 | `.sidebar` (mobile overlay) |
|
|
68
|
+
|
|
69
|
+
### Key Rules
|
|
70
|
+
|
|
71
|
+
1. **Footer is viewport-fixed**, not content-appended. It uses `position: fixed; bottom: 0` and spans full width.
|
|
72
|
+
2. **Sidebar stops above footer** via `bottom: var(--footer-height)` — no overlap, sidebar scrolls independently within its band.
|
|
73
|
+
3. **Content has bottom padding** of `calc(var(--footer-height) + 1rem)` so the last content line is never hidden behind the footer.
|
|
74
|
+
4. **Layout min-height** is `calc(100vh - var(--footer-height))` to prevent the document from extending behind the footer.
|
|
75
|
+
5. **Mobile breakpoints** inherit the same `--footer-height` variable — no per-breakpoint footer overrides needed.
|
|
76
|
+
6. **Print styles** hide the footer entirely (`.site-footer { display: none !important }`).
|
|
77
|
+
|
|
78
|
+
### Responsive Behavior
|
|
79
|
+
|
|
80
|
+
| Breakpoint | Sidebar | TOC | Footer |
|
|
81
|
+
| ---------- | ------------------ | ----------- | ------------------------ |
|
|
82
|
+
| > 1200px | Fixed left | Fixed right | Fixed bottom, full-width |
|
|
83
|
+
| 769–1200px | Fixed left (240px) | Hidden | Fixed bottom, full-width |
|
|
84
|
+
| ≤ 768px | Overlay (toggle) | Hidden | Fixed bottom, full-width |
|
|
85
|
+
|
|
86
|
+
The footer ribbon is consistent across all breakpoints — it never changes position or width.
|
|
87
|
+
|
|
88
|
+
## Consequences
|
|
89
|
+
|
|
90
|
+
### Positive
|
|
91
|
+
|
|
92
|
+
- Footer is always visible as a status/provenance ribbon without scrolling
|
|
93
|
+
- Sidebar navigation never extends below footer
|
|
94
|
+
- Single `--footer-height` variable controls all spacing — easy to adjust
|
|
95
|
+
- No per-breakpoint footer margin overrides
|
|
96
|
+
- Clean visual hierarchy: chrome frames content
|
|
97
|
+
|
|
98
|
+
### Negative
|
|
99
|
+
|
|
100
|
+
- Content needs `padding-bottom` to avoid being hidden — if `--footer-height` changes, padding must match (mitigated by using the CSS variable)
|
|
101
|
+
- Fixed footer consumes ~36px of viewport permanently — acceptable for the information density it provides (version, date, copyright, brand link)
|
|
102
|
+
|
|
103
|
+
## Alternatives Considered
|
|
104
|
+
|
|
105
|
+
### Sticky footer (content-appended)
|
|
106
|
+
|
|
107
|
+
The original approach. Footer stays in document flow but sticks to bottom on short pages. Rejected because it doesn't span the sidebar and creates layout inconsistencies across page lengths.
|
|
108
|
+
|
|
109
|
+
### CSS Grid viewport layout
|
|
110
|
+
|
|
111
|
+
Use `grid-template-rows: 1fr auto` on the body. Would work but requires restructuring the HTML template (moving sidebar inside a grid container). More invasive than necessary for the current fix.
|