@grainulation/barn 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (50) hide show
  1. package/CHANGELOG.md +13 -0
  2. package/LICENSE +21 -0
  3. package/README.md +87 -0
  4. package/bin/barn.js +98 -0
  5. package/lib/index.js +93 -0
  6. package/lib/server.js +368 -0
  7. package/package.json +52 -0
  8. package/public/grainulation-tokens.css +321 -0
  9. package/public/index.html +907 -0
  10. package/templates/README.md +48 -0
  11. package/templates/adr.html +223 -0
  12. package/templates/adr.json +29 -0
  13. package/templates/brief.html +297 -0
  14. package/templates/brief.json +26 -0
  15. package/templates/certificate.html +247 -0
  16. package/templates/certificate.json +23 -0
  17. package/templates/changelog.html +239 -0
  18. package/templates/changelog.json +19 -0
  19. package/templates/ci-workflow.yml +52 -0
  20. package/templates/comparison.html +248 -0
  21. package/templates/comparison.json +21 -0
  22. package/templates/conflict-map.html +240 -0
  23. package/templates/conflict-map.json +19 -0
  24. package/templates/dashboard.html +515 -0
  25. package/templates/dashboard.json +22 -0
  26. package/templates/email-digest.html +178 -0
  27. package/templates/email-digest.json +18 -0
  28. package/templates/evidence-matrix.html +232 -0
  29. package/templates/evidence-matrix.json +21 -0
  30. package/templates/explainer.html +342 -0
  31. package/templates/explainer.json +23 -0
  32. package/templates/handoff.html +343 -0
  33. package/templates/handoff.json +24 -0
  34. package/templates/one-pager.html +248 -0
  35. package/templates/one-pager.json +22 -0
  36. package/templates/postmortem.html +303 -0
  37. package/templates/postmortem.json +20 -0
  38. package/templates/rfc.html +199 -0
  39. package/templates/rfc.json +32 -0
  40. package/templates/risk-register.html +231 -0
  41. package/templates/risk-register.json +22 -0
  42. package/templates/slide-deck.html +239 -0
  43. package/templates/slide-deck.json +23 -0
  44. package/templates/template.schema.json +25 -0
  45. package/templates/wiki-page.html +222 -0
  46. package/templates/wiki-page.json +23 -0
  47. package/tools/README.md +31 -0
  48. package/tools/build-pdf.js +43 -0
  49. package/tools/detect-sprints.js +292 -0
  50. package/tools/generate-manifest.js +237 -0
