@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.
- package/CHANGELOG.md +13 -0
- package/LICENSE +21 -0
- package/README.md +87 -0
- package/bin/barn.js +98 -0
- package/lib/index.js +93 -0
- package/lib/server.js +368 -0
- package/package.json +52 -0
- package/public/grainulation-tokens.css +321 -0
- package/public/index.html +907 -0
- package/templates/README.md +48 -0
- package/templates/adr.html +223 -0
- package/templates/adr.json +29 -0
- package/templates/brief.html +297 -0
- package/templates/brief.json +26 -0
- package/templates/certificate.html +247 -0
- package/templates/certificate.json +23 -0
- package/templates/changelog.html +239 -0
- package/templates/changelog.json +19 -0
- package/templates/ci-workflow.yml +52 -0
- package/templates/comparison.html +248 -0
- package/templates/comparison.json +21 -0
- package/templates/conflict-map.html +240 -0
- package/templates/conflict-map.json +19 -0
- package/templates/dashboard.html +515 -0
- package/templates/dashboard.json +22 -0
- package/templates/email-digest.html +178 -0
- package/templates/email-digest.json +18 -0
- package/templates/evidence-matrix.html +232 -0
- package/templates/evidence-matrix.json +21 -0
- package/templates/explainer.html +342 -0
- package/templates/explainer.json +23 -0
- package/templates/handoff.html +343 -0
- package/templates/handoff.json +24 -0
- package/templates/one-pager.html +248 -0
- package/templates/one-pager.json +22 -0
- package/templates/postmortem.html +303 -0
- package/templates/postmortem.json +20 -0
- package/templates/rfc.html +199 -0
- package/templates/rfc.json +32 -0
- package/templates/risk-register.html +231 -0
- package/templates/risk-register.json +22 -0
- package/templates/slide-deck.html +239 -0
- package/templates/slide-deck.json +23 -0
- package/templates/template.schema.json +25 -0
- package/templates/wiki-page.html +222 -0
- package/templates/wiki-page.json +23 -0
- package/tools/README.md +31 -0
- package/tools/build-pdf.js +43 -0
- package/tools/detect-sprints.js +292 -0
- package/tools/generate-manifest.js +237 -0
|
@@ -0,0 +1,199 @@
|
|
|
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>RFC-{{RFC_NUMBER}}: {{TITLE}}</title>
|
|
7
|
+
<style>
|
|
8
|
+
/* barn/templates/rfc.html — Request for Comments / design doc template
|
|
9
|
+
Self-contained, no external dependencies. */
|
|
10
|
+
|
|
11
|
+
:root {
|
|
12
|
+
--bg: #0a0e1a;
|
|
13
|
+
--bg2: #111827;
|
|
14
|
+
--bg3: #1e293b;
|
|
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
|
+
--text: #f1f5f9;
|
|
26
|
+
--text-muted: #94a3b8;
|
|
27
|
+
--text-dim: #64748b;
|
|
28
|
+
--border: rgba(255,255,255,0.08);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
* { margin: 0; padding: 0; box-sizing: border-box; }
|
|
32
|
+
|
|
33
|
+
body {
|
|
34
|
+
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Inter', sans-serif;
|
|
35
|
+
background: var(--bg);
|
|
36
|
+
color: var(--text);
|
|
37
|
+
font-size: 11pt;
|
|
38
|
+
line-height: 1.6;
|
|
39
|
+
-webkit-font-smoothing: antialiased;
|
|
40
|
+
max-width: 820px;
|
|
41
|
+
margin: 0 auto;
|
|
42
|
+
padding: 48px 24px;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
header { margin-bottom: 36px; border-bottom: 2px solid var(--accent); padding-bottom: 24px; }
|
|
46
|
+
|
|
47
|
+
.rfc-id {
|
|
48
|
+
font-size: 10pt;
|
|
49
|
+
font-weight: 600;
|
|
50
|
+
color: var(--text-dim);
|
|
51
|
+
text-transform: uppercase;
|
|
52
|
+
letter-spacing: 0.1em;
|
|
53
|
+
margin-bottom: 8px;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
h1 { font-size: 26pt; font-weight: 700; color: #fff; margin-bottom: 16px; line-height: 1.2; }
|
|
57
|
+
h2 {
|
|
58
|
+
font-size: 16pt; font-weight: 600; color: #fff;
|
|
59
|
+
margin: 36px 0 12px; padding-bottom: 8px;
|
|
60
|
+
border-bottom: 1px solid var(--border);
|
|
61
|
+
}
|
|
62
|
+
h3 { font-size: 13pt; font-weight: 600; color: var(--accent-light); margin: 20px 0 8px; }
|
|
63
|
+
p { color: var(--text-muted); margin-bottom: 12px; }
|
|
64
|
+
ul, ol { color: var(--text-muted); margin: 0 0 16px 20px; }
|
|
65
|
+
li { margin-bottom: 6px; }
|
|
66
|
+
|
|
67
|
+
.meta-table {
|
|
68
|
+
width: 100%;
|
|
69
|
+
border-collapse: collapse;
|
|
70
|
+
margin-bottom: 4px;
|
|
71
|
+
font-size: 10pt;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
.meta-table td {
|
|
75
|
+
padding: 6px 12px;
|
|
76
|
+
border-bottom: 1px solid var(--border);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
.meta-table td:first-child {
|
|
80
|
+
color: var(--text-dim);
|
|
81
|
+
font-weight: 600;
|
|
82
|
+
text-transform: uppercase;
|
|
83
|
+
letter-spacing: 0.06em;
|
|
84
|
+
width: 120px;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
.meta-table td:last-child { color: var(--text-muted); }
|
|
88
|
+
|
|
89
|
+
.status-badge {
|
|
90
|
+
display: inline-block;
|
|
91
|
+
font-size: 9pt;
|
|
92
|
+
font-weight: 700;
|
|
93
|
+
text-transform: uppercase;
|
|
94
|
+
letter-spacing: 0.08em;
|
|
95
|
+
padding: 3px 12px;
|
|
96
|
+
border-radius: 4px;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
.status-draft { background: rgba(100,116,139,0.2); color: var(--text-dim); }
|
|
100
|
+
.status-review { background: rgba(59,130,246,0.15); color: var(--accent-light); }
|
|
101
|
+
.status-accepted { background: var(--green-dim); color: var(--green); }
|
|
102
|
+
.status-rejected { background: var(--red-dim); color: var(--red); }
|
|
103
|
+
|
|
104
|
+
.section-block { background: var(--bg2); border: 1px solid var(--border); border-radius: 8px; padding: 20px 24px; margin-bottom: 16px; }
|
|
105
|
+
.alternative-card { background: var(--bg3); border: 1px solid var(--border); border-radius: 6px; padding: 16px 20px; margin-bottom: 12px; }
|
|
106
|
+
.alternative-card h4 { font-size: 12pt; font-weight: 600; color: var(--text); margin-bottom: 6px; }
|
|
107
|
+
.trade-off { display: flex; gap: 16px; margin-top: 8px; }
|
|
108
|
+
.trade-off .pro { flex: 1; border-left: 3px solid var(--green); padding-left: 10px; font-size: 10pt; color: var(--text-muted); }
|
|
109
|
+
.trade-off .con { flex: 1; border-left: 3px solid var(--red); padding-left: 10px; font-size: 10pt; color: var(--text-muted); }
|
|
110
|
+
.open-question { background: var(--bg3); border-left: 3px solid var(--orange); padding: 10px 14px; margin-bottom: 10px; border-radius: 0 6px 6px 0; font-size: 10pt; color: var(--text-muted); }
|
|
111
|
+
.claim-appendix table { width: 100%; border-collapse: collapse; font-size: 10pt; margin-top: 12px; }
|
|
112
|
+
.claim-appendix th { text-align: left; padding: 8px 12px; background: var(--bg3); color: var(--accent-light); font-size: 9pt; font-weight: 600; text-transform: uppercase; letter-spacing: 0.06em; border-bottom: 2px solid rgba(59,130,246,0.3); }
|
|
113
|
+
.claim-appendix td { padding: 8px 12px; border-bottom: 1px solid var(--border); color: var(--text-muted); }
|
|
114
|
+
|
|
115
|
+
.claim-ref { font-size: 8pt; color: var(--text-dim); font-family: monospace; }
|
|
116
|
+
|
|
117
|
+
footer {
|
|
118
|
+
margin-top: 40px;
|
|
119
|
+
padding-top: 16px;
|
|
120
|
+
border-top: 1px solid var(--border);
|
|
121
|
+
font-size: 8pt;
|
|
122
|
+
color: var(--text-dim);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
@media print {
|
|
126
|
+
body { background: #fff; color: #1a1a1a; max-width: 100%; }
|
|
127
|
+
header { border-color: #333; }
|
|
128
|
+
h1, h2, h3, h4 { color: #111; }
|
|
129
|
+
p, li, .meta-table td:last-child { color: #333; }
|
|
130
|
+
.meta-table td:first-child { color: #666; }
|
|
131
|
+
.section-block, .alternative-card, .open-question { background: #f5f5f5; border-color: #ddd; }
|
|
132
|
+
.claim-appendix th { background: #eee; color: #333; }
|
|
133
|
+
.claim-appendix td { color: #333; border-color: #ddd; }
|
|
134
|
+
.status-badge { border: 1px solid #ccc; }
|
|
135
|
+
.trade-off .pro { border-color: #228822; }
|
|
136
|
+
.trade-off .con { border-color: #cc2222; }
|
|
137
|
+
.open-question { border-color: #cc8800; }
|
|
138
|
+
a { color: #0066cc; }
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
@media (max-width: 600px) {
|
|
142
|
+
body { padding: 24px 16px; }
|
|
143
|
+
h1 { font-size: 20pt; }
|
|
144
|
+
h2 { font-size: 14pt; }
|
|
145
|
+
.section-block { padding: 14px 16px; }
|
|
146
|
+
.alternative-card { padding: 12px 14px; }
|
|
147
|
+
.trade-off { flex-direction: column; gap: 8px; }
|
|
148
|
+
.meta-table td:first-child { width: 90px; }
|
|
149
|
+
}
|
|
150
|
+
</style>
|
|
151
|
+
</head>
|
|
152
|
+
<body>
|
|
153
|
+
<article aria-label="Request for Comments: {{TITLE}}">
|
|
154
|
+
|
|
155
|
+
<header>
|
|
156
|
+
<div class="rfc-id">RFC-{{RFC_NUMBER}}</div>
|
|
157
|
+
<h1>{{TITLE}}</h1>
|
|
158
|
+
<table class="meta-table" aria-label="RFC metadata">
|
|
159
|
+
<tr><td>Author</td><td>{{AUTHOR}}</td></tr>
|
|
160
|
+
<tr><td>Status</td><td><span class="status-badge {{STATUS}}">{{STATUS}}</span></td></tr>
|
|
161
|
+
<tr><td>Date</td><td>{{DATE}}</td></tr>
|
|
162
|
+
</table>
|
|
163
|
+
</header>
|
|
164
|
+
|
|
165
|
+
<section aria-label="Problem statement">
|
|
166
|
+
<h2>Problem Statement</h2>
|
|
167
|
+
{{PROBLEM}}
|
|
168
|
+
</section>
|
|
169
|
+
|
|
170
|
+
<section aria-label="Proposed solution">
|
|
171
|
+
<h2>Proposed Solution</h2>
|
|
172
|
+
{{PROPOSAL}}
|
|
173
|
+
</section>
|
|
174
|
+
|
|
175
|
+
<section aria-label="Alternatives considered">
|
|
176
|
+
<h2>Alternatives Considered</h2>
|
|
177
|
+
{{ALTERNATIVES}}
|
|
178
|
+
</section>
|
|
179
|
+
|
|
180
|
+
<section aria-label="Open questions">
|
|
181
|
+
<h2>Open Questions</h2>
|
|
182
|
+
{{OPEN_QUESTIONS}}
|
|
183
|
+
</section>
|
|
184
|
+
|
|
185
|
+
<section aria-label="Rollout plan">
|
|
186
|
+
<h2>Rollout Plan</h2>
|
|
187
|
+
{{ROLLOUT}}
|
|
188
|
+
</section>
|
|
189
|
+
|
|
190
|
+
<section class="claim-appendix" aria-label="Claim appendix">
|
|
191
|
+
<h2>Appendix: Claim Inventory</h2>
|
|
192
|
+
{{CLAIM_APPENDIX}}
|
|
193
|
+
</section>
|
|
194
|
+
|
|
195
|
+
<footer>Built with barn -- grainulation</footer>
|
|
196
|
+
|
|
197
|
+
</article>
|
|
198
|
+
</body>
|
|
199
|
+
</html>
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
{
|
|
2
|
+
"title": "Request for Comments",
|
|
3
|
+
"description": "RFC / design doc format for engineering proposals. Includes problem statement, proposed solution, alternatives with trade-off analysis, open questions from unresolved claims, rollout plan, and full claim inventory appendix.",
|
|
4
|
+
"tags": ["rfc", "design-doc", "proposal", "review", "engineering"],
|
|
5
|
+
"author": "grainulation",
|
|
6
|
+
"version": "1.0.0",
|
|
7
|
+
"exportPresets": [
|
|
8
|
+
{ "name": "pdf", "format": "pdf" },
|
|
9
|
+
{ "name": "static-site", "format": "html" },
|
|
10
|
+
{ "name": "markdown-outline", "format": "md" }
|
|
11
|
+
],
|
|
12
|
+
"seedPacks": [
|
|
13
|
+
"architecture",
|
|
14
|
+
"api-design"
|
|
15
|
+
],
|
|
16
|
+
"scaffoldConfig": {
|
|
17
|
+
"defaultPlaceholders": {
|
|
18
|
+
"RFC_NUMBER": "000",
|
|
19
|
+
"TITLE": "Untitled RFC",
|
|
20
|
+
"AUTHOR": "",
|
|
21
|
+
"STATUS": "status-draft",
|
|
22
|
+
"DATE": "",
|
|
23
|
+
"PROBLEM": "",
|
|
24
|
+
"PROPOSAL": "",
|
|
25
|
+
"ALTERNATIVES": "",
|
|
26
|
+
"OPEN_QUESTIONS": "",
|
|
27
|
+
"ROLLOUT": "",
|
|
28
|
+
"CLAIM_APPENDIX": ""
|
|
29
|
+
},
|
|
30
|
+
"postInit": ["load-claims", "compile-brief"]
|
|
31
|
+
}
|
|
32
|
+
}
|
|
@@ -0,0 +1,231 @@
|
|
|
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}} -- {{SPRINT_NAME}}</title>
|
|
7
|
+
<style>
|
|
8
|
+
:root {
|
|
9
|
+
--bg: #0a0e1a;
|
|
10
|
+
--bg2: #111827;
|
|
11
|
+
--bg3: #1e293b;
|
|
12
|
+
--accent: #3b82f6;
|
|
13
|
+
--accent-light: #60a5fa;
|
|
14
|
+
--green: #22c55e;
|
|
15
|
+
--green-dim: rgba(34,197,94,0.15);
|
|
16
|
+
--orange: #f59e0b;
|
|
17
|
+
--orange-dim: rgba(245,158,11,0.15);
|
|
18
|
+
--red: #e11d48;
|
|
19
|
+
--red-dim: rgba(225,29,72,0.15);
|
|
20
|
+
--purple: #a78bfa;
|
|
21
|
+
--text: #f1f5f9;
|
|
22
|
+
--text-muted: #94a3b8;
|
|
23
|
+
--text-dim: #64748b;
|
|
24
|
+
--border: rgba(255,255,255,0.06);
|
|
25
|
+
}
|
|
26
|
+
* { margin: 0; padding: 0; box-sizing: border-box; }
|
|
27
|
+
html { scroll-snap-type: y mandatory; scroll-behavior: smooth; }
|
|
28
|
+
body {
|
|
29
|
+
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Inter', sans-serif;
|
|
30
|
+
background: var(--bg);
|
|
31
|
+
color: var(--text);
|
|
32
|
+
font-size: 10pt;
|
|
33
|
+
line-height: 1.5;
|
|
34
|
+
-webkit-font-smoothing: antialiased;
|
|
35
|
+
}
|
|
36
|
+
section {
|
|
37
|
+
scroll-snap-align: start;
|
|
38
|
+
min-height: 100vh;
|
|
39
|
+
padding: 40px;
|
|
40
|
+
display: flex;
|
|
41
|
+
flex-direction: column;
|
|
42
|
+
justify-content: center;
|
|
43
|
+
}
|
|
44
|
+
.header-section { justify-content: flex-end; padding-bottom: 80px; }
|
|
45
|
+
.header-section h1 {
|
|
46
|
+
font-size: 28pt;
|
|
47
|
+
font-weight: 800;
|
|
48
|
+
letter-spacing: -0.02em;
|
|
49
|
+
background: linear-gradient(135deg, #fff 0%, #94a3b8 100%);
|
|
50
|
+
-webkit-background-clip: text;
|
|
51
|
+
-webkit-text-fill-color: transparent;
|
|
52
|
+
margin-bottom: 12px;
|
|
53
|
+
}
|
|
54
|
+
.meta-row {
|
|
55
|
+
display: flex;
|
|
56
|
+
gap: 24px;
|
|
57
|
+
color: var(--text-muted);
|
|
58
|
+
font-size: 10pt;
|
|
59
|
+
font-family: monospace;
|
|
60
|
+
}
|
|
61
|
+
.summary-cards {
|
|
62
|
+
display: grid;
|
|
63
|
+
grid-template-columns: repeat(4, 1fr);
|
|
64
|
+
gap: 16px;
|
|
65
|
+
margin-top: 24px;
|
|
66
|
+
}
|
|
67
|
+
.summary-card {
|
|
68
|
+
background: var(--bg2);
|
|
69
|
+
border: 1px solid var(--border);
|
|
70
|
+
border-radius: 8px;
|
|
71
|
+
padding: 16px 20px;
|
|
72
|
+
text-align: center;
|
|
73
|
+
}
|
|
74
|
+
.summary-card .value {
|
|
75
|
+
font-size: 20pt;
|
|
76
|
+
font-weight: 800;
|
|
77
|
+
}
|
|
78
|
+
.summary-card .label {
|
|
79
|
+
font-size: 8pt;
|
|
80
|
+
text-transform: uppercase;
|
|
81
|
+
letter-spacing: 0.1em;
|
|
82
|
+
color: var(--text-dim);
|
|
83
|
+
margin-top: 4px;
|
|
84
|
+
}
|
|
85
|
+
.summary-card.total .value { color: var(--accent-light); }
|
|
86
|
+
.summary-card.mitigated .value { color: var(--green); }
|
|
87
|
+
.summary-card.open .value { color: var(--orange); }
|
|
88
|
+
.summary-card.critical .value { color: var(--red); }
|
|
89
|
+
.panel {
|
|
90
|
+
background: var(--bg2);
|
|
91
|
+
border-radius: 12px;
|
|
92
|
+
padding: 24px;
|
|
93
|
+
border: 1px solid var(--border);
|
|
94
|
+
}
|
|
95
|
+
.panel-title {
|
|
96
|
+
font-size: 9pt;
|
|
97
|
+
font-weight: 700;
|
|
98
|
+
text-transform: uppercase;
|
|
99
|
+
letter-spacing: 0.1em;
|
|
100
|
+
color: var(--text-dim);
|
|
101
|
+
margin-bottom: 16px;
|
|
102
|
+
}
|
|
103
|
+
.risk-table {
|
|
104
|
+
width: 100%;
|
|
105
|
+
border-collapse: collapse;
|
|
106
|
+
font-size: 9pt;
|
|
107
|
+
}
|
|
108
|
+
.risk-table th {
|
|
109
|
+
text-align: left;
|
|
110
|
+
padding: 10px 12px;
|
|
111
|
+
background: var(--bg3);
|
|
112
|
+
color: var(--text-dim);
|
|
113
|
+
font-weight: 700;
|
|
114
|
+
text-transform: uppercase;
|
|
115
|
+
letter-spacing: 0.06em;
|
|
116
|
+
font-size: 8pt;
|
|
117
|
+
border-bottom: 2px solid var(--border);
|
|
118
|
+
cursor: pointer;
|
|
119
|
+
user-select: none;
|
|
120
|
+
}
|
|
121
|
+
.risk-table th:hover { color: var(--text); }
|
|
122
|
+
.risk-table th .sort-indicator { margin-left: 4px; font-size: 7pt; }
|
|
123
|
+
.risk-table td {
|
|
124
|
+
padding: 10px 12px;
|
|
125
|
+
border-bottom: 1px solid var(--border);
|
|
126
|
+
color: var(--text-muted);
|
|
127
|
+
vertical-align: top;
|
|
128
|
+
}
|
|
129
|
+
.risk-table tr:hover td { background: rgba(255,255,255,0.02); }
|
|
130
|
+
.risk-table td:first-child { font-family: monospace; color: var(--text-dim); }
|
|
131
|
+
.severity-dot { display: inline-block; width: 10px; height: 10px; border-radius: 50%; margin-right: 6px; vertical-align: middle; }
|
|
132
|
+
.severity-dot.red { background: var(--red); } .severity-dot.amber { background: var(--orange); } .severity-dot.green { background: var(--green); }
|
|
133
|
+
.badge { display: inline-block; padding: 2px 8px; border-radius: 4px; font-size: 8pt; font-weight: 600; text-transform: uppercase; letter-spacing: 0.04em; }
|
|
134
|
+
.badge.production { color: var(--green); background: var(--green-dim); } .badge.tested { color: var(--accent-light); background: rgba(59,130,246,0.12); }
|
|
135
|
+
.badge.documented { color: var(--purple); background: rgba(167,139,250,0.12); } .badge.web { color: var(--orange); background: var(--orange-dim); }
|
|
136
|
+
.badge.stated { color: var(--text-dim); background: rgba(100,116,139,0.15); } .badge.open { color: var(--orange); background: var(--orange-dim); } .badge.mitigated { color: var(--green); background: var(--green-dim); }
|
|
137
|
+
.constraint-item { padding: 12px 16px; margin-bottom: 8px; border-radius: 8px; border-left: 3px solid var(--purple); background: rgba(167,139,250,0.08); }
|
|
138
|
+
.constraint-item .constraint-id { font-family: monospace; font-size: 8pt; color: var(--text-dim); margin-bottom: 4px; }
|
|
139
|
+
.constraint-item .constraint-text { font-size: 10pt; color: var(--text-muted); line-height: 1.4; }
|
|
140
|
+
.compilation-bar {
|
|
141
|
+
margin-top: 32px;
|
|
142
|
+
padding: 16px 24px;
|
|
143
|
+
background: var(--bg2);
|
|
144
|
+
border-radius: 8px;
|
|
145
|
+
border: 1px solid var(--border);
|
|
146
|
+
display: flex;
|
|
147
|
+
justify-content: space-between;
|
|
148
|
+
font-size: 9pt;
|
|
149
|
+
color: var(--text-dim);
|
|
150
|
+
}
|
|
151
|
+
@media (max-width: 768px) {
|
|
152
|
+
section { padding: 20px; min-height: auto; }
|
|
153
|
+
.header-section h1 { font-size: 18pt; }
|
|
154
|
+
.meta-row { flex-wrap: wrap; gap: 8px; font-size: 9pt; }
|
|
155
|
+
.summary-cards { grid-template-columns: repeat(2, 1fr); }
|
|
156
|
+
.panel { padding: 16px; overflow-x: auto; }
|
|
157
|
+
.risk-table { font-size: 8pt; }
|
|
158
|
+
.risk-table th, .risk-table td { padding: 6px 8px; }
|
|
159
|
+
.risk-table th:nth-child(6), .risk-table td:nth-child(6) { display: none; }
|
|
160
|
+
}
|
|
161
|
+
@media (max-width: 480px) {
|
|
162
|
+
.summary-cards { grid-template-columns: 1fr 1fr; gap: 8px; } .summary-card { padding: 12px; } .summary-card .value { font-size: 16pt; }
|
|
163
|
+
.risk-table th:nth-child(4), .risk-table td:nth-child(4) { display: none; }
|
|
164
|
+
}
|
|
165
|
+
@media print {
|
|
166
|
+
html { scroll-snap-type: none; }
|
|
167
|
+
section { min-height: auto; page-break-inside: avoid; padding: 16px 0; }
|
|
168
|
+
body { background: #fff; color: #111; }
|
|
169
|
+
.panel { border-color: #ccc; background: #f9f9f9; }
|
|
170
|
+
.risk-table th { background: #eee; }
|
|
171
|
+
.severity-dot.red { background: #c00; }
|
|
172
|
+
.severity-dot.amber { background: #c80; }
|
|
173
|
+
.severity-dot.green { background: #080; }
|
|
174
|
+
.compilation-bar { background: #f9f9f9; border-color: #ccc; }
|
|
175
|
+
}
|
|
176
|
+
</style>
|
|
177
|
+
</head>
|
|
178
|
+
<body>
|
|
179
|
+
|
|
180
|
+
<section class="header-section" aria-label="Risk register header">
|
|
181
|
+
<h1>{{TITLE}}</h1>
|
|
182
|
+
<div class="meta-row">
|
|
183
|
+
<span>Sprint: {{SPRINT_NAME}}</span>
|
|
184
|
+
<span>Review: {{REVIEW_DATE}}</span>
|
|
185
|
+
</div>
|
|
186
|
+
<div class="summary-cards" aria-label="Risk summary">
|
|
187
|
+
{{RISK_SUMMARY}}
|
|
188
|
+
</div>
|
|
189
|
+
</section>
|
|
190
|
+
|
|
191
|
+
<section aria-label="Risk table">
|
|
192
|
+
<div class="panel">
|
|
193
|
+
<div class="panel-title">Risk Register</div>
|
|
194
|
+
<table class="risk-table" role="grid" aria-label="Sortable risk register">
|
|
195
|
+
<thead>
|
|
196
|
+
<tr>
|
|
197
|
+
<th>ID <span class="sort-indicator"></span></th>
|
|
198
|
+
<th>Description <span class="sort-indicator"></span></th>
|
|
199
|
+
<th>Severity <span class="sort-indicator"></span></th>
|
|
200
|
+
<th>Evidence <span class="sort-indicator"></span></th>
|
|
201
|
+
<th>Status <span class="sort-indicator"></span></th>
|
|
202
|
+
<th>Mitigation</th>
|
|
203
|
+
</tr>
|
|
204
|
+
</thead>
|
|
205
|
+
<tbody>
|
|
206
|
+
{{RISK_TABLE}}
|
|
207
|
+
</tbody>
|
|
208
|
+
</table>
|
|
209
|
+
</div>
|
|
210
|
+
</section>
|
|
211
|
+
|
|
212
|
+
<section aria-label="Constraints">
|
|
213
|
+
<div class="panel">
|
|
214
|
+
<div class="panel-title">Constraints</div>
|
|
215
|
+
{{CONSTRAINTS}}
|
|
216
|
+
</div>
|
|
217
|
+
</section>
|
|
218
|
+
|
|
219
|
+
<section aria-label="Compilation footer">
|
|
220
|
+
<div class="compilation-bar">
|
|
221
|
+
<div>Compiled with barn</div>
|
|
222
|
+
<div style="font-family: monospace; font-size: 8pt;">{{CERTIFICATE_HASH}}</div>
|
|
223
|
+
</div>
|
|
224
|
+
</section>
|
|
225
|
+
|
|
226
|
+
<script>
|
|
227
|
+
(function(){var t=document.querySelector('.risk-table');if(!t)return;t.querySelectorAll('th').forEach(function(h,i){if(i>=5)return;h.addEventListener('click',function(){var b=t.querySelector('tbody'),r=Array.from(b.querySelectorAll('tr')),a=h.dataset.sort!=='asc';h.dataset.sort=a?'asc':'desc';r.sort(function(x,y){var u=(x.cells[i]||{}).textContent||'',v=(y.cells[i]||{}).textContent||'';return a?u.localeCompare(v):v.localeCompare(u)});r.forEach(function(w){b.appendChild(w)})})})})();
|
|
228
|
+
</script>
|
|
229
|
+
|
|
230
|
+
</body>
|
|
231
|
+
</html>
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
{
|
|
2
|
+
"title": "Risk Register",
|
|
3
|
+
"description": "Filtered view of risk and constraint claims for risk reviews. Sortable table with severity indicators, evidence tiers, and mitigation notes.",
|
|
4
|
+
"tags": ["risk", "register", "constraints", "review", "severity"],
|
|
5
|
+
"author": "grainulation",
|
|
6
|
+
"version": "1.0.0",
|
|
7
|
+
"exportPresets": [
|
|
8
|
+
{ "name": "pdf-landscape", "format": "pdf" },
|
|
9
|
+
{ "name": "static-site", "format": "html" }
|
|
10
|
+
],
|
|
11
|
+
"seedPacks": [
|
|
12
|
+
"security",
|
|
13
|
+
"compliance"
|
|
14
|
+
],
|
|
15
|
+
"scaffoldConfig": {
|
|
16
|
+
"defaultPlaceholders": {
|
|
17
|
+
"TITLE": "Risk Register",
|
|
18
|
+
"SPRINT_NAME": "Untitled Sprint"
|
|
19
|
+
},
|
|
20
|
+
"postInit": ["load-claims", "filter-risks"]
|
|
21
|
+
}
|
|
22
|
+
}
|