@cyber-dash-tech/revela 0.15.2 → 0.15.4
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/README.md +62 -108
- package/README.zh-CN.md +63 -108
- package/designs/starter/DESIGN.md +33 -14
- package/designs/starter/preview.html +23 -16
- package/designs/summit/DESIGN.md +35 -42
- package/designs/summit/preview.html +49 -49
- package/lib/commands/brief.ts +1 -1
- package/lib/commands/designs-new.ts +6 -6
- package/lib/commands/designs.ts +9 -9
- package/lib/commands/domains.ts +9 -9
- package/lib/commands/edit.ts +1 -1
- package/lib/commands/help.ts +34 -37
- package/lib/commands/init.ts +1 -1
- package/lib/commands/inspect.ts +2 -20
- package/lib/commands/narrative.ts +3 -3
- package/lib/commands/pdf.ts +3 -3
- package/lib/commands/pptx.ts +2 -2
- package/lib/commands/refine.ts +3 -3
- package/lib/commands/review.ts +14 -7
- package/lib/decks-state.ts +6 -6
- package/lib/edit/deck-state.ts +1 -1
- package/lib/edit/resolve-deck.ts +1 -1
- package/lib/inspect/server.ts +2 -2
- package/lib/prompt-builder.ts +20 -14
- package/lib/refine/server.ts +50 -33
- package/package.json +1 -1
- package/plugin.ts +140 -281
- package/skill/NARRATIVE_SKILL.md +17 -19
- package/skill/SKILL.md +220 -477
- package/tools/edit.ts +6 -6
- package/tools/inspection-result.ts +1 -1
- package/lib/commands/disable.ts +0 -14
- package/lib/commands/enable.ts +0 -48
package/designs/summit/DESIGN.md
CHANGED
|
@@ -31,8 +31,8 @@ Apply this visual style when generating all slides in this session.
|
|
|
31
31
|
--accent-danger: #b94a3c;
|
|
32
32
|
--accent-sage: #9eb0a6;
|
|
33
33
|
--shadow-soft: rgba(0, 0, 0, 0.18);
|
|
34
|
-
--font-display: '
|
|
35
|
-
--font-body: '
|
|
34
|
+
--font-display: 'Montserrat', ui-sans-serif, sans-serif;
|
|
35
|
+
--font-body: 'Montserrat', ui-sans-serif, sans-serif;
|
|
36
36
|
--font-size-body: 17px;
|
|
37
37
|
--font-size-meta: 17px;
|
|
38
38
|
--font-size-body-strong: 20px;
|
|
@@ -49,13 +49,13 @@ Accent usage guidance:
|
|
|
49
49
|
|
|
50
50
|
### Typography
|
|
51
51
|
|
|
52
|
-
- **Display / heading font**: `
|
|
53
|
-
- **Body font**: `
|
|
52
|
+
- **Display / heading font**: `Montserrat` — used for all headings (`h1`–`h4`), eyebrows, and display text across every layout
|
|
53
|
+
- **Body font**: `Montserrat` — used for body copy, labels, captions, and UI text
|
|
54
54
|
- Font link tag:
|
|
55
55
|
```html
|
|
56
56
|
<link rel="preconnect" href="https://fonts.googleapis.com">
|
|
57
57
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
|
58
|
-
<link href="https://fonts.googleapis.com/css2?family=
|
|
58
|
+
<link href="https://fonts.googleapis.com/css2?family=Montserrat:wght@300;400;500;600;700;800&display=swap" rel="stylesheet">
|
|
59
59
|
```
|
|
60
60
|
- cover h1: `108px` to `124px`, weight `600` to `700`, line-height `0.88` to `0.94`, Title Case
|
|
61
61
|
- inner-layout h2: `30px` to `36px`, weight `600` to `700`, line-height `1.06` to `1.12`
|
|
@@ -127,7 +127,7 @@ Every generated presentation must use this exact HTML skeleton:
|
|
|
127
127
|
<title>{Presentation Title}</title>
|
|
128
128
|
<link rel="preconnect" href="https://fonts.googleapis.com">
|
|
129
129
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
|
130
|
-
<link href="https://fonts.googleapis.com/css2?family=
|
|
130
|
+
<link href="https://fonts.googleapis.com/css2?family=Montserrat:wght@300;400;500;600;700;800&display=swap" rel="stylesheet">
|
|
131
131
|
<!-- <script src="https://cdn.jsdelivr.net/npm/echarts@5/dist/echarts.min.js"></script> only if charts are needed -->
|
|
132
132
|
<style>/* all CSS here */</style>
|
|
133
133
|
</head>
|
|
@@ -220,7 +220,7 @@ body {
|
|
|
220
220
|
|
|
221
221
|
h1, h2, h3, h4 {
|
|
222
222
|
font-family: var(--font-display);
|
|
223
|
-
font-weight:
|
|
223
|
+
font-weight: 500;
|
|
224
224
|
letter-spacing: -0.02em;
|
|
225
225
|
color: var(--text-primary);
|
|
226
226
|
}
|
|
@@ -2012,53 +2012,46 @@ Rules:
|
|
|
2012
2012
|
<!-- @component:toc:start -->
|
|
2013
2013
|
#### TOC Panel
|
|
2014
2014
|
|
|
2015
|
-
|
|
2015
|
+
Minimal table-of-contents slide with a quiet title block on the left and a spacious numbered section list on the right. Use this for agenda, section map, or transition overview slides.
|
|
2016
2016
|
|
|
2017
2017
|
```html
|
|
2018
2018
|
<div class="toc-panel">
|
|
2019
|
-
<div
|
|
2020
|
-
|
|
2021
|
-
|
|
2022
|
-
<
|
|
2023
|
-
<p
|
|
2024
|
-
<ol style="list-style:none;display:flex;flex-direction:column;gap:7px;margin-top:20px;">
|
|
2025
|
-
<li style="display:grid;grid-template-columns:24px 1fr;gap:10px;align-items:center;font-size:14px;line-height:1.35;letter-spacing:0.01em;border-bottom:1px solid var(--line);padding-bottom:6px;"><span style="font-weight:700;">01</span><span>Chapter Title or Section Theme</span></li>
|
|
2026
|
-
<li style="display:grid;grid-template-columns:24px 1fr;gap:10px;align-items:center;font-size:14px;line-height:1.35;letter-spacing:0.01em;border-bottom:1px solid var(--line);padding-bottom:6px;"><span style="font-weight:700;">02</span><span>Chapter Title or Section Theme</span></li>
|
|
2027
|
-
<li style="display:grid;grid-template-columns:24px 1fr;gap:10px;align-items:center;font-size:14px;line-height:1.35;letter-spacing:0.01em;border-bottom:1px solid var(--line);padding-bottom:6px;"><span style="font-weight:700;">03</span><span>Chapter Title or Section Theme</span></li>
|
|
2028
|
-
<li style="display:grid;grid-template-columns:24px 1fr;gap:10px;align-items:center;font-size:14px;line-height:1.35;letter-spacing:0.01em;border-bottom:1px solid var(--line);padding-bottom:6px;"><span style="font-weight:700;">04</span><span>Chapter Title or Section Theme</span></li>
|
|
2029
|
-
<li style="display:grid;grid-template-columns:24px 1fr;gap:10px;align-items:center;font-size:14px;line-height:1.35;letter-spacing:0.01em;border-bottom:1px solid var(--line);padding-bottom:6px;"><span style="font-weight:700;">05</span><span>Chapter Title or Section Theme</span></li>
|
|
2030
|
-
<li style="display:grid;grid-template-columns:24px 1fr;gap:10px;align-items:center;font-size:14px;line-height:1.35;letter-spacing:0.01em;"><span style="font-weight:700;">06</span><span>Chapter Title or Section Theme</span></li>
|
|
2031
|
-
</ol>
|
|
2032
|
-
</div>
|
|
2033
|
-
<div style="display:flex;flex-direction:column;gap:14px;">
|
|
2034
|
-
<div class="rule"></div>
|
|
2035
|
-
<div>
|
|
2036
|
-
<p class="caption">Scope of report</p>
|
|
2037
|
-
<p style="margin-top:10px;color:var(--text-secondary);max-width:255px;">Optional scope note, data coverage period, or brief methodology reference.</p>
|
|
2038
|
-
</div>
|
|
2039
|
-
<div style="display:flex;justify-content:space-between;align-items:end;">
|
|
2040
|
-
<p class="caption">Organisation · Year</p>
|
|
2041
|
-
</div>
|
|
2019
|
+
<div class="toc-panel-inner">
|
|
2020
|
+
<div class="toc-header">
|
|
2021
|
+
<h2>Table of<br>Contents</h2>
|
|
2022
|
+
<p class="toc-note">Brief context note describing the scope of the sections that follow.</p>
|
|
2023
|
+
<p class="toc-footer">Creative-Curious-Cooperation</p>
|
|
2042
2024
|
</div>
|
|
2025
|
+
<ol class="toc-list">
|
|
2026
|
+
<li class="toc-item"><span>01</span><strong>The vision of a changing world</strong></li>
|
|
2027
|
+
<li class="toc-item"><span>02</span><strong>Smart home solutions</strong></li>
|
|
2028
|
+
<li class="toc-item"><span>03</span><strong>Smart city innovations</strong></li>
|
|
2029
|
+
<li class="toc-item"><span>04</span><strong>Smart office revolution</strong></li>
|
|
2030
|
+
<li class="toc-item"><span>05</span><strong>Wearable technology</strong></li>
|
|
2031
|
+
<li class="toc-item"><span>06</span><strong>The future of connected work</strong></li>
|
|
2032
|
+
</ol>
|
|
2043
2033
|
</div>
|
|
2044
2034
|
</div>
|
|
2045
2035
|
```
|
|
2046
2036
|
|
|
2047
2037
|
```css
|
|
2048
|
-
.toc-panel {
|
|
2049
|
-
|
|
2050
|
-
|
|
2051
|
-
|
|
2052
|
-
|
|
2053
|
-
}
|
|
2038
|
+
.toc-panel { height: 100%; padding: 86px 118px 58px; display: flex; overflow: hidden; background: var(--bg-page); }
|
|
2039
|
+
.toc-panel-inner { width: 100%; display: grid; grid-template-columns: 37% 1fr; align-items: stretch; gap: 76px; }
|
|
2040
|
+
.toc-header { display: flex; flex-direction: column; min-height: 100%; }
|
|
2041
|
+
.toc-header h2 { margin-top: 32px; max-width: 360px; font-size: 46px; line-height: 1.04; letter-spacing: 0.02em; text-transform: uppercase; font-weight: 500; }
|
|
2042
|
+
.toc-note { margin-top: 230px; margin-bottom: 0; max-width: 300px; font-size: 14px; line-height: 1.7; letter-spacing: 0.02em; color: var(--text-secondary); opacity: 0.58; }
|
|
2043
|
+
.toc-footer { margin-top: auto; font-size: 11px; line-height: 1.4; letter-spacing: 0.08em; text-transform: uppercase; font-weight: 500; color: var(--text-primary); }
|
|
2044
|
+
.toc-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; justify-content: center; gap: 42px; height: 100%; }
|
|
2045
|
+
.toc-item { display: grid; grid-template-columns: 80px 1fr; gap: 44px; align-items: center; }
|
|
2046
|
+
.toc-item span { font-style: normal; font-family: var(--font-display); font-size: 42px; line-height: 1; letter-spacing: 0.03em; color: var(--text-primary); font-variant-numeric: tabular-nums; }
|
|
2047
|
+
.toc-item strong { font-size: 17px; line-height: 1.35; letter-spacing: 0.12em; text-transform: uppercase; font-weight: 500; color: var(--text-primary); }
|
|
2054
2048
|
```
|
|
2055
2049
|
|
|
2056
2050
|
##### Tips
|
|
2057
|
-
- **
|
|
2058
|
-
- **Keep
|
|
2059
|
-
- **
|
|
2060
|
-
- **
|
|
2061
|
-
- **`justify-content:space-between` requires a defined height on the parent.** The panel must sit inside a container with a known height (grid cell, absolute position, or `height:100%` chain) or the footer will not pin to the bottom.
|
|
2051
|
+
- **Use generous empty space.** This TOC is intentionally quiet: avoid boxes, rules, icons, decorative images, or dense explanatory copy.
|
|
2052
|
+
- **Keep section titles short.** Six items fit best when titles stay under one line; two-line titles are acceptable but should not dominate the numbered rhythm.
|
|
2053
|
+
- **No page-number column.** The visible structure is section number plus title only. Do not add trailing page numbers or border dividers unless the user explicitly asks for them.
|
|
2054
|
+
- **Left footer stays small.** The footer should read like a restrained production note, not a secondary headline.
|
|
2062
2055
|
<!-- @component:toc:end -->
|
|
2063
2056
|
|
|
2064
2057
|
<!-- @component:quote:start -->
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
<title>Summit — Climate Report 2026</title>
|
|
7
7
|
<link rel="preconnect" href="https://fonts.googleapis.com">
|
|
8
8
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
|
9
|
-
<link href="https://fonts.googleapis.com/css2?family=
|
|
9
|
+
<link href="https://fonts.googleapis.com/css2?family=Montserrat:wght@300;400;500;600;700;800&display=swap" rel="stylesheet">
|
|
10
10
|
<script src="https://cdn.jsdelivr.net/npm/echarts@5/dist/echarts.min.js"></script>
|
|
11
11
|
<style>
|
|
12
12
|
:root {
|
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
body {
|
|
38
38
|
background: var(--bg-frame);
|
|
39
39
|
color: var(--text-primary);
|
|
40
|
-
font-family: '
|
|
40
|
+
font-family: 'Montserrat', ui-sans-serif, sans-serif;
|
|
41
41
|
-webkit-font-smoothing: antialiased;
|
|
42
42
|
height: 100%;
|
|
43
43
|
}
|
|
@@ -89,8 +89,8 @@
|
|
|
89
89
|
}
|
|
90
90
|
|
|
91
91
|
h1, h2, h3, h4 {
|
|
92
|
-
font-family: '
|
|
93
|
-
font-weight:
|
|
92
|
+
font-family: 'Montserrat', ui-sans-serif, sans-serif;
|
|
93
|
+
font-weight: 500;
|
|
94
94
|
letter-spacing: -0.02em;
|
|
95
95
|
color: var(--text-primary);
|
|
96
96
|
}
|
|
@@ -115,6 +115,17 @@
|
|
|
115
115
|
background: var(--line-strong);
|
|
116
116
|
}
|
|
117
117
|
|
|
118
|
+
.toc-panel { height: 100%; padding: 96px 150px 76px; display: flex; overflow: hidden; background: var(--bg-page); }
|
|
119
|
+
.toc-panel-inner { width: 100%; display: grid; grid-template-columns: 34% 1fr; align-items: stretch; gap: 104px; }
|
|
120
|
+
.toc-header { display: flex; flex-direction: column; min-height: 100%; }
|
|
121
|
+
.toc-header h2 { margin-top: 32px; max-width: 360px; font-size: 46px; line-height: 1.04; letter-spacing: 0.02em; text-transform: uppercase; font-weight: 500; }
|
|
122
|
+
.toc-note { margin-top: 230px; margin-bottom: 0; max-width: 300px; font-size: 14px; line-height: 1.7; letter-spacing: 0.02em; color: var(--text-secondary); opacity: 0.58; }
|
|
123
|
+
.toc-footer { margin-top: auto; font-size: 11px; line-height: 1.4; letter-spacing: 0.08em; text-transform: uppercase; font-weight: 500; color: var(--text-primary); }
|
|
124
|
+
.toc-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; justify-content: center; gap: 42px; height: 100%; }
|
|
125
|
+
.toc-item { display: grid; grid-template-columns: 80px 1fr; gap: 44px; align-items: center; }
|
|
126
|
+
.toc-item span { font-style: normal; font-family: 'Montserrat', ui-sans-serif, sans-serif; font-size: 42px; line-height: 1; letter-spacing: 0.03em; color: var(--text-primary); font-variant-numeric: tabular-nums; }
|
|
127
|
+
.toc-item strong { font-size: 17px; line-height: 1.35; letter-spacing: 0.12em; text-transform: uppercase; font-weight: 500; color: var(--text-primary); }
|
|
128
|
+
|
|
118
129
|
.chevron-divider {
|
|
119
130
|
display: inline-flex;
|
|
120
131
|
align-items: center;
|
|
@@ -471,7 +482,7 @@
|
|
|
471
482
|
}
|
|
472
483
|
|
|
473
484
|
.flow-horizontal .flow-number {
|
|
474
|
-
font-family: '
|
|
485
|
+
font-family: 'Montserrat', ui-sans-serif, sans-serif;
|
|
475
486
|
font-size: 13px;
|
|
476
487
|
font-weight: 700;
|
|
477
488
|
letter-spacing: 0.12em;
|
|
@@ -518,7 +529,7 @@
|
|
|
518
529
|
}
|
|
519
530
|
|
|
520
531
|
.flow-vertical .flow-number {
|
|
521
|
-
font-family: '
|
|
532
|
+
font-family: 'Montserrat', ui-sans-serif, sans-serif;
|
|
522
533
|
font-size: 13px;
|
|
523
534
|
font-weight: 700;
|
|
524
535
|
letter-spacing: 0.12em;
|
|
@@ -570,7 +581,7 @@
|
|
|
570
581
|
.data-table {
|
|
571
582
|
width: 100%;
|
|
572
583
|
border-collapse: collapse;
|
|
573
|
-
font-family: '
|
|
584
|
+
font-family: 'Montserrat', ui-sans-serif, sans-serif;
|
|
574
585
|
font-size: 13px;
|
|
575
586
|
font-variant-numeric: tabular-nums;
|
|
576
587
|
color: var(--text-primary);
|
|
@@ -659,7 +670,7 @@
|
|
|
659
670
|
.dense-table {
|
|
660
671
|
width: 100%;
|
|
661
672
|
border-collapse: collapse;
|
|
662
|
-
font-family: '
|
|
673
|
+
font-family: 'Montserrat', ui-sans-serif, sans-serif;
|
|
663
674
|
font-size: 11px;
|
|
664
675
|
font-variant-numeric: tabular-nums;
|
|
665
676
|
color: var(--text-secondary);
|
|
@@ -933,7 +944,7 @@
|
|
|
933
944
|
position: absolute;
|
|
934
945
|
bottom: 36px;
|
|
935
946
|
right: 52px;
|
|
936
|
-
font-family: '
|
|
947
|
+
font-family: 'Montserrat', ui-sans-serif, sans-serif;
|
|
937
948
|
font-size: 11px;
|
|
938
949
|
font-weight: 700;
|
|
939
950
|
letter-spacing: 0.18em;
|
|
@@ -1069,42 +1080,31 @@
|
|
|
1069
1080
|
═══════════════════════════════════════════════════════════ -->
|
|
1070
1081
|
<section class="slide" slide-qa="false" data-index="1">
|
|
1071
1082
|
<div class="slide-canvas">
|
|
1072
|
-
<div class="page reveal" style="padding:0;overflow:hidden;">
|
|
1073
|
-
<div style="
|
|
1074
|
-
<div class="
|
|
1075
|
-
<
|
|
1076
|
-
<img src="https://images.unsplash.com/photo-1522163182402-834f871fd851?q=80&w=1800&auto=format&fit=crop" alt="Climbers resting on a steep alpine wall at sunrise">
|
|
1077
|
-
</div>
|
|
1083
|
+
<div class="page reveal" style="padding:0;overflow:hidden;background:var(--bg-frame);">
|
|
1084
|
+
<div class="hero-field" style="position:absolute;inset:0;z-index:0;">
|
|
1085
|
+
<div class="full-bleed-media" style="height:100%;">
|
|
1086
|
+
<img src="https://images.unsplash.com/photo-1447752875215-b2761acb3c5d?q=80&w=1800&auto=format&fit=crop" alt="Aerial view of dense taiga forest canopy">
|
|
1078
1087
|
</div>
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
<li style="display:grid;grid-template-columns:26px 1fr;gap:12px;font-size:11px;line-height:1.45;text-transform:uppercase;letter-spacing:0.06em;border-bottom:1px solid var(--line);padding-bottom:8px;"><span style="font-weight:700;">02</span><span>Material Transition & Circular Design</span></li>
|
|
1088
|
-
<li style="display:grid;grid-template-columns:26px 1fr;gap:12px;font-size:11px;line-height:1.45;text-transform:uppercase;letter-spacing:0.06em;border-bottom:1px solid var(--line);padding-bottom:8px;"><span style="font-weight:700;">03</span><span>Field Programme Action Highlights</span></li>
|
|
1089
|
-
<li style="display:grid;grid-template-columns:26px 1fr;gap:12px;font-size:11px;line-height:1.45;text-transform:uppercase;letter-spacing:0.06em;border-bottom:1px solid var(--line);padding-bottom:8px;"><span style="font-weight:700;">04</span><span>Carbon Emissions — Scope 1, 2 & 3</span></li>
|
|
1090
|
-
<li style="display:grid;grid-template-columns:26px 1fr;gap:12px;font-size:11px;line-height:1.45;text-transform:uppercase;letter-spacing:0.06em;border-bottom:1px solid var(--line);padding-bottom:8px;"><span style="font-weight:700;">05</span><span>Decarbonisation Roadmap 2026–2030</span></li>
|
|
1091
|
-
<li style="display:grid;grid-template-columns:26px 1fr;gap:12px;font-size:11px;line-height:1.45;text-transform:uppercase;letter-spacing:0.06em;"><span style="font-weight:700;">06</span><span>Emissions Data & Assurance Tables</span></li>
|
|
1092
|
-
</ol>
|
|
1093
|
-
</div>
|
|
1094
|
-
<div style="display:flex;flex-direction:column;gap:14px;">
|
|
1095
|
-
<div class="rule"></div>
|
|
1096
|
-
<div>
|
|
1097
|
-
<p class="caption">Scope of report</p>
|
|
1098
|
-
<p style="margin-top:10px;font-size:11px;line-height:1.6;color:var(--text-secondary);max-width:255px;">Data covers fiscal year 2026 (Jan–Dec). Scope 3 figures are independently verified by Bureau Veritas.</p>
|
|
1099
|
-
</div>
|
|
1100
|
-
<div style="display:flex;justify-content:space-between;align-items:end;">
|
|
1101
|
-
<p class="caption">Summit Outdoor Co. · 2026</p>
|
|
1102
|
-
</div>
|
|
1103
|
-
</div>
|
|
1088
|
+
</div>
|
|
1089
|
+
<div style="position:absolute;inset:0;z-index:1;background:linear-gradient(90deg,rgba(5,5,5,0.88) 0%,rgba(5,5,5,0.76) 44%,rgba(5,5,5,0.56) 72%,rgba(5,5,5,0.36) 100%);"></div>
|
|
1090
|
+
<div class="toc-panel" style="position:relative;z-index:2;background:transparent;--text-primary:#f7f4ee;--text-secondary:rgba(247,244,238,0.72);--text-muted:rgba(247,244,238,0.50);">
|
|
1091
|
+
<div class="toc-panel-inner">
|
|
1092
|
+
<div class="toc-header reveal">
|
|
1093
|
+
<h2>Table of<br>Contents</h2>
|
|
1094
|
+
<p class="toc-note">Six sections mapping our progress against the commitments made in our 2022 baseline report.</p>
|
|
1095
|
+
<p class="toc-footer">Summit Outdoor Co. 2026</p>
|
|
1104
1096
|
</div>
|
|
1097
|
+
<ol class="toc-list reveal">
|
|
1098
|
+
<li class="toc-item"><span>01</span><strong>Climate commitments and 2030 targets</strong></li>
|
|
1099
|
+
<li class="toc-item"><span>02</span><strong>Material transition and circular design</strong></li>
|
|
1100
|
+
<li class="toc-item"><span>03</span><strong>Field programme action highlights</strong></li>
|
|
1101
|
+
<li class="toc-item"><span>04</span><strong>Carbon emissions scope one two and three</strong></li>
|
|
1102
|
+
<li class="toc-item"><span>05</span><strong>Decarbonisation roadmap 2026 to 2030</strong></li>
|
|
1103
|
+
<li class="toc-item"><span>06</span><strong>Emissions data and assurance tables</strong></li>
|
|
1104
|
+
</ol>
|
|
1105
1105
|
</div>
|
|
1106
1106
|
</div>
|
|
1107
|
-
<div class="page-number">01 / 11</div>
|
|
1107
|
+
<div class="page-number page-number--light">01 / 11</div>
|
|
1108
1108
|
</div>
|
|
1109
1109
|
</div>
|
|
1110
1110
|
</section>
|
|
@@ -2072,7 +2072,7 @@
|
|
|
2072
2072
|
grid: { top: 20, right: 40, bottom: 36, left: 60 },
|
|
2073
2073
|
legend: {
|
|
2074
2074
|
bottom: 0,
|
|
2075
|
-
textStyle: { fontSize: 12, color: '#8a7f73', fontFamily: '
|
|
2075
|
+
textStyle: { fontSize: 12, color: '#8a7f73', fontFamily: 'Montserrat, sans-serif' },
|
|
2076
2076
|
itemWidth: 14,
|
|
2077
2077
|
itemHeight: 8,
|
|
2078
2078
|
},
|
|
@@ -2080,7 +2080,7 @@
|
|
|
2080
2080
|
trigger: 'axis',
|
|
2081
2081
|
backgroundColor: '#2c2828',
|
|
2082
2082
|
borderColor: 'rgba(243,238,230,0.12)',
|
|
2083
|
-
textStyle: { color: '#f3eee6', fontSize: 12, fontFamily: '
|
|
2083
|
+
textStyle: { color: '#f3eee6', fontSize: 12, fontFamily: 'Montserrat, sans-serif' },
|
|
2084
2084
|
formatter: (params) => {
|
|
2085
2085
|
let out = `<div style="font-size:11px;letter-spacing:0.1em;text-transform:uppercase;color:rgba(243,238,230,0.6);margin-bottom:6px;">${params[0].name}</div>`;
|
|
2086
2086
|
params.forEach(p => {
|
|
@@ -2094,15 +2094,15 @@
|
|
|
2094
2094
|
data: ['2022', '2023', '2024', '2025', '2026'],
|
|
2095
2095
|
axisLine: { lineStyle: { color: 'rgba(23,20,17,0.14)' } },
|
|
2096
2096
|
axisTick: { show: false },
|
|
2097
|
-
axisLabel: { color: '#8a7f73', fontSize: 12, fontFamily: '
|
|
2097
|
+
axisLabel: { color: '#8a7f73', fontSize: 12, fontFamily: 'Montserrat, sans-serif', margin: 10 },
|
|
2098
2098
|
},
|
|
2099
2099
|
yAxis: {
|
|
2100
2100
|
type: 'value',
|
|
2101
2101
|
name: 'kt CO₂e',
|
|
2102
|
-
nameTextStyle: { color: '#8a7f73', fontSize: 11, fontFamily: '
|
|
2102
|
+
nameTextStyle: { color: '#8a7f73', fontSize: 11, fontFamily: 'Montserrat, sans-serif' },
|
|
2103
2103
|
axisLine: { show: false },
|
|
2104
2104
|
axisTick: { show: false },
|
|
2105
|
-
axisLabel: { color: '#8a7f73', fontSize: 12, fontFamily: '
|
|
2105
|
+
axisLabel: { color: '#8a7f73', fontSize: 12, fontFamily: 'Montserrat, sans-serif' },
|
|
2106
2106
|
splitLine: { lineStyle: { color: 'rgba(23,20,17,0.1)', type: 'dashed' } },
|
|
2107
2107
|
},
|
|
2108
2108
|
series: [
|
|
@@ -2187,7 +2187,7 @@
|
|
|
2187
2187
|
axisPointer: { type: 'cross' },
|
|
2188
2188
|
backgroundColor: '#2c2828',
|
|
2189
2189
|
borderColor: 'rgba(243,238,230,0.12)',
|
|
2190
|
-
textStyle: { color: '#f3eee6', fontSize: 11, fontFamily: '
|
|
2190
|
+
textStyle: { color: '#f3eee6', fontSize: 11, fontFamily: 'Montserrat, sans-serif' },
|
|
2191
2191
|
formatter: (params) => {
|
|
2192
2192
|
const p = params[0];
|
|
2193
2193
|
return `<div style="font-size:10px;letter-spacing:0.1em;text-transform:uppercase;color:rgba(243,238,230,0.55);margin-bottom:6px;">${p.name}</div>` +
|
|
@@ -2202,7 +2202,7 @@
|
|
|
2202
2202
|
axisLine: { lineStyle: { color: 'var(--line-strong)' } },
|
|
2203
2203
|
axisTick: { show: false },
|
|
2204
2204
|
axisLabel: {
|
|
2205
|
-
fontFamily: '
|
|
2205
|
+
fontFamily: 'Montserrat, sans-serif',
|
|
2206
2206
|
fontSize: 10,
|
|
2207
2207
|
color: '#8a7f73',
|
|
2208
2208
|
interval: 5,
|
|
@@ -2216,7 +2216,7 @@
|
|
|
2216
2216
|
axisLine: { show: false },
|
|
2217
2217
|
axisTick: { show: false },
|
|
2218
2218
|
axisLabel: {
|
|
2219
|
-
fontFamily: '
|
|
2219
|
+
fontFamily: 'Montserrat, sans-serif',
|
|
2220
2220
|
fontSize: 10,
|
|
2221
2221
|
color: '#8a7f73',
|
|
2222
2222
|
formatter: (v) => '$' + v,
|
package/lib/commands/brief.ts
CHANGED
|
@@ -12,7 +12,7 @@ export type ParseBriefArgsResult = { ok: true; args: BriefArgs } | { ok: false;
|
|
|
12
12
|
export function parseBriefArgs(input: string): ParseBriefArgsResult {
|
|
13
13
|
const value = input.trim()
|
|
14
14
|
if (!value) return { ok: true, args: {} }
|
|
15
|
-
if (value.startsWith("--")) return { ok: false, error: "Usage: `/revela brief [workspace-relative-output.md]`" }
|
|
15
|
+
if (value.startsWith("--")) return { ok: false, error: "Usage: `/revela make --brief [workspace-relative-output.md]`" }
|
|
16
16
|
if (!value.endsWith(".md")) return { ok: false, error: "Executive brief output must be a Markdown file ending in `.md`." }
|
|
17
17
|
if (isAbsolute(value) || value.split(/[\\/]+/).includes("..")) return { ok: false, error: "Executive brief output must be a safe workspace-relative path." }
|
|
18
18
|
return { ok: true, args: { outputPath: normalize(value).replace(/\\/g, "/") } }
|
|
@@ -12,12 +12,12 @@ export type DesignsEditParseResult =
|
|
|
12
12
|
| { ok: false; error: string }
|
|
13
13
|
|
|
14
14
|
const USAGE =
|
|
15
|
-
"**Usage:** `/revela
|
|
16
|
-
"Example: `/revela
|
|
15
|
+
"**Usage:** `/revela design --new <kebab-case-name> [--base starter]`\n" +
|
|
16
|
+
"Example: `/revela design --new neon-finance --base starter`"
|
|
17
17
|
|
|
18
18
|
const EDIT_USAGE =
|
|
19
|
-
"**Usage:** `/revela
|
|
20
|
-
"Example: `/revela
|
|
19
|
+
"**Usage:** `/revela design --edit <kebab-case-name>`\n" +
|
|
20
|
+
"Example: `/revela design --edit neon-finance`"
|
|
21
21
|
|
|
22
22
|
function isValidDesignName(name: string): boolean {
|
|
23
23
|
return /^[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$/.test(name)
|
|
@@ -126,7 +126,7 @@ Workflow:
|
|
|
126
126
|
8. Self-review the preview against the visual schema before saving.
|
|
127
127
|
9. Save the package with \`revela-designs-author\` using action \`create\`.
|
|
128
128
|
10. Validate it with \`revela-designs-author\` using action \`validate\`.
|
|
129
|
-
11. Report the saved path and activation command: \`/revela
|
|
129
|
+
11. Report the saved path and activation command: \`/revela design --use ${name}\`.
|
|
130
130
|
|
|
131
131
|
Hard requirements:
|
|
132
132
|
- \`DESIGN.md\` must include frontmatter with name, description, author, and version.
|
|
@@ -166,7 +166,7 @@ Workflow:
|
|
|
166
166
|
7. Self-review the preview for text overlap, scale drift, lost anchoring, overflow, and whether the requested change is visible.
|
|
167
167
|
8. Save with \`revela-designs-author\` using action \`create\`, name \`${name}\`, and overwrite=true.
|
|
168
168
|
9. Validate with \`revela-designs-author\` using action \`validate\`.
|
|
169
|
-
10. Report the saved path and activation command: \`/revela
|
|
169
|
+
10. Report the saved path and activation command: \`/revela design --use ${name}\`.
|
|
170
170
|
|
|
171
171
|
Hard requirements:
|
|
172
172
|
- Preserve valid frontmatter and marker structure.
|
package/lib/commands/designs.ts
CHANGED
|
@@ -2,10 +2,10 @@
|
|
|
2
2
|
* lib/commands/designs.ts
|
|
3
3
|
*
|
|
4
4
|
* Handlers for design-related sub-commands:
|
|
5
|
-
* /revela
|
|
6
|
-
* /revela
|
|
7
|
-
* /revela
|
|
8
|
-
* /revela
|
|
5
|
+
* /revela design — list installed designs
|
|
6
|
+
* /revela design --use <name> — activate a design
|
|
7
|
+
* /revela design --add <url> — install a design from URL / github:user/repo / local path
|
|
8
|
+
* /revela design --rm <name> — remove an installed design
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
11
|
import { listDesigns, activeDesign, activateDesign, installDesign, removeDesign } from "../design/designs"
|
|
@@ -17,7 +17,7 @@ export async function handleDesignsList(
|
|
|
17
17
|
const designs = listDesigns()
|
|
18
18
|
const current = activeDesign()
|
|
19
19
|
if (!designs.length) {
|
|
20
|
-
await send(`No designs installed. Use \`/revela
|
|
20
|
+
await send(`No designs installed. Use \`/revela design --add <url>\` to install one.`)
|
|
21
21
|
return
|
|
22
22
|
}
|
|
23
23
|
const lines = designs.map((d) => {
|
|
@@ -36,7 +36,7 @@ export async function handleDesignsActivate(
|
|
|
36
36
|
try {
|
|
37
37
|
activateDesign(name)
|
|
38
38
|
buildPrompt({ mode: "narrative" })
|
|
39
|
-
await send(`**Design activated:** \`${name}\`\nNarrative prompt rebuilt. The design will apply when \`/revela make deck\` enters deck-render mode.`)
|
|
39
|
+
await send(`**Design activated:** \`${name}\`\nNarrative prompt rebuilt. The design will apply when \`/revela make --deck\` enters deck-render mode.`)
|
|
40
40
|
} catch (e: any) {
|
|
41
41
|
await send(`**Error:** ${e.message}`)
|
|
42
42
|
}
|
|
@@ -47,13 +47,13 @@ export async function handleDesignsAdd(
|
|
|
47
47
|
send: (text: string) => Promise<void>,
|
|
48
48
|
): Promise<void> {
|
|
49
49
|
if (!source) {
|
|
50
|
-
await send(`**Usage:** \`/revela
|
|
50
|
+
await send(`**Usage:** \`/revela design --add <url|github:user/repo|local-path>\``)
|
|
51
51
|
return
|
|
52
52
|
}
|
|
53
53
|
try {
|
|
54
54
|
await send(`Installing design from \`${source}\`…`)
|
|
55
55
|
const name = await installDesign(source)
|
|
56
|
-
await send(`**Design installed:** \`${name}\`\nUse \`/revela
|
|
56
|
+
await send(`**Design installed:** \`${name}\`\nUse \`/revela design --use ${name}\` to activate it.`)
|
|
57
57
|
} catch (e: any) {
|
|
58
58
|
await send(`**Install failed:** ${e.message}`)
|
|
59
59
|
}
|
|
@@ -64,7 +64,7 @@ export async function handleDesignsRemove(
|
|
|
64
64
|
send: (text: string) => Promise<void>,
|
|
65
65
|
): Promise<void> {
|
|
66
66
|
if (!name) {
|
|
67
|
-
await send(`**Usage:** \`/revela
|
|
67
|
+
await send(`**Usage:** \`/revela design --rm <name>\``)
|
|
68
68
|
return
|
|
69
69
|
}
|
|
70
70
|
try {
|
package/lib/commands/domains.ts
CHANGED
|
@@ -2,10 +2,10 @@
|
|
|
2
2
|
* lib/commands/domains.ts
|
|
3
3
|
*
|
|
4
4
|
* Handlers for domain-related sub-commands:
|
|
5
|
-
* /revela
|
|
6
|
-
* /revela
|
|
7
|
-
* /revela
|
|
8
|
-
* /revela
|
|
5
|
+
* /revela domain — list installed domains
|
|
6
|
+
* /revela domain --use <name> — activate a domain
|
|
7
|
+
* /revela domain --add <url> — install a domain from URL / github:user/repo / local path
|
|
8
|
+
* /revela domain --rm <name> — remove an installed domain
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
11
|
import { listDomains, activeDomain, activateDomain, installDomain, removeDomain } from "../domain/domains"
|
|
@@ -17,7 +17,7 @@ export async function handleDomainsList(
|
|
|
17
17
|
const domains = listDomains()
|
|
18
18
|
const current = activeDomain()
|
|
19
19
|
if (!domains.length) {
|
|
20
|
-
await send(`No domains installed. Use \`/revela
|
|
20
|
+
await send(`No domains installed. Use \`/revela domain --add <url>\` to install one.`)
|
|
21
21
|
return
|
|
22
22
|
}
|
|
23
23
|
const lines = domains.map((d) => {
|
|
@@ -36,7 +36,7 @@ export async function handleDomainsActivate(
|
|
|
36
36
|
try {
|
|
37
37
|
activateDomain(name)
|
|
38
38
|
buildPrompt({ mode: "narrative" })
|
|
39
|
-
await send(`**Domain activated:** \`${name}\`\nNarrative prompt rebuilt. Domain reasoning applies now; deck-specific render guidance applies during \`/revela make deck\`.`)
|
|
39
|
+
await send(`**Domain activated:** \`${name}\`\nNarrative prompt rebuilt. Domain reasoning applies now; deck-specific render guidance applies during \`/revela make --deck\`.`)
|
|
40
40
|
} catch (e: any) {
|
|
41
41
|
await send(`**Error:** ${e.message}`)
|
|
42
42
|
}
|
|
@@ -47,13 +47,13 @@ export async function handleDomainsAdd(
|
|
|
47
47
|
send: (text: string) => Promise<void>,
|
|
48
48
|
): Promise<void> {
|
|
49
49
|
if (!source) {
|
|
50
|
-
await send(`**Usage:** \`/revela
|
|
50
|
+
await send(`**Usage:** \`/revela domain --add <url|github:user/repo|local-path>\``)
|
|
51
51
|
return
|
|
52
52
|
}
|
|
53
53
|
try {
|
|
54
54
|
await send(`Installing domain from \`${source}\`…`)
|
|
55
55
|
const name = await installDomain(source)
|
|
56
|
-
await send(`**Domain installed:** \`${name}\`\nUse \`/revela
|
|
56
|
+
await send(`**Domain installed:** \`${name}\`\nUse \`/revela domain --use ${name}\` to activate it.`)
|
|
57
57
|
} catch (e: any) {
|
|
58
58
|
await send(`**Install failed:** ${e.message}`)
|
|
59
59
|
}
|
|
@@ -64,7 +64,7 @@ export async function handleDomainsRemove(
|
|
|
64
64
|
send: (text: string) => Promise<void>,
|
|
65
65
|
): Promise<void> {
|
|
66
66
|
if (!name) {
|
|
67
|
-
await send(`**Usage:** \`/revela
|
|
67
|
+
await send(`**Usage:** \`/revela domain --rm <name>\``)
|
|
68
68
|
return
|
|
69
69
|
}
|
|
70
70
|
try {
|
package/lib/commands/edit.ts
CHANGED
|
@@ -3,5 +3,5 @@ export async function handleEdit(
|
|
|
3
3
|
send: (text: string) => Promise<void>,
|
|
4
4
|
): Promise<void> {
|
|
5
5
|
void options
|
|
6
|
-
await send("`/revela edit` has been removed. Use `/revela
|
|
6
|
+
await send("`/revela edit` has been removed. Use `/revela review --deck` and the Comment tab for the unified deck review workspace.")
|
|
7
7
|
}
|
package/lib/commands/help.ts
CHANGED
|
@@ -17,45 +17,42 @@ export async function handleHelp(
|
|
|
17
17
|
const status = ctx.enabled ? "enabled ✓" : "disabled"
|
|
18
18
|
await send(
|
|
19
19
|
`\`\`\`\n` +
|
|
20
|
-
` R E V E L A v${pkg.version}\n` +
|
|
20
|
+
` R E V E L A H e l p v${pkg.version}\n` +
|
|
21
21
|
`\`\`\`\n` +
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
22
|
+
`Turn source materials, research, and narrative state into trusted, traceable decision artifacts.\n\n` +
|
|
23
|
+
`**Current**\n\n` +
|
|
24
|
+
`Status: ${status}\n` +
|
|
25
|
+
`Design: \`${design}\`\n` +
|
|
26
|
+
`Domain: \`${domain}\`\n\n` +
|
|
27
|
+
`---\n\n` +
|
|
28
|
+
`**Workflow**\n\n` +
|
|
29
|
+
`1. \`init\` — discover workspace sources and capture intent\n` +
|
|
30
|
+
`2. \`research\` — close evidence gaps and bind support\n` +
|
|
31
|
+
`3. \`story\` — inspect audience, thesis, claims, evidence, risks, and approval\n` +
|
|
32
|
+
`4. \`make\` — generate deck or brief from approved story state\n` +
|
|
33
|
+
`5. \`review\` — comment on and inspect rendered deck artifacts\n` +
|
|
34
|
+
`6. \`export\` — export deck artifacts to PDF or PPTX\n\n` +
|
|
25
35
|
`---\n\n` +
|
|
26
36
|
`**Commands**\n\n` +
|
|
27
|
-
`\`/revela
|
|
28
|
-
`\`/revela
|
|
29
|
-
`\`/revela
|
|
30
|
-
`\`/revela
|
|
31
|
-
`\`/revela
|
|
32
|
-
`\`/revela
|
|
33
|
-
`\`/revela
|
|
34
|
-
`\`/revela
|
|
35
|
-
`\`/revela
|
|
36
|
-
`\`/revela
|
|
37
|
-
`\`/revela
|
|
38
|
-
`\`/revela
|
|
39
|
-
`\`/revela
|
|
40
|
-
`\`/revela
|
|
41
|
-
`\`/revela
|
|
42
|
-
`\`/revela design
|
|
43
|
-
`\`/revela
|
|
44
|
-
`\`/revela
|
|
45
|
-
`\`/revela
|
|
46
|
-
`\`/revela
|
|
47
|
-
`\`/revela designs\` — list installed designs\n` +
|
|
48
|
-
`\`/revela designs <name>\` — activate a design\n` +
|
|
49
|
-
`\`/revela designs-new <name>\` — create a new custom design with AI\n` +
|
|
50
|
-
`\`/revela designs-edit <name>\` — refine an existing custom design with AI\n` +
|
|
51
|
-
`\`/revela designs-preview [name]\` — open a design preview in browser\n` +
|
|
52
|
-
`\`/revela domains\` — list installed domains\n` +
|
|
53
|
-
`\`/revela domains <name>\` — activate a domain\n` +
|
|
54
|
-
`\`/revela designs-add <url>\` — install a design from URL / github:user/repo\n` +
|
|
55
|
-
`\`/revela domains-add <url>\` — install a domain from URL / github:user/repo\n` +
|
|
56
|
-
`\`/revela designs-rm <name>\` — remove an installed design\n` +
|
|
57
|
-
`\`/revela domains-rm <name>\` — remove an installed domain\n` +
|
|
58
|
-
`\`/revela pdf <file>\` — export HTML slide deck to PDF\n` +
|
|
59
|
-
`\`/revela pptx [file] [--notes]\` — export HTML slide deck to PPTX`
|
|
37
|
+
`\`/revela\` — show REVELA help\n` +
|
|
38
|
+
`\`/revela init\` — initialize or refresh workspace story state\n` +
|
|
39
|
+
`\`/revela research\` — research, bind evidence, and reduce story gaps\n` +
|
|
40
|
+
`\`/revela story [-l language]\` — open the read-only story workspace UI\n` +
|
|
41
|
+
`\`/revela make --deck\` — make a deck from approved story state\n` +
|
|
42
|
+
`\`/revela make --brief [file.md]\` — render executive brief from approved story\n` +
|
|
43
|
+
`\`/revela review --deck\` — open deck reading, insight, and comment workspace\n` +
|
|
44
|
+
`\`/revela export --deck pdf [file.html]\` — export HTML deck to PDF\n` +
|
|
45
|
+
`\`/revela export --deck pptx [file.html] [--notes]\` — export HTML deck to PPTX\n` +
|
|
46
|
+
`\`/revela design\` — list installed designs\n` +
|
|
47
|
+
`\`/revela design --use <name>\` — activate a design\n` +
|
|
48
|
+
`\`/revela design --preview [name]\` — open a design preview in browser\n` +
|
|
49
|
+
`\`/revela design --new <name>\` — create a custom design with AI\n` +
|
|
50
|
+
`\`/revela design --edit <name>\` — refine an existing custom design with AI\n` +
|
|
51
|
+
`\`/revela design --add <source>\` — install a design from URL / github:user/repo / local path\n` +
|
|
52
|
+
`\`/revela design --rm <name>\` — remove an installed design\n` +
|
|
53
|
+
`\`/revela domain\` — list installed domains\n` +
|
|
54
|
+
`\`/revela domain --use <name>\` — activate a domain\n` +
|
|
55
|
+
`\`/revela domain --add <source>\` — install a domain from URL / github:user/repo / local path\n` +
|
|
56
|
+
`\`/revela domain --rm <name>\` — remove an installed domain`
|
|
60
57
|
)
|
|
61
58
|
}
|
package/lib/commands/init.ts
CHANGED
|
@@ -17,7 +17,7 @@ Goal:
|
|
|
17
17
|
- Build or update ${DECKS_STATE_FILE}, the workspace-level machine-readable state file for Revela narrative and artifact work.
|
|
18
18
|
- Use the \`revela-decks\` tool for state updates. Do not write or patch ${DECKS_STATE_FILE} directly.
|
|
19
19
|
- Capture stable narrative context first: primary audience, belief before, belief after, decision/action, thesis, central claims, evidence availability, objections, risks, available source materials, existing artifact history, and open questions.
|
|
20
|
-
- Do not treat initialization as permission to write a deck. Narrative readiness is reviewed later by \`/revela story\`; deck/artifact readiness is
|
|
20
|
+
- Do not treat initialization as permission to write a deck. Narrative readiness is reviewed later by \`/revela story\`; deck/artifact readiness is handled by \`/revela make --deck\` after story approval and deck-plan confirmation.
|
|
21
21
|
- Do not require slide count, visual style, design selection, output path, layout choices, or component choices during narrative initialization unless the user explicitly asks to render a deck now.
|
|
22
22
|
- ${DECKS_STATE_FILE} is the compatibility workspace-state file. Deck specs are render-target projections, not the center of initialization.
|
|
23
23
|
|