@@ -0,0 +1,342 @@
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>{{TITLE}}</title>
7
+ <style>
8
+ /* barn/templates/explainer.html — dark scroll-snap presentation template
9
+ System font stack, no external dependencies, fully self-contained. */
10
+
11
+ :root {
12
+ --bg-dark: #0f172a;
13
+ --bg-card: #1e293b;
14
+ --bg-card-hover: #263548;
15
+ --accent: #3b82f6;
16
+ --accent-light: #60a5fa;
17
+ --green: #22c55e;
18
+ --green-dim: rgba(34,197,94,0.12);
19
+ --orange: #f59e0b;
20
+ --orange-dim: rgba(245,158,11,0.12);
21
+ --red: #e11d48;
22
+ --red-dim: rgba(225,29,72,0.12);
23
+ --purple: #a78bfa;
24
+ --purple-dim: rgba(167,139,250,0.12);
25
+ --pink: #f472b6;
26
+ --pink-dim: rgba(244,114,182,0.12);
27
+ --text: #f1f5f9;
28
+ --text-muted: #94a3b8;
29
+ --text-dim: #64748b;
30
+ }
31
+
32
+ * { margin: 0; padding: 0; box-sizing: border-box; }
33
+
34
+ html, body {
35
+ height: 100%;
36
+ margin: 0;
37
+ scroll-behavior: smooth;
38
+ }
39
+
40
+ html {
41
+ overflow-y: scroll;
42
+ scroll-snap-type: y mandatory;
43
+ }
44
+
45
+ body {
46
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Inter', sans-serif;
47
+ background: var(--bg-dark);
48
+ color: var(--text);
49
+ font-size: 11pt;
50
+ line-height: 1.5;
51
+ -webkit-font-smoothing: antialiased;
52
+ overflow-y: scroll;
53
+ scroll-snap-type: y mandatory;
54
+ }
55
+
56
+ .slide {
57
+ width: 100%;
58
+ height: 100vh;
59
+ padding: 60px 80px;
60
+ display: flex;
61
+ flex-direction: column;
62
+ justify-content: center;
63
+ position: relative;
64
+ overflow: hidden;
65
+ scroll-snap-align: start;
66
+ }
67
+
68
+ .slide::before {
69
+ content: '';
70
+ position: absolute;
71
+ top: 0;
72
+ right: 0;
73
+ width: 40%;
74
+ height: 100%;
75
+ background: radial-gradient(ellipse at top right, rgba(59,130,246,0.08) 0%, transparent 70%);
76
+ pointer-events: none;
77
+ }
78
+
79
+ h1 {
80
+ font-size: 42pt;
81
+ font-weight: 800;
82
+ letter-spacing: -0.03em;
83
+ line-height: 1.1;
84
+ margin-bottom: 16px;
85
+ background: linear-gradient(135deg, #fff 0%, #94a3b8 100%);
86
+ -webkit-background-clip: text;
87
+ -webkit-text-fill-color: transparent;
88
+ }
89
+
90
+ h2 {
91
+ font-size: 32pt;
92
+ font-weight: 700;
93
+ letter-spacing: -0.02em;
94
+ line-height: 1.15;
95
+ margin-bottom: 24px;
96
+ color: #fff;
97
+ }
98
+
99
+ h3 {
100
+ font-size: 14pt;
101
+ font-weight: 600;
102
+ color: var(--accent-light);
103
+ margin-bottom: 12px;
104
+ text-transform: uppercase;
105
+ letter-spacing: 0.08em;
106
+ }
107
+
108
+ h4 {
109
+ font-size: 13pt;
110
+ font-weight: 600;
111
+ color: var(--text);
112
+ margin-bottom: 8px;
113
+ }
114
+
115
+ p {
116
+ font-size: 14pt;
117
+ color: var(--text-muted);
118
+ line-height: 1.6;
119
+ margin-bottom: 12px;
120
+ text-align: left;
121
+ font-weight: 400;
122
+ max-width: 85%;
123
+ }
124
+
125
+ .subtitle {
126
+ font-size: 18pt;
127
+ color: var(--text-muted);
128
+ font-weight: 300;
129
+ max-width: 70%;
130
+ }
131
+
132
+ .label {
133
+ display: inline-block;
134
+ font-size: 9pt;
135
+ font-weight: 600;
136
+ letter-spacing: 0.12em;
137
+ text-transform: uppercase;
138
+ color: var(--accent-light);
139
+ background: rgba(59,130,246,0.12);
140
+ padding: 4px 12px;
141
+ border-radius: 4px;
142
+ margin-bottom: 16px;
143
+ }
144
+
145
+ .label.green { color: var(--green); background: var(--green-dim); }
146
+ .label.orange { color: var(--orange); background: var(--orange-dim); }
147
+ .label.red { color: var(--red); background: var(--red-dim); }
148
+ .label.purple { color: var(--purple); background: var(--purple-dim); }
149
+ .label.pink { color: var(--pink); background: var(--pink-dim); }
150
+
151
+ .divider {
152
+ width: 60px;
153
+ height: 3px;
154
+ background: var(--accent);
155
+ border-radius: 2px;
156
+ margin: 16px 0 24px 0;
157
+ }
158
+
159
+ .two-col {
160
+ display: flex;
161
+ gap: 60px;
162
+ align-items: flex-start;
163
+ }
164
+
165
+ .two-col > div { flex: 1; }
166
+
167
+ .three-col {
168
+ display: flex;
169
+ gap: 24px;
170
+ align-items: stretch;
171
+ }
172
+
173
+ .three-col > div { flex: 1; }
174
+
175
+ .card {
176
+ background: var(--bg-card);
177
+ border-radius: 16px;
178
+ padding: 32px;
179
+ border: 1px solid rgba(255,255,255,0.06);
180
+ position: relative;
181
+ overflow: hidden;
182
+ }
183
+
184
+ .card::after {
185
+ content: '';
186
+ position: absolute;
187
+ top: 0;
188
+ left: 0;
189
+ width: 4px;
190
+ height: 100%;
191
+ background: var(--accent);
192
+ border-radius: 4px 0 0 4px;
193
+ }
194
+
195
+ .card.green::after { background: var(--green); }
196
+ .card.orange::after { background: var(--orange); }
197
+ .card.red::after { background: var(--red); }
198
+ .card.purple::after { background: var(--purple); }
199
+ .card.pink::after { background: var(--pink); }
200
+
201
+ .card-label {
202
+ font-size: 9pt;
203
+ font-weight: 600;
204
+ text-transform: uppercase;
205
+ letter-spacing: 0.1em;
206
+ color: var(--accent-light);
207
+ margin-bottom: 8px;
208
+ }
209
+
210
+ .card.green .card-label { color: var(--green); }
211
+ .card.orange .card-label { color: var(--orange); }
212
+ .card.red .card-label { color: var(--red); }
213
+ .card.purple .card-label { color: var(--purple); }
214
+
215
+ .card-text {
216
+ font-size: 16pt;
217
+ color: var(--text);
218
+ line-height: 1.5;
219
+ font-weight: 500;
220
+ }
221
+
222
+ .card-detail {
223
+ font-size: 12pt;
224
+ color: var(--text-muted);
225
+ line-height: 1.5;
226
+ margin-top: 12px;
227
+ }
228
+
229
+ table {
230
+ width: 100%;
231
+ border-collapse: collapse;
232
+ margin: 16px 0;
233
+ font-size: 11pt;
234
+ }
235
+
236
+ th {
237
+ text-align: left;
238
+ padding: 10px 16px;
239
+ background: var(--bg-card);
240
+ color: var(--accent-light);
241
+ font-weight: 600;
242
+ font-size: 9pt;
243
+ text-transform: uppercase;
244
+ letter-spacing: 0.08em;
245
+ border-bottom: 2px solid rgba(59,130,246,0.3);
246
+ }
247
+
248
+ td {
249
+ padding: 10px 16px;
250
+ border-bottom: 1px solid rgba(255,255,255,0.06);
251
+ color: var(--text-muted);
252
+ }
253
+
254
+ tr:hover td {
255
+ background: rgba(255,255,255,0.02);
256
+ }
257
+
258
+ .claim-ref {
259
+ font-size: 8pt;
260
+ color: var(--text-dim);
261
+ font-family: monospace;
262
+ }
263
+
264
+ .slide-nav {
265
+ position: fixed;
266
+ right: 24px;
267
+ top: 50%;
268
+ transform: translateY(-50%);
269
+ display: flex;
270
+ flex-direction: column;
271
+ gap: 8px;
272
+ z-index: 100;
273
+ }
274
+
275
+ .slide-nav a {
276
+ width: 8px;
277
+ height: 8px;
278
+ border-radius: 50%;
279
+ background: var(--text-dim);
280
+ display: block;
281
+ transition: all 0.2s;
282
+ }
283
+
284
+ .slide-nav a:hover,
285
+ .slide-nav a.active {
286
+ background: var(--accent);
287
+ transform: scale(1.5);
288
+ }
289
+
290
+ @keyframes fadeInUp {
291
+ from { transform: translateY(20px); opacity: 0; }
292
+ to { transform: translateY(0); opacity: 1; }
293
+ }
294
+
295
+ .fade-in {
296
+ animation: fadeInUp 0.6s ease-out forwards;
297
+ }
298
+
299
+ .barn-footer {
300
+ position: absolute;
301
+ bottom: 24px;
302
+ right: 40px;
303
+ font-size: 8pt;
304
+ color: var(--text-dim);
305
+ letter-spacing: 0.05em;
306
+ }
307
+
308
+ @media (max-width: 768px) {
309
+ .slide { padding: 32px 20px; height: auto; min-height: 100vh; }
310
+ h1 { font-size: 24pt; }
311
+ h2 { font-size: 20pt; }
312
+ h3 { font-size: 12pt; }
313
+ p, .subtitle { font-size: 12pt; max-width: 100%; }
314
+ .two-col, .three-col { flex-direction: column; gap: 20px; }
315
+ .card { padding: 20px; }
316
+ .card-text { font-size: 13pt; }
317
+ .card-detail { font-size: 11pt; }
318
+ .slide-nav { display: none; }
319
+ .barn-footer { right: 20px; bottom: 16px; }
320
+ table { font-size: 9pt; }
321
+ th, td { padding: 6px 10px; }
322
+ }
323
+ </style>
324
+ </head>
325
+ <body>
326
+
327
+ <!-- TEMPLATE: Replace slide content below with your content -->
328
+ <!-- Each .slide div becomes a full-screen scroll-snap section -->
329
+
330
+ <div class="slide">
331
+ <span class="label">Research Sprint</span>
332
+ <h1>{{TITLE}}</h1>
333
+ <p class="subtitle">{{SUBTITLE}}</p>
334
+ <div class="barn-footer">Built with barn</div>
335
+ </div>
336
+
337
+ <!-- Add more slides as needed -->
338
+ <!-- Use .card, .two-col, .three-col, table, .label for layout -->
339
+ <!-- Reference claims with <span class="claim-ref">[r001]</span> -->
340
+
341
+ </body>
342
+ </html>
@@ -0,0 +1,23 @@
1
+ {
2
+ "title": "Explainer",
3
+ "description": "Dark scroll-snap presentation template with responsive slides. Ideal for research briefs and topic deep-dives.",
4
+ "tags": ["explainer", "presentation", "scroll-snap", "slides", "research"],
5
+ "author": "grainulation",
6
+ "version": "1.0.0",
7
+ "exportPresets": [
8
+ { "name": "pdf-slides", "format": "pdf" },
9
+ { "name": "static-site", "format": "html" },
10
+ { "name": "markdown-outline", "format": "md" }
11
+ ],
12
+ "seedPacks": [
13
+ "research-findings",
14
+ "evidence-tiers"
15
+ ],
16
+ "scaffoldConfig": {
17
+ "defaultPlaceholders": {
18
+ "TITLE": "Research Explainer",
19
+ "TOPIC": "Untitled Topic"
20
+ },
21
+ "postInit": ["load-claims", "compile-brief"]
22
+ }
23
+ }
@@ -0,0 +1,343 @@
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>{{TITLE}} — Handoff</title>
7
+ <style>
8
+ /* barn/templates/handoff.html — knowledge transfer document
9
+ System font stack, no external dependencies, fully self-contained. */
10
+
11
+ :root {
12
+ --bg: #0a0e1a;
13
+ --bg2: #111827;
14
+ --bg3: #1e293b;
15
+ --accent: #3b82f6;
16
+ --accent-light: #60a5fa;
17
+ --green: #22c55e;
18
+ --orange: #f59e0b;
19
+ --red: #e11d48;
20
+ --purple: #a78bfa;
21
+ --text: #f1f5f9;
22
+ --text-muted: #94a3b8;
23
+ --text-dim: #64748b;
24
+ --border: rgba(255,255,255,0.06);
25
+ }
26
+
27
+ * { margin: 0; padding: 0; box-sizing: border-box; }
28
+ html { height: 100%; scroll-behavior: smooth; scroll-snap-type: y mandatory; overflow-y: scroll; }
29
+
30
+ body {
31
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Inter', sans-serif;
32
+ background: var(--bg);
33
+ color: var(--text);
34
+ font-size: 11pt;
35
+ line-height: 1.5;
36
+ -webkit-font-smoothing: antialiased;
37
+ }
38
+
39
+ section {
40
+ min-height: 100vh;
41
+ padding: 60px 80px;
42
+ display: flex;
43
+ flex-direction: column;
44
+ justify-content: center;
45
+ scroll-snap-align: start;
46
+ position: relative;
47
+ }
48
+
49
+ section::before {
50
+ content: '';
51
+ position: absolute;
52
+ top: 0; right: 0;
53
+ width: 35%; height: 100%;
54
+ background: radial-gradient(ellipse at top right, rgba(59,130,246,0.06) 0%, transparent 70%);
55
+ pointer-events: none;
56
+ }
57
+
58
+ h1 {
59
+ font-size: 36pt;
60
+ font-weight: 800;
61
+ letter-spacing: -0.03em;
62
+ line-height: 1.1;
63
+ margin-bottom: 12px;
64
+ background: linear-gradient(135deg, #fff 0%, #94a3b8 100%);
65
+ -webkit-background-clip: text;
66
+ -webkit-text-fill-color: transparent;
67
+ }
68
+
69
+ h2 {
70
+ font-size: 24pt;
71
+ font-weight: 700;
72
+ letter-spacing: -0.02em;
73
+ margin-bottom: 20px;
74
+ color: #fff;
75
+ }
76
+
77
+ .section-label {
78
+ display: inline-block;
79
+ font-size: 9pt;
80
+ font-weight: 600;
81
+ letter-spacing: 0.12em;
82
+ text-transform: uppercase;
83
+ color: var(--accent-light);
84
+ background: rgba(59,130,246,0.12);
85
+ padding: 4px 12px;
86
+ border-radius: 4px;
87
+ margin-bottom: 16px;
88
+ }
89
+
90
+ .context-block {
91
+ background: var(--bg2);
92
+ border-radius: 12px;
93
+ padding: 24px;
94
+ border: 1px solid var(--border);
95
+ margin-top: 20px;
96
+ max-width: 85%;
97
+ }
98
+
99
+ .context-row {
100
+ display: flex;
101
+ gap: 12px;
102
+ padding: 8px 0;
103
+ border-bottom: 1px solid var(--border);
104
+ font-size: 10pt;
105
+ }
106
+
107
+ .context-row:last-child { border-bottom: none; }
108
+
109
+ .context-key {
110
+ width: 120px;
111
+ flex-shrink: 0;
112
+ color: var(--text-dim);
113
+ font-weight: 600;
114
+ text-transform: uppercase;
115
+ letter-spacing: 0.06em;
116
+ font-size: 9pt;
117
+ padding-top: 2px;
118
+ }
119
+
120
+ .context-value { color: var(--text-muted); line-height: 1.5; }
121
+
122
+ .timeline-item {
123
+ display: flex;
124
+ gap: 20px;
125
+ padding: 16px 0;
126
+ border-bottom: 1px solid var(--border);
127
+ align-items: flex-start;
128
+ }
129
+
130
+ .timeline-item:last-child { border-bottom: none; }
131
+
132
+ .timeline-phase {
133
+ width: 100px;
134
+ flex-shrink: 0;
135
+ font-size: 9pt;
136
+ font-weight: 700;
137
+ text-transform: uppercase;
138
+ letter-spacing: 0.08em;
139
+ color: var(--accent-light);
140
+ padding-top: 2px;
141
+ }
142
+
143
+ .timeline-phase.completed { color: var(--green); }
144
+ .timeline-phase.active { color: var(--orange); }
145
+ .timeline-content { font-size: 10pt; color: var(--text-muted); line-height: 1.5; }
146
+
147
+ .decision-card {
148
+ background: var(--bg2);
149
+ border-radius: 10px;
150
+ padding: 16px 20px;
151
+ border: 1px solid var(--border);
152
+ border-left: 3px solid var(--green);
153
+ margin-bottom: 12px;
154
+ }
155
+
156
+ .decision-title { font-size: 11pt; font-weight: 600; color: var(--text); margin-bottom: 4px; }
157
+ .decision-detail { font-size: 10pt; color: var(--text-muted); line-height: 1.4; }
158
+ .decision-ref { font-family: monospace; font-size: 8pt; color: var(--text-dim); margin-top: 6px; }
159
+
160
+ .open-card {
161
+ background: var(--bg2);
162
+ border-radius: 10px;
163
+ padding: 16px 20px;
164
+ border: 1px solid var(--border);
165
+ border-left: 3px solid var(--orange);
166
+ margin-bottom: 12px;
167
+ }
168
+
169
+ .claim-table { width: 100%; border-collapse: collapse; font-size: 9pt; }
170
+
171
+ .claim-table th {
172
+ text-align: left;
173
+ padding: 8px 12px;
174
+ background: var(--bg2);
175
+ color: var(--text-dim);
176
+ font-weight: 700;
177
+ text-transform: uppercase;
178
+ letter-spacing: 0.06em;
179
+ font-size: 8pt;
180
+ border-bottom: 2px solid var(--border);
181
+ }
182
+
183
+ .claim-table td { padding: 8px 12px; border-bottom: 1px solid var(--border); color: var(--text-muted); }
184
+ .claim-table tr:hover td { background: rgba(255,255,255,0.02); }
185
+
186
+ .badge {
187
+ display: inline-block;
188
+ padding: 2px 8px;
189
+ border-radius: 4px;
190
+ font-size: 8pt;
191
+ font-weight: 600;
192
+ text-transform: uppercase;
193
+ letter-spacing: 0.04em;
194
+ }
195
+
196
+ .badge.factual { color: var(--accent-light); background: rgba(59,130,246,0.12); }
197
+ .badge.constraint { color: var(--purple); background: rgba(167,139,250,0.12); }
198
+ .badge.estimate { color: var(--orange); background: rgba(245,158,11,0.12); }
199
+ .badge.risk { color: var(--red); background: rgba(225,29,72,0.12); }
200
+ .badge.recommendation { color: var(--green); background: rgba(34,197,94,0.12); }
201
+ .badge.feedback { color: #f472b6; background: rgba(244,114,182,0.12); }
202
+
203
+ .next-steps-list { list-style: none; padding: 0; }
204
+
205
+ .next-steps-list li {
206
+ background: var(--bg2);
207
+ border-radius: 10px;
208
+ padding: 16px 20px;
209
+ border: 1px solid var(--border);
210
+ margin-bottom: 10px;
211
+ font-size: 10pt;
212
+ color: var(--text-muted);
213
+ line-height: 1.5;
214
+ }
215
+
216
+ .next-steps-list li code {
217
+ font-family: monospace;
218
+ font-size: 9pt;
219
+ background: var(--bg3);
220
+ padding: 2px 6px;
221
+ border-radius: 4px;
222
+ color: var(--accent-light);
223
+ }
224
+
225
+ .barn-footer {
226
+ position: absolute;
227
+ bottom: 24px; right: 40px;
228
+ font-size: 8pt;
229
+ color: var(--text-dim);
230
+ letter-spacing: 0.05em;
231
+ }
232
+
233
+ nav[aria-label="sections"] {
234
+ position: fixed; right: 24px; top: 50%; transform: translateY(-50%);
235
+ display: flex; flex-direction: column; gap: 8px; z-index: 100;
236
+ }
237
+
238
+ nav[aria-label="sections"] a {
239
+ width: 8px; height: 8px; border-radius: 50%;
240
+ background: var(--text-dim); display: block; transition: all 0.2s;
241
+ }
242
+
243
+ nav[aria-label="sections"] a:hover { background: var(--accent); transform: scale(1.5); }
244
+
245
+ @media (max-width: 768px) {
246
+ section { padding: 32px 20px; height: auto; }
247
+ h1 { font-size: 22pt; } h2 { font-size: 18pt; }
248
+ .context-block { max-width: 100%; }
249
+ .context-row { flex-direction: column; gap: 2px; }
250
+ .context-key { width: auto; }
251
+ .timeline-item { flex-direction: column; gap: 4px; }
252
+ .timeline-phase { width: auto; }
253
+ .claim-table { font-size: 8pt; }
254
+ .claim-table th, .claim-table td { padding: 6px 8px; }
255
+ .claim-table th:nth-child(4), .claim-table td:nth-child(4) { display: none; }
256
+ nav[aria-label="sections"] { display: none; }
257
+ .barn-footer { right: 20px; bottom: 16px; }
258
+ }
259
+
260
+ @media print {
261
+ html { scroll-snap-type: none; }
262
+ section { min-height: auto; height: auto; page-break-after: always; padding: 40px; }
263
+ body { background: #fff; color: #1a1a1a; }
264
+ h1 { background: none; -webkit-text-fill-color: #1a1a1a; }
265
+ h2 { color: #1a1a1a; }
266
+ .context-block, .decision-card, .open-card, .next-steps-list li { background: #f5f5f5; border-color: #ddd; }
267
+ .context-value, .decision-detail, .timeline-content { color: #333; }
268
+ nav[aria-label="sections"], .barn-footer { display: none; }
269
+ }
270
+ </style>
271
+ </head>
272
+ <body>
273
+
274
+ <nav aria-label="sections">
275
+ <a href="#context" title="Sprint Context"></a>
276
+ <a href="#timeline" title="Timeline"></a>
277
+ <a href="#decisions" title="Key Decisions"></a>
278
+ <a href="#open" title="Open Questions"></a>
279
+ <a href="#inventory" title="Claim Inventory"></a>
280
+ <a href="#continue" title="How to Continue"></a>
281
+ </nav>
282
+
283
+ <section id="context" aria-label="Sprint Context">
284
+ <span class="section-label">Handoff Document</span>
285
+ <h1>{{TITLE}}</h1>
286
+ <div class="context-block">
287
+ <div class="context-row">
288
+ <div class="context-key">Sprint</div>
289
+ <div class="context-value">{{SPRINT_NAME}}</div>
290
+ </div>
291
+ <div class="context-row">
292
+ <div class="context-key">Question</div>
293
+ <div class="context-value">{{QUESTION}}</div>
294
+ </div>
295
+ <div class="context-row">
296
+ <div class="context-key">Audience</div>
297
+ <div class="context-value">{{AUDIENCE}}</div>
298
+ </div>
299
+ </div>
300
+ <div class="barn-footer">Built with barn</div>
301
+ </section>
302
+
303
+ <section id="timeline" aria-label="What You Need to Know">
304
+ <span class="section-label">Timeline</span>
305
+ <h2>What You Need to Know</h2>
306
+ {{TIMELINE}}
307
+ </section>
308
+
309
+ <section id="decisions" aria-label="Key Decisions">
310
+ <span class="section-label">Decisions Made</span>
311
+ <h2>Key Decisions</h2>
312
+ {{DECISIONS}}
313
+ </section>
314
+
315
+ <section id="open" aria-label="Open Questions">
316
+ <span class="section-label">Unresolved</span>
317
+ <h2>Open Questions</h2>
318
+ {{OPEN_QUESTIONS}}
319
+ </section>
320
+
321
+ <section id="inventory" aria-label="Claim Inventory">
322
+ <span class="section-label">Full Inventory</span>
323
+ <h2>All Claims</h2>
324
+ <table class="claim-table">
325
+ <thead>
326
+ <tr><th>ID</th><th>Type</th><th>Content</th><th>Evidence</th><th>Status</th></tr>
327
+ </thead>
328
+ <tbody>
329
+ {{CLAIM_TABLE}}
330
+ </tbody>
331
+ </table>
332
+ </section>
333
+
334
+ <section id="continue" aria-label="How to Continue">
335
+ <span class="section-label">Next Steps</span>
336
+ <h2>How to Continue</h2>
337
+ <ul class="next-steps-list">
338
+ {{NEXT_STEPS}}
339
+ </ul>
340
+ </section>
341
+
342
+ </body>
343
+ </html>