@cyber-dash-tech/revela 0.1.11 → 0.1.12
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 +180 -91
- package/README.zh-CN.md +185 -128
- package/designs/summit/DESIGN.md +122 -55
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -2,32 +2,44 @@
|
|
|
2
2
|
|
|
3
3
|
**English** | [中文](README.zh-CN.md)
|
|
4
4
|
|
|
5
|
-
[](https://www.npmjs.com/package/@cyber-dash-tech/revela) [](LICENSE) [](https://www.npmjs.com/package/@cyber-dash-tech/revela) [](LICENSE) [](tests/) [](https://opencode.ai) [](https://bun.sh)
|
|
6
6
|
|
|
7
7
|
<p align="center">
|
|
8
8
|
<img src="assets/img/logo.png" alt="Revela" width="800" />
|
|
9
9
|
</p>
|
|
10
10
|
|
|
11
|
-
|
|
12
|
-
|
|
11
|
+
Revela is an [OpenCode](https://opencode.ai) plugin that turns your current agent into an HTML slide deck generator.
|
|
12
|
+
Enable it for a session, give the agent a presentation task, and it can research, structure, write, and QA a complete deck in `slides/*.html`.
|
|
13
13
|
|
|
14
|
+
**[Live Demo — The AI Power Shift](https://cyber-dash-tech.github.io/revela/assets/html/ai-power-shift.html)** · A 5-slide investment brief generated with Revela.
|
|
14
15
|
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
## What Revela Is
|
|
15
19
|
|
|
16
|
-
|
|
20
|
+
Revela is a mode, not a separate chat agent.
|
|
21
|
+
|
|
22
|
+
- `/revela enable` injects a presentation-specific system prompt into your current agent
|
|
23
|
+
- the prompt is built from 3 layers: core skill, active domain, active design
|
|
24
|
+
- the agent can scan workspace files, delegate web research, generate HTML slides, and run layout QA automatically
|
|
25
|
+
- design and domain switching happen locally and rebuild the active prompt immediately
|
|
17
26
|
|
|
18
27
|
---
|
|
19
28
|
|
|
20
29
|
## Requirements
|
|
21
30
|
|
|
22
|
-
- [OpenCode](https://opencode.ai)
|
|
23
|
-
-
|
|
24
|
-
-
|
|
31
|
+
- [OpenCode](https://opencode.ai)
|
|
32
|
+
- Bun runtime (`bun >= 1.0.0`)
|
|
33
|
+
- [Google Chrome](https://www.google.com/chrome/) or Chromium for layout QA and PDF export
|
|
34
|
+
- Git for source install
|
|
25
35
|
|
|
26
36
|
---
|
|
27
37
|
|
|
28
38
|
## Install
|
|
29
39
|
|
|
30
|
-
|
|
40
|
+
### Standard install
|
|
41
|
+
|
|
42
|
+
Add `@cyber-dash-tech/revela` to the `plugin` array in `opencode.json`:
|
|
31
43
|
|
|
32
44
|
```json
|
|
33
45
|
{
|
|
@@ -36,15 +48,24 @@ Add `@cyber-dash-tech/revela` to the `plugin` array in your `opencode.json`:
|
|
|
36
48
|
}
|
|
37
49
|
```
|
|
38
50
|
|
|
39
|
-
Restart OpenCode
|
|
51
|
+
Restart OpenCode. The plugin is installed automatically via Bun.
|
|
40
52
|
|
|
41
|
-
To install globally
|
|
53
|
+
To install globally, add the same `plugin` entry to `~/.config/opencode/opencode.json`.
|
|
42
54
|
|
|
43
|
-
###
|
|
55
|
+
### Local wrapper install
|
|
56
|
+
|
|
57
|
+
Use this when:
|
|
58
|
+
|
|
59
|
+
- Bun plugin install is blocked or unreliable
|
|
60
|
+
- you are on a mainland China network
|
|
61
|
+
- you want to run Revela from a local checkout
|
|
62
|
+
|
|
63
|
+
From source:
|
|
44
64
|
|
|
45
65
|
```bash
|
|
46
66
|
git clone https://github.com/cyber-dash-tech/revela
|
|
47
|
-
cd revela
|
|
67
|
+
cd revela
|
|
68
|
+
npm install
|
|
48
69
|
```
|
|
49
70
|
|
|
50
71
|
Create `~/.config/opencode/plugins/revela.js`:
|
|
@@ -53,24 +74,43 @@ Create `~/.config/opencode/plugins/revela.js`:
|
|
|
53
74
|
export { default } from "/absolute/path/to/revela/index.ts";
|
|
54
75
|
```
|
|
55
76
|
|
|
56
|
-
|
|
77
|
+
If you use the local wrapper route, make sure `~/.config/opencode/opencode.json` does not also contain a `plugin` entry for `@cyber-dash-tech/revela`, otherwise OpenCode will still try Bun-based installation.
|
|
78
|
+
|
|
79
|
+
### China mainland note
|
|
80
|
+
|
|
81
|
+
OpenCode's npm plugin installer uses Bun and may ignore npm mirror configuration. If direct installation fails, use the local wrapper method above or install the package with npm under `~/.config/opencode/` and create a local wrapper file.
|
|
57
82
|
|
|
58
83
|
---
|
|
59
84
|
|
|
60
85
|
## Quick Start
|
|
61
86
|
|
|
62
|
-
|
|
87
|
+
Start OpenCode:
|
|
88
|
+
|
|
63
89
|
```bash
|
|
64
|
-
|
|
90
|
+
opencode
|
|
65
91
|
```
|
|
66
92
|
|
|
67
|
-
Enable Revela in
|
|
68
|
-
|
|
93
|
+
Enable Revela in the current session:
|
|
94
|
+
|
|
95
|
+
```text
|
|
69
96
|
/revela enable
|
|
70
97
|
```
|
|
71
98
|
|
|
72
|
-
|
|
99
|
+
Then give the agent a slide task, for example:
|
|
100
|
+
|
|
101
|
+
```text
|
|
102
|
+
Create a 6-slide HTML deck on humanoid robotics supply chains. Use the summit design, cite the main market drivers, and save the result to slides/humanoid-robotics.html.
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
Export the resulting HTML deck to PDF if needed:
|
|
106
|
+
|
|
107
|
+
```text
|
|
108
|
+
/revela pdf slides/humanoid-robotics.html
|
|
73
109
|
```
|
|
110
|
+
|
|
111
|
+
Disable Revela and return the current agent to normal mode:
|
|
112
|
+
|
|
113
|
+
```text
|
|
74
114
|
/revela disable
|
|
75
115
|
```
|
|
76
116
|
|
|
@@ -78,86 +118,113 @@ To turn it off and restore the primary agent to normal:
|
|
|
78
118
|
|
|
79
119
|
## Commands
|
|
80
120
|
|
|
81
|
-
```
|
|
82
|
-
/revela show status
|
|
83
|
-
/revela enable
|
|
84
|
-
/revela disable
|
|
121
|
+
```text
|
|
122
|
+
/revela show status and help
|
|
123
|
+
/revela enable enable presentation mode for this session
|
|
124
|
+
/revela disable disable presentation mode
|
|
85
125
|
|
|
86
126
|
/revela designs list installed designs
|
|
87
|
-
/revela designs <name>
|
|
88
|
-
/revela designs-add <source> install a design from
|
|
127
|
+
/revela designs <name> activate a design
|
|
128
|
+
/revela designs-add <source> install a design from URL, local path, or github:user/repo
|
|
129
|
+
/revela designs-rm <name> remove an installed design
|
|
89
130
|
|
|
90
131
|
/revela domains list installed domains
|
|
91
|
-
/revela domains <name>
|
|
92
|
-
/revela domains-add <source> install a domain from
|
|
132
|
+
/revela domains <name> activate a domain
|
|
133
|
+
/revela domains-add <source> install a domain from URL, local path, or github:user/repo
|
|
134
|
+
/revela domains-rm <name> remove an installed domain
|
|
135
|
+
|
|
136
|
+
/revela pdf <file> export an HTML deck to PDF in the same directory
|
|
93
137
|
```
|
|
94
138
|
|
|
95
|
-
All commands execute locally
|
|
139
|
+
All `/revela` commands execute locally with zero LLM cost.
|
|
96
140
|
|
|
97
141
|
---
|
|
98
142
|
|
|
99
|
-
##
|
|
143
|
+
## How It Works
|
|
100
144
|
|
|
101
|
-
|
|
145
|
+
When Revela is enabled, it appends a generated prompt to the current agent's system prompt.
|
|
102
146
|
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
147
|
+
That prompt is built from 3 layers:
|
|
148
|
+
|
|
149
|
+
1. `skill/SKILL.md` — the core slide-generation workflow
|
|
150
|
+
2. active domain — domain-specific report structure and terminology
|
|
151
|
+
3. active design — visual language, layouts, components, and chart rules
|
|
152
|
+
|
|
153
|
+
The current design and domain are persisted in `~/.config/revela/config.json`. The session-level enabled/disabled state is not persisted.
|
|
107
154
|
|
|
108
155
|
---
|
|
109
156
|
|
|
110
|
-
##
|
|
157
|
+
## Research And File Ingestion
|
|
111
158
|
|
|
112
|
-
|
|
159
|
+
When Revela is enabled, the agent can use:
|
|
113
160
|
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
161
|
+
- `revela-workspace-scan` to discover PDFs, Office files, CSVs, Markdown, and text files in the workspace
|
|
162
|
+
- the `revela-research` subagent to fetch targeted web sources and save structured findings into `researches/<topic>/`
|
|
163
|
+
- `revela-research-save` to write one findings file per research axis
|
|
164
|
+
|
|
165
|
+
Supported file types for `@` reference and automatic text extraction:
|
|
166
|
+
|
|
167
|
+
- `.pdf`
|
|
168
|
+
- `.docx`
|
|
169
|
+
- `.pptx`
|
|
170
|
+
- `.xlsx`
|
|
119
171
|
|
|
120
|
-
|
|
172
|
+
Revela transparently extracts text from these binary files before the main agent reasons over them.
|
|
121
173
|
|
|
122
174
|
---
|
|
123
175
|
|
|
124
|
-
##
|
|
176
|
+
## Layout QA And Compliance
|
|
125
177
|
|
|
126
|
-
|
|
178
|
+
Every time the agent writes `slides/*.html`, Revela automatically runs a Puppeteer-based QA pass at `1920x1080`.
|
|
179
|
+
The QA report is fed back immediately so the agent can fix layout or compliance problems before moving on.
|
|
127
180
|
|
|
128
|
-
|
|
129
|
-
- **Run parallel research** via the `revela-research` subagent — fetches targeted URLs and saves structured findings to `researches/<topic>/`. The primary agent then synthesises these findings into slides.
|
|
181
|
+
Current QA dimensions:
|
|
130
182
|
|
|
131
|
-
|
|
183
|
+
| Dimension | What it checks |
|
|
184
|
+
|---|---|
|
|
185
|
+
| `overflow` | Elements extending outside the slide canvas |
|
|
186
|
+
| `balance` | Sparse slides, weak fill, centroid drift, and bottom-gap issues |
|
|
187
|
+
| `symmetry` | Side-by-side column imbalance in height or density |
|
|
188
|
+
| `rhythm` | Irregular vertical spacing between stacked siblings |
|
|
189
|
+
| `compliance` | Unknown design classes and novel CSS rules outside the active design vocabulary |
|
|
190
|
+
|
|
191
|
+
Slides must declare `slide-qa="true"` or `slide-qa="false"`.
|
|
192
|
+
|
|
193
|
+
- use `slide-qa="true"` for content-heavy slides that should undergo full layout QA
|
|
194
|
+
- use `slide-qa="false"` for structural slides such as cover, TOC, quote, summary, or closing pages
|
|
195
|
+
|
|
196
|
+
Compliance is part of the generation loop, not a soft suggestion. If the agent introduces classes or CSS rules that are not defined by the active design, QA flags them and the file should be corrected.
|
|
197
|
+
|
|
198
|
+
You can also run QA manually with the `revela-qa` tool.
|
|
132
199
|
|
|
133
200
|
---
|
|
134
201
|
|
|
135
|
-
##
|
|
202
|
+
## Built-in Designs
|
|
136
203
|
|
|
137
|
-
|
|
204
|
+
Switch designs with `/revela designs <name>`.
|
|
138
205
|
|
|
139
|
-
|
|
206
|
+
| Name | Description | Preview |
|
|
207
|
+
|---|---|---|
|
|
208
|
+
| `aurora` | Dark executive style with structured information density and ECharts-ready data visualization patterns |  |
|
|
209
|
+
| `summit` | Editorial annual-report style for image-rich narrative slides and restrained business storytelling |  |
|
|
140
210
|
|
|
141
|
-
|
|
142
|
-
|---|---|
|
|
143
|
-
| **Fill ratio** | Content must occupy enough of the canvas |
|
|
144
|
-
| **Bottom whitespace** | Flags large empty gaps at the slide bottom |
|
|
145
|
-
| **Overflow** | Elements that extend outside the canvas |
|
|
146
|
-
| **Asymmetry** | Side-by-side columns with large height differences |
|
|
147
|
-
| **Density imbalance** | Columns where CSS `align-items: stretch` hides content imbalance |
|
|
148
|
-
| **Sparse** | Slides with too few visible elements |
|
|
211
|
+
---
|
|
149
212
|
|
|
150
|
-
|
|
213
|
+
## Built-in Domains
|
|
151
214
|
|
|
152
|
-
|
|
215
|
+
Switch domains with `/revela domains <name>`.
|
|
153
216
|
|
|
154
|
-
|
|
217
|
+
| Name | Description |
|
|
218
|
+
|---|---|
|
|
219
|
+
| `general` | No domain specialization |
|
|
220
|
+
| `deeptech-investment` | VC and investment analysis: market sizing, technical readiness, moat, and investment thesis |
|
|
221
|
+
| `consulting` | Strategic consulting: go/no-go decisions, strategy design, and belief-change reporting |
|
|
155
222
|
|
|
156
223
|
---
|
|
157
224
|
|
|
158
225
|
## Custom Designs
|
|
159
226
|
|
|
160
|
-
A design is a folder
|
|
227
|
+
A custom design is a folder containing `DESIGN.md` with frontmatter metadata:
|
|
161
228
|
|
|
162
229
|
```yaml
|
|
163
230
|
---
|
|
@@ -168,49 +235,60 @@ version: 1.0.0
|
|
|
168
235
|
---
|
|
169
236
|
```
|
|
170
237
|
|
|
171
|
-
The body
|
|
238
|
+
The body defines the visual system used by the agent.
|
|
172
239
|
|
|
173
|
-
###
|
|
240
|
+
### Marker system
|
|
174
241
|
|
|
175
|
-
|
|
242
|
+
For larger designs, use the current marker format:
|
|
176
243
|
|
|
177
244
|
```html
|
|
178
|
-
<!-- @
|
|
179
|
-
|
|
180
|
-
<!-- @
|
|
245
|
+
<!-- @design:foundation:start -->
|
|
246
|
+
Colors, typography, CSS variables, HTML shell, base JS...
|
|
247
|
+
<!-- @design:foundation:end -->
|
|
248
|
+
|
|
249
|
+
<!-- @design:rules:start -->
|
|
250
|
+
Composition rules, do/don't guidance, design-specific constraints...
|
|
251
|
+
<!-- @design:rules:end -->
|
|
252
|
+
|
|
253
|
+
<!-- @design:layouts:start -->
|
|
254
|
+
<!-- @layout:cover:start qa=false -->
|
|
255
|
+
Layout details...
|
|
256
|
+
<!-- @layout:cover:end -->
|
|
181
257
|
|
|
182
|
-
<!-- @
|
|
183
|
-
Layout
|
|
184
|
-
<!-- @
|
|
258
|
+
<!-- @layout:two-col:start qa=true -->
|
|
259
|
+
Layout details...
|
|
260
|
+
<!-- @layout:two-col:end -->
|
|
261
|
+
<!-- @design:layouts:end -->
|
|
185
262
|
|
|
186
|
-
<!-- @
|
|
263
|
+
<!-- @design:components:start -->
|
|
187
264
|
<!-- @component:card:start -->
|
|
188
|
-
|
|
265
|
+
Component HTML + CSS...
|
|
189
266
|
<!-- @component:card:end -->
|
|
190
267
|
|
|
191
268
|
<!-- @component:stat-card:start -->
|
|
192
|
-
|
|
269
|
+
Component HTML + CSS...
|
|
193
270
|
<!-- @component:stat-card:end -->
|
|
194
|
-
<!-- @
|
|
271
|
+
<!-- @design:components:end -->
|
|
195
272
|
|
|
196
|
-
<!-- @
|
|
197
|
-
|
|
198
|
-
<!-- @
|
|
199
|
-
|
|
200
|
-
<!-- @section:guide:start -->
|
|
201
|
-
Composition rules, common recipes, do/don't examples...
|
|
202
|
-
<!-- @section:guide:end -->
|
|
273
|
+
<!-- @design:chart-rules:start -->
|
|
274
|
+
Chart guidance...
|
|
275
|
+
<!-- @design:chart-rules:end -->
|
|
203
276
|
```
|
|
204
277
|
|
|
205
|
-
|
|
278
|
+
Prompt injection behavior:
|
|
279
|
+
|
|
280
|
+
- always injected: `@design:foundation`, `@design:rules`, layout index, component index
|
|
281
|
+
- fetched on demand: individual `@layout:*`, individual `@component:*`, `@design:chart-rules`
|
|
206
282
|
|
|
207
|
-
|
|
283
|
+
If a design has no markers, Revela falls back to injecting the full `DESIGN.md` body.
|
|
208
284
|
|
|
209
|
-
|
|
285
|
+
### Compliance note for design authors
|
|
286
|
+
|
|
287
|
+
Revela extracts the allowed CSS class vocabulary from your design and uses it during QA compliance checks. If the agent invents a class or defines a CSS rule outside that vocabulary, QA reports it.
|
|
210
288
|
|
|
211
289
|
### Install a custom design
|
|
212
290
|
|
|
213
|
-
```
|
|
291
|
+
```text
|
|
214
292
|
/revela designs-add github:your-org/your-design
|
|
215
293
|
/revela designs-add https://example.com/my-design.zip
|
|
216
294
|
/revela designs-add ./path/to/local/design-folder
|
|
@@ -220,20 +298,31 @@ Without markers, the entire `DESIGN.md` body is injected every turn (backward-co
|
|
|
220
298
|
|
|
221
299
|
## Custom Domains
|
|
222
300
|
|
|
223
|
-
A domain
|
|
301
|
+
A custom domain is a folder containing `INDUSTRY.md` with frontmatter metadata similar to a design.
|
|
224
302
|
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
```
|
|
303
|
+
```text
|
|
228
304
|
/revela domains-add github:your-org/your-domain
|
|
229
305
|
```
|
|
230
306
|
|
|
307
|
+
`INDUSTRY.md` is a legacy filename kept for compatibility.
|
|
308
|
+
|
|
309
|
+
---
|
|
310
|
+
|
|
311
|
+
## PDF Export
|
|
312
|
+
|
|
313
|
+
Export a generated HTML deck to PDF:
|
|
314
|
+
|
|
315
|
+
```text
|
|
316
|
+
/revela pdf slides/my-deck.html
|
|
317
|
+
```
|
|
318
|
+
|
|
319
|
+
Revela renders each slide through Chrome/Chromium and assembles the final PDF in the same directory.
|
|
320
|
+
|
|
231
321
|
---
|
|
232
322
|
|
|
233
323
|
## Logging
|
|
234
324
|
|
|
235
|
-
Revela uses structured
|
|
236
|
-
Logs are written to `stderr`. To enable verbose debug output:
|
|
325
|
+
Revela uses structured logging via [tslog](https://tslog.js.org/). To enable verbose debug output:
|
|
237
326
|
|
|
238
327
|
```bash
|
|
239
328
|
REVELA_DEBUG=1 opencode
|
package/README.zh-CN.md
CHANGED
|
@@ -2,35 +2,44 @@
|
|
|
2
2
|
|
|
3
3
|
[English](README.md) | **中文**
|
|
4
4
|
|
|
5
|
-
[](https://www.npmjs.com/package/@cyber-dash-tech/revela)
|
|
6
|
-
|
|
5
|
+
[](https://www.npmjs.com/package/@cyber-dash-tech/revela) [](LICENSE) [](tests/) [](https://opencode.ai) [](https://bun.sh)
|
|
7
6
|
|
|
8
7
|
<p align="center">
|
|
9
8
|
<img src="assets/img/logo.png" alt="Revela" width="800" />
|
|
10
9
|
</p>
|
|
11
10
|
|
|
12
|
-
Revela
|
|
13
|
-
|
|
11
|
+
Revela 是一个 [OpenCode](https://opencode.ai) 插件,可以把你当前使用的 agent 变成 HTML 幻灯片生成器。
|
|
12
|
+
在当前会话中启用它之后,agent 可以完成调研、结构设计、HTML 写作和自动 QA,并把结果输出到 `slides/*.html`。
|
|
13
|
+
|
|
14
|
+
**[在线演示 — AI 权力转移](https://cyber-dash-tech.github.io/revela/assets/html/ai-power-shift.html)** · 一份使用 Revela 生成的 5 页投资简报。
|
|
15
|
+
|
|
16
|
+
---
|
|
14
17
|
|
|
18
|
+
## Revela 是什么
|
|
15
19
|
|
|
20
|
+
Revela 是一种工作模式,不是一个独立聊天 agent。
|
|
16
21
|
|
|
17
|
-
|
|
22
|
+
- `/revela enable` 会把演示文稿生成专用的 system prompt 注入到当前 agent
|
|
23
|
+
- prompt 由 3 层组成:核心 skill、当前 domain、当前 design
|
|
24
|
+
- agent 可以扫描工作区文件、委托网页调研、生成 HTML 幻灯片,并自动执行布局 QA
|
|
25
|
+
- design 和 domain 的切换都在本地完成,并会立即重建 active prompt
|
|
18
26
|
|
|
19
27
|
---
|
|
20
28
|
|
|
21
29
|
## 环境要求
|
|
22
30
|
|
|
23
|
-
- [OpenCode](https://opencode.ai)
|
|
24
|
-
-
|
|
25
|
-
-
|
|
31
|
+
- [OpenCode](https://opencode.ai)
|
|
32
|
+
- Bun 运行时(`bun >= 1.0.0`)
|
|
33
|
+
- [Google Chrome](https://www.google.com/chrome/) 或 Chromium,用于布局 QA 和 PDF 导出
|
|
34
|
+
- Git,用于源码安装
|
|
26
35
|
|
|
27
36
|
---
|
|
28
37
|
|
|
29
38
|
## 安装
|
|
30
39
|
|
|
31
|
-
###
|
|
40
|
+
### 标准安装
|
|
32
41
|
|
|
33
|
-
|
|
42
|
+
在 `opencode.json` 的 `plugin` 数组中加入 `@cyber-dash-tech/revela`:
|
|
34
43
|
|
|
35
44
|
```json
|
|
36
45
|
{
|
|
@@ -39,69 +48,69 @@ Revela 是一款 [OpenCode](https://opencode.ai) 插件,让 AI 成为你的PPT
|
|
|
39
48
|
}
|
|
40
49
|
```
|
|
41
50
|
|
|
42
|
-
重启 OpenCode
|
|
51
|
+
重启 OpenCode 后,插件会通过 Bun 自动安装。
|
|
43
52
|
|
|
44
|
-
|
|
53
|
+
如果想全局安装,可以把同样的 `plugin` 配置写到 `~/.config/opencode/opencode.json`。
|
|
45
54
|
|
|
46
|
-
###
|
|
55
|
+
### 本地 wrapper 安装
|
|
47
56
|
|
|
48
|
-
|
|
49
|
-
如果直接安装失败,推荐以下方式:
|
|
57
|
+
以下情况建议直接使用本地 wrapper:
|
|
50
58
|
|
|
51
|
-
|
|
59
|
+
- Bun 插件安装不稳定或被网络环境阻塞
|
|
60
|
+
- 你在中国大陆网络环境下使用 OpenCode
|
|
61
|
+
- 你希望直接运行本地源码仓库
|
|
52
62
|
|
|
53
|
-
|
|
54
|
-
# 确认 npm 镜像已配置
|
|
55
|
-
npm config get registry # 应为 https://registry.npmmirror.com/
|
|
63
|
+
源码安装方式:
|
|
56
64
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
65
|
+
```bash
|
|
66
|
+
git clone https://github.com/cyber-dash-tech/revela
|
|
67
|
+
cd revela
|
|
68
|
+
npm install
|
|
60
69
|
```
|
|
61
70
|
|
|
62
|
-
|
|
71
|
+
创建 `~/.config/opencode/plugins/revela.js`:
|
|
63
72
|
|
|
64
|
-
```
|
|
65
|
-
|
|
66
|
-
export { default } from "/Users/<你的用户名>/.config/opencode/node_modules/@cyber-dash-tech/revela/index.ts";
|
|
67
|
-
EOF
|
|
73
|
+
```js
|
|
74
|
+
export { default } from "/absolute/path/to/revela/index.ts";
|
|
68
75
|
```
|
|
69
76
|
|
|
70
|
-
|
|
77
|
+
如果走本地 wrapper 方案,确保 `~/.config/opencode/opencode.json` 里不要同时保留 `@cyber-dash-tech/revela` 的 `plugin` 配置,否则 OpenCode 启动时仍会尝试用 Bun 安装。
|
|
78
|
+
|
|
79
|
+
### 中国大陆网络说明
|
|
80
|
+
|
|
81
|
+
OpenCode 的 npm 插件安装依赖 Bun,而 Bun 可能不会遵循 npm mirror 配置。如果直接安装失败,优先使用上面的本地 wrapper 方案,或者先把包安装到 `~/.config/opencode/`,再手动创建本地插件入口文件。
|
|
71
82
|
|
|
72
|
-
|
|
83
|
+
---
|
|
73
84
|
|
|
74
|
-
|
|
85
|
+
## 快速开始
|
|
75
86
|
|
|
76
|
-
|
|
87
|
+
启动 OpenCode:
|
|
77
88
|
|
|
78
89
|
```bash
|
|
79
|
-
|
|
80
|
-
cd revela && npm install
|
|
90
|
+
opencode
|
|
81
91
|
```
|
|
82
92
|
|
|
83
|
-
|
|
93
|
+
在当前会话中启用 Revela:
|
|
84
94
|
|
|
85
|
-
```
|
|
86
|
-
|
|
95
|
+
```text
|
|
96
|
+
/revela enable
|
|
87
97
|
```
|
|
88
98
|
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
## 快速开始
|
|
99
|
+
然后直接给 agent 一个幻灯片任务,例如:
|
|
92
100
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
OPENCODE_ENABLE_EXA=1 opencode
|
|
101
|
+
```text
|
|
102
|
+
Create a 6-slide HTML deck on humanoid robotics supply chains. Use the summit design, cite the main market drivers, and save the result to slides/humanoid-robotics.html.
|
|
96
103
|
```
|
|
97
104
|
|
|
98
|
-
|
|
99
|
-
```
|
|
100
|
-
/revela enable
|
|
101
|
-
```
|
|
105
|
+
如果需要,把生成好的 HTML 导出为 PDF:
|
|
102
106
|
|
|
103
|
-
|
|
107
|
+
```text
|
|
108
|
+
/revela pdf slides/humanoid-robotics.html
|
|
104
109
|
```
|
|
110
|
+
|
|
111
|
+
关闭 Revela,让当前 agent 回到普通模式:
|
|
112
|
+
|
|
113
|
+
```text
|
|
105
114
|
/revela disable
|
|
106
115
|
```
|
|
107
116
|
|
|
@@ -109,139 +118,177 @@ OPENCODE_ENABLE_EXA=1 opencode
|
|
|
109
118
|
|
|
110
119
|
## 命令
|
|
111
120
|
|
|
112
|
-
```
|
|
113
|
-
/revela
|
|
114
|
-
/revela enable
|
|
115
|
-
/revela disable
|
|
121
|
+
```text
|
|
122
|
+
/revela 显示当前状态与帮助
|
|
123
|
+
/revela enable 为当前会话启用演示文稿模式
|
|
124
|
+
/revela disable 关闭演示文稿模式
|
|
125
|
+
|
|
126
|
+
/revela designs 列出已安装 design
|
|
127
|
+
/revela designs <name> 激活某个 design
|
|
128
|
+
/revela designs-add <source> 从 URL、本地路径或 github:user/repo 安装 design
|
|
129
|
+
/revela designs-rm <name> 删除已安装 design
|
|
116
130
|
|
|
117
|
-
/revela
|
|
118
|
-
/revela
|
|
119
|
-
/revela
|
|
131
|
+
/revela domains 列出已安装 domain
|
|
132
|
+
/revela domains <name> 激活某个 domain
|
|
133
|
+
/revela domains-add <source> 从 URL、本地路径或 github:user/repo 安装 domain
|
|
134
|
+
/revela domains-rm <name> 删除已安装 domain
|
|
120
135
|
|
|
121
|
-
/revela
|
|
122
|
-
/revela domains <name> 切换领域
|
|
123
|
-
/revela domains-add <source> 从 URL、本地路径或 github:user/repo 安装领域
|
|
136
|
+
/revela pdf <file> 将 HTML deck 导出为同目录 PDF
|
|
124
137
|
```
|
|
125
138
|
|
|
126
|
-
|
|
139
|
+
所有 `/revela` 命令都在本地执行,不消耗 LLM token。
|
|
127
140
|
|
|
128
141
|
---
|
|
129
142
|
|
|
130
|
-
##
|
|
143
|
+
## 工作原理
|
|
131
144
|
|
|
132
|
-
|
|
145
|
+
启用 Revela 后,它会把一份动态生成的 prompt 追加到当前 agent 的 system prompt 中。
|
|
133
146
|
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
147
|
+
这份 prompt 由 3 层组成:
|
|
148
|
+
|
|
149
|
+
1. `skill/SKILL.md`:核心幻灯片生成流程
|
|
150
|
+
2. 当前 active domain:行业结构与术语
|
|
151
|
+
3. 当前 active design:视觉语言、layout、component 和图表规则
|
|
152
|
+
|
|
153
|
+
当前 design 和 domain 会持久化到 `~/.config/revela/config.json`。是否启用 Revela 则是会话级状态,不会跨会话持久化。
|
|
138
154
|
|
|
139
155
|
---
|
|
140
156
|
|
|
141
|
-
##
|
|
157
|
+
## 调研与文件摄取
|
|
142
158
|
|
|
143
|
-
|
|
159
|
+
启用 Revela 后,agent 可以使用:
|
|
144
160
|
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
161
|
+
- `revela-workspace-scan` 扫描工作区中的 PDF、Office 文件、CSV、Markdown 和文本文件
|
|
162
|
+
- `revela-research` 子代理抓取目标网页,并把结构化结果保存到 `researches/<topic>/`
|
|
163
|
+
- `revela-research-save` 按 research axis 写入单个 findings 文件
|
|
164
|
+
|
|
165
|
+
支持 `@` 引用和自动文本提取的文件类型:
|
|
166
|
+
|
|
167
|
+
- `.pdf`
|
|
168
|
+
- `.docx`
|
|
169
|
+
- `.pptx`
|
|
170
|
+
- `.xlsx`
|
|
150
171
|
|
|
151
|
-
|
|
172
|
+
Revela 会在主 agent 处理这些文件前,先透明地完成文本提取。
|
|
152
173
|
|
|
153
174
|
---
|
|
154
175
|
|
|
155
|
-
##
|
|
176
|
+
## 布局 QA 与合规检查
|
|
177
|
+
|
|
178
|
+
每次 agent 写入 `slides/*.html` 时,Revela 都会自动在 `1920x1080` 分辨率下运行一轮基于 Puppeteer 的 QA。
|
|
179
|
+
报告会立刻反馈给 agent,用于继续修正布局或 design compliance 问题。
|
|
180
|
+
|
|
181
|
+
当前 QA 维度如下:
|
|
182
|
+
|
|
183
|
+
| 维度 | 检查内容 |
|
|
184
|
+
|---|---|
|
|
185
|
+
| `overflow` | 元素是否超出 slide canvas |
|
|
186
|
+
| `balance` | 是否过稀、重心偏移、底部留白过大等 |
|
|
187
|
+
| `symmetry` | 并列列之间的高度或密度是否明显失衡 |
|
|
188
|
+
| `rhythm` | 垂直堆叠元素之间的间距节奏是否不稳定 |
|
|
189
|
+
| `compliance` | 是否使用了 active design 之外的 class 或新增 CSS 规则 |
|
|
190
|
+
|
|
191
|
+
每张 slide 都必须显式声明 `slide-qa="true"` 或 `slide-qa="false"`。
|
|
156
192
|
|
|
157
|
-
|
|
193
|
+
- `slide-qa="true"`:适用于内容型页面,执行完整 QA
|
|
194
|
+
- `slide-qa="false"`:适用于封面、目录、引用、总结、结尾等结构型页面
|
|
158
195
|
|
|
159
|
-
|
|
160
|
-
- **并行研究**(通过 `revela-research` 子代理)—— 抓取目标 URL,将结构化研究结果保存到 `researches/<topic>/`,主代理随后将这些结果整合到幻灯片中。
|
|
196
|
+
`compliance` 不是软建议,而是生成流程的一部分。如果 agent 发明了 design 之外的 class 或 CSS rule,QA 会直接指出并要求修正。
|
|
161
197
|
|
|
162
|
-
|
|
198
|
+
也可以手动调用 `revela-qa` 工具执行 QA。
|
|
163
199
|
|
|
164
200
|
---
|
|
165
201
|
|
|
166
|
-
##
|
|
202
|
+
## 内置 Designs
|
|
167
203
|
|
|
168
|
-
|
|
204
|
+
使用 `/revela designs <name>` 切换。
|
|
169
205
|
|
|
170
|
-
|
|
206
|
+
| 名称 | 说明 | 预览 |
|
|
207
|
+
|---|---|---|
|
|
208
|
+
| `aurora` | 深色 executive 风格,信息密度更高,适合结构化商业表达和 ECharts 数据可视化 |  |
|
|
209
|
+
| `summit` | 年报式 editorial 风格,适合图像丰富、叙事感更强的商业表达 |  |
|
|
171
210
|
|
|
172
|
-
|
|
173
|
-
|---|---|
|
|
174
|
-
| **填充率** | 内容必须占据足够的画布面积 |
|
|
175
|
-
| **底部留白** | 标记幻灯片底部的大片空白 |
|
|
176
|
-
| **溢出** | 超出画布边界的元素 |
|
|
177
|
-
| **不对称** | 并排列高度差异过大 |
|
|
178
|
-
| **密度失衡** | CSS `align-items: stretch` 列布局中隐藏的内容不平衡 |
|
|
179
|
-
| **稀疏** | 可见元素过少的幻灯片 |
|
|
211
|
+
---
|
|
180
212
|
|
|
181
|
-
|
|
213
|
+
## 内置 Domains
|
|
182
214
|
|
|
183
|
-
|
|
215
|
+
使用 `/revela domains <name>` 切换。
|
|
184
216
|
|
|
185
|
-
|
|
217
|
+
| 名称 | 说明 |
|
|
218
|
+
|---|---|
|
|
219
|
+
| `general` | 不做领域专化 |
|
|
220
|
+
| `deeptech-investment` | VC / 投资分析:市场规模、技术成熟度、护城河与投资逻辑 |
|
|
221
|
+
| `consulting` | 战略咨询:go/no-go 判断、战略设计与 belief-change 报告 |
|
|
186
222
|
|
|
187
223
|
---
|
|
188
224
|
|
|
189
|
-
##
|
|
225
|
+
## 自定义 Designs
|
|
190
226
|
|
|
191
|
-
|
|
227
|
+
自定义 design 是一个包含 `DESIGN.md` 的文件夹,文件头使用 frontmatter:
|
|
192
228
|
|
|
193
229
|
```yaml
|
|
194
230
|
---
|
|
195
231
|
name: my-design
|
|
196
232
|
description: 在 /revela designs 中显示的简短说明
|
|
197
|
-
author:
|
|
233
|
+
author: you
|
|
198
234
|
version: 1.0.0
|
|
199
235
|
---
|
|
200
236
|
```
|
|
201
237
|
|
|
202
|
-
|
|
238
|
+
文件正文定义 agent 可使用的视觉系统。
|
|
203
239
|
|
|
204
|
-
###
|
|
240
|
+
### Marker 体系
|
|
205
241
|
|
|
206
|
-
|
|
242
|
+
对于较大的 design,建议使用当前 marker 格式:
|
|
207
243
|
|
|
208
244
|
```html
|
|
209
|
-
<!-- @
|
|
210
|
-
|
|
211
|
-
<!-- @
|
|
245
|
+
<!-- @design:foundation:start -->
|
|
246
|
+
色彩、字体、CSS 变量、HTML 外壳、基础 JS...
|
|
247
|
+
<!-- @design:foundation:end -->
|
|
248
|
+
|
|
249
|
+
<!-- @design:rules:start -->
|
|
250
|
+
构图规则、正反案例、design 特定约束...
|
|
251
|
+
<!-- @design:rules:end -->
|
|
212
252
|
|
|
213
|
-
<!-- @
|
|
214
|
-
|
|
215
|
-
|
|
253
|
+
<!-- @design:layouts:start -->
|
|
254
|
+
<!-- @layout:cover:start qa=false -->
|
|
255
|
+
Layout 详情...
|
|
256
|
+
<!-- @layout:cover:end -->
|
|
216
257
|
|
|
217
|
-
<!-- @
|
|
258
|
+
<!-- @layout:two-col:start qa=true -->
|
|
259
|
+
Layout 详情...
|
|
260
|
+
<!-- @layout:two-col:end -->
|
|
261
|
+
<!-- @design:layouts:end -->
|
|
262
|
+
|
|
263
|
+
<!-- @design:components:start -->
|
|
218
264
|
<!-- @component:card:start -->
|
|
219
|
-
|
|
265
|
+
Component HTML + CSS...
|
|
220
266
|
<!-- @component:card:end -->
|
|
221
267
|
|
|
222
268
|
<!-- @component:stat-card:start -->
|
|
223
|
-
|
|
269
|
+
Component HTML + CSS...
|
|
224
270
|
<!-- @component:stat-card:end -->
|
|
225
|
-
<!-- @
|
|
226
|
-
|
|
227
|
-
<!-- @section:charts:start -->
|
|
228
|
-
ECharts / 数据可视化规范...
|
|
229
|
-
<!-- @section:charts:end -->
|
|
271
|
+
<!-- @design:components:end -->
|
|
230
272
|
|
|
231
|
-
<!-- @
|
|
232
|
-
|
|
233
|
-
<!-- @
|
|
273
|
+
<!-- @design:chart-rules:start -->
|
|
274
|
+
图表规则...
|
|
275
|
+
<!-- @design:chart-rules:end -->
|
|
234
276
|
```
|
|
235
277
|
|
|
236
|
-
|
|
278
|
+
Prompt 注入行为如下:
|
|
237
279
|
|
|
238
|
-
|
|
280
|
+
- 常驻注入:`@design:foundation`、`@design:rules`、layout index、component index
|
|
281
|
+
- 按需获取:单个 `@layout:*`、单个 `@component:*`、`@design:chart-rules`
|
|
239
282
|
|
|
240
|
-
|
|
283
|
+
如果 design 没有 marker,Revela 会退回到整份 `DESIGN.md` 全量注入。
|
|
241
284
|
|
|
242
|
-
###
|
|
285
|
+
### 给 design 作者的 compliance 说明
|
|
243
286
|
|
|
244
|
-
|
|
287
|
+
Revela 会从 design 中提取允许使用的 CSS class vocabulary,并在 QA 的 compliance 维度里做校验。如果 agent 发明了新的 class 或 CSS rule,QA 会直接报出。
|
|
288
|
+
|
|
289
|
+
### 安装自定义 Design
|
|
290
|
+
|
|
291
|
+
```text
|
|
245
292
|
/revela designs-add github:your-org/your-design
|
|
246
293
|
/revela designs-add https://example.com/my-design.zip
|
|
247
294
|
/revela designs-add ./path/to/local/design-folder
|
|
@@ -249,23 +296,33 @@ ECharts / 数据可视化规范...
|
|
|
249
296
|
|
|
250
297
|
---
|
|
251
298
|
|
|
252
|
-
##
|
|
253
|
-
|
|
254
|
-
领域为 AI 增加特定行业的报告框架、术语和结构化指导。
|
|
299
|
+
## 自定义 Domains
|
|
255
300
|
|
|
256
|
-
|
|
301
|
+
自定义 domain 是一个包含 `INDUSTRY.md` 的文件夹,frontmatter 结构与 design 类似。
|
|
257
302
|
|
|
258
|
-
```
|
|
303
|
+
```text
|
|
259
304
|
/revela domains-add github:your-org/your-domain
|
|
260
305
|
```
|
|
261
306
|
|
|
307
|
+
`INDUSTRY.md` 是为了兼容历史版本而保留的文件名。
|
|
308
|
+
|
|
309
|
+
---
|
|
310
|
+
|
|
311
|
+
## PDF 导出
|
|
312
|
+
|
|
313
|
+
把生成好的 HTML deck 导出为 PDF:
|
|
314
|
+
|
|
315
|
+
```text
|
|
316
|
+
/revela pdf slides/my-deck.html
|
|
317
|
+
```
|
|
318
|
+
|
|
319
|
+
Revela 会通过 Chrome / Chromium 渲染每一页 slide,并在同目录生成最终 PDF。
|
|
320
|
+
|
|
262
321
|
---
|
|
263
322
|
|
|
264
323
|
## 日志
|
|
265
324
|
|
|
266
|
-
Revela
|
|
267
|
-
|
|
268
|
-
开启详细调试输出:
|
|
325
|
+
Revela 使用 [tslog](https://tslog.js.org/) 输出结构化日志。开启详细调试输出:
|
|
269
326
|
|
|
270
327
|
```bash
|
|
271
328
|
REVELA_DEBUG=1 opencode
|
|
@@ -275,4 +332,4 @@ REVELA_DEBUG=1 opencode
|
|
|
275
332
|
|
|
276
333
|
## 许可证
|
|
277
334
|
|
|
278
|
-
MIT
|
|
335
|
+
MIT,详见 [LICENSE](LICENSE).
|
package/designs/summit/DESIGN.md
CHANGED
|
@@ -31,6 +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: 'IBM Plex Sans Condensed', 'Inter', ui-sans-serif, sans-serif;
|
|
35
|
+
--font-body: 'Inter', ui-sans-serif, sans-serif;
|
|
34
36
|
}
|
|
35
37
|
```
|
|
36
38
|
|
|
@@ -150,7 +152,7 @@ html {
|
|
|
150
152
|
body {
|
|
151
153
|
background: var(--bg-frame);
|
|
152
154
|
color: var(--text-primary);
|
|
153
|
-
font-family:
|
|
155
|
+
font-family: var(--font-body);
|
|
154
156
|
-webkit-font-smoothing: antialiased;
|
|
155
157
|
height: 100%;
|
|
156
158
|
}
|
|
@@ -202,7 +204,7 @@ body {
|
|
|
202
204
|
}
|
|
203
205
|
|
|
204
206
|
h1, h2, h3, h4 {
|
|
205
|
-
font-family:
|
|
207
|
+
font-family: var(--font-display);
|
|
206
208
|
font-weight: 600;
|
|
207
209
|
letter-spacing: -0.02em;
|
|
208
210
|
color: var(--text-primary);
|
|
@@ -572,6 +574,8 @@ Every slot accepts 1 or more components. The LLM decides what each slot contains
|
|
|
572
574
|
|
|
573
575
|
Equal N-column layout. Use when 3 or more parallel items of roughly equal visual weight should appear side by side — proof blocks, highlights, feature comparisons, stat groups, or any multi-column editorial spread.
|
|
574
576
|
|
|
577
|
+
A short section header is optional but recommended. In Summit, that header should stay lean: eyebrow plus title only, with no intro paragraph competing with the columns below.
|
|
578
|
+
|
|
575
579
|
Structural intent:
|
|
576
580
|
- each slot: 1fr column — any component(s)
|
|
577
581
|
- column count: determined by the number of direct child divs in the grid container; `auto-fit` distributes space equally
|
|
@@ -582,6 +586,11 @@ Every slot accepts 1 or more components. Add or remove child divs to control col
|
|
|
582
586
|
<section class="slide" slide-qa="true" data-index="N">
|
|
583
587
|
<div class="slide-canvas">
|
|
584
588
|
<div class="page">
|
|
589
|
+
<div style="display:flex;flex-direction:column;gap:10px;margin-bottom:28px;max-width:520px;">
|
|
590
|
+
<p class="eyebrow">Section Label</p>
|
|
591
|
+
<h2 style="font-size:52px;line-height:0.94;text-transform:uppercase;">Short framing title for the parallel columns</h2>
|
|
592
|
+
</div>
|
|
593
|
+
|
|
585
594
|
<div class="highlight-cols-grid" style="flex:1;min-height:0;">
|
|
586
595
|
|
|
587
596
|
<!-- [slot: 1] — 1+ components; suggested: editorial-image-top, editorial-text-top, echart-panel -->
|
|
@@ -619,8 +628,10 @@ Every slot accepts 1 or more components. Add or remove child divs to control col
|
|
|
619
628
|
|
|
620
629
|
##### Tips
|
|
621
630
|
- **Grid container needs `flex:1;min-height:0` inline** when inside `.page` (which is flex-column). The class handles column sizing; the inline style handles row stretch.
|
|
631
|
+
- **Header stays lean.** If you add a section header above the grid, use only `eyebrow + title`. Do not add an intro paragraph; the columns themselves should carry the explanation.
|
|
622
632
|
- **Column count = number of direct child divs.** `repeat(auto-fit, minmax(0, 1fr))` distributes available width equally across however many children exist. Add a 4th or 5th div to get 4 or 5 columns — no CSS change needed.
|
|
623
633
|
- **Equal columns — no hierarchy.** All slots carry the same visual weight. Adjust content density to suit the slide purpose; do not artificially inflate one column to create false hierarchy.
|
|
634
|
+
- **When using 4-5 columns, compress the header.** Keep the title to one or two short lines so the grid retains most of the slide height.
|
|
624
635
|
- **Do not set fixed heights on editorial components.** Let components fill height via flexbox stretch.
|
|
625
636
|
<!-- @layout:highlight-cols:end -->
|
|
626
637
|
|
|
@@ -860,6 +871,79 @@ Rules:
|
|
|
860
871
|
- **`editorial-list` inside `--dark`.** Add `style="--accent-earth:rgba(247,244,238,0.72)"` on the `<ul>` wrapper so the bullet squares read against the dark background.
|
|
861
872
|
<!-- @component:text-panel:end -->
|
|
862
873
|
|
|
874
|
+
<!-- @component:stat-card:start -->
|
|
875
|
+
#### Stat Card
|
|
876
|
+
|
|
877
|
+
Lightweight editorial metric module for a single highlighted number. Use when one data point should carry the visual emphasis while the metric name and guiding sentence stay quiet and compact.
|
|
878
|
+
|
|
879
|
+
This is **not** a dashboard card. It has no border, no background fill, no shadow, and no corner treatment. Hierarchy comes from number scale, spacing, and restrained typography.
|
|
880
|
+
|
|
881
|
+
```html
|
|
882
|
+
<!-- variant A: default vertical composition -->
|
|
883
|
+
<div class="stat-card">
|
|
884
|
+
<p class="caption" style="color:var(--text-muted);">Performance signal</p>
|
|
885
|
+
<div class="stat-card-value" style="color: var(--accent-gold);">27%</div>
|
|
886
|
+
<div class="text-panel-body" style="gap:10px;max-width:330px;">
|
|
887
|
+
<h3 style="font-size:24px;line-height:1.04;text-transform:uppercase;">EBIT Margin</h3>
|
|
888
|
+
<p style="font-size:14px;line-height:1.56;color:var(--text-secondary);">Expanded for the third consecutive quarter as premium mix offset freight pressure and held pricing discipline through softer volume.</p>
|
|
889
|
+
</div>
|
|
890
|
+
</div>
|
|
891
|
+
|
|
892
|
+
<!-- variant B: horizontal composition -->
|
|
893
|
+
<div class="stat-card stat-card--horizontal">
|
|
894
|
+
<div style="display:flex;flex-direction:column;gap:12px;flex:0 0 220px;min-width:0;">
|
|
895
|
+
<p class="caption" style="color:var(--text-muted);">Operational baseline</p>
|
|
896
|
+
<div class="stat-card-value" style="color: var(--accent-olive);">4.8x</div>
|
|
897
|
+
</div>
|
|
898
|
+
<div class="text-panel-body" style="gap:10px;max-width:330px;">
|
|
899
|
+
<h3 style="font-size:24px;line-height:1.04;text-transform:uppercase;">Inventory Turnover</h3>
|
|
900
|
+
<p style="font-size:14px;line-height:1.56;color:var(--text-secondary);">Higher cycle efficiency reduced working-capital drag without adding new capacity, leaving more headroom for seasonal demand swings.</p>
|
|
901
|
+
</div>
|
|
902
|
+
</div>
|
|
903
|
+
```
|
|
904
|
+
|
|
905
|
+
```css
|
|
906
|
+
.stat-card {
|
|
907
|
+
height: 100%;
|
|
908
|
+
display: flex;
|
|
909
|
+
min-height: 0;
|
|
910
|
+
flex-direction: column;
|
|
911
|
+
justify-content: flex-start;
|
|
912
|
+
gap: 16px;
|
|
913
|
+
padding-top: 8px;
|
|
914
|
+
}
|
|
915
|
+
|
|
916
|
+
.stat-card--horizontal {
|
|
917
|
+
flex-direction: row;
|
|
918
|
+
align-items: flex-start;
|
|
919
|
+
gap: 30px;
|
|
920
|
+
}
|
|
921
|
+
|
|
922
|
+
.stat-card-value {
|
|
923
|
+
font-family: var(--font-display);
|
|
924
|
+
font-size: 88px;
|
|
925
|
+
line-height: 0.9;
|
|
926
|
+
letter-spacing: -0.04em;
|
|
927
|
+
font-weight: 600;
|
|
928
|
+
font-variant-numeric: tabular-nums;
|
|
929
|
+
color: inherit;
|
|
930
|
+
}
|
|
931
|
+
```
|
|
932
|
+
|
|
933
|
+
Rules:
|
|
934
|
+
- Use this component only for a **single** highlighted metric. If the slide needs several peer metrics, switch to a multi-item layout instead of stacking several stat cards together without hierarchy.
|
|
935
|
+
- The number color is chosen semantically from the Summit palette via inline `style="color: var(--accent-xxx)"`; do not hardcode a fixed color in the component CSS.
|
|
936
|
+
- Do not add background fills, borders, shadows, or rounded corners. The module must remain typographic and editorial.
|
|
937
|
+
- Use `h3` for the metric name and a single compact `p` for the guiding sentence. Keep the copy to one or two sentences.
|
|
938
|
+
- Default `stat-card` is vertical. Add `stat-card--horizontal` only when the number and explanation need a side-by-side read.
|
|
939
|
+
|
|
940
|
+
##### Tips
|
|
941
|
+
- **Horizontal width discipline.** In the horizontal variant, keep the number column narrow (`~220px`) so the prose still reads as the explanatory side, not as a second visual block.
|
|
942
|
+
- **Long numbers.** For values such as `12,450` or `83.6%`, reduce the inline font size slightly before tightening letter-spacing further.
|
|
943
|
+
- **Semantic color choice.** `--accent-gold` works for primary emphasis, `--accent-olive` for stable or positive operational metrics, `--accent-danger` for negative indicators, and `--accent-sage` for environmental or resilience-oriented signals.
|
|
944
|
+
- **Do not over-explain.** If the description starts to become paragraph-length, switch to `text-panel` or pair the stat card with a narrative component in the neighboring slot.
|
|
945
|
+
<!-- @component:stat-card:end -->
|
|
946
|
+
|
|
863
947
|
<!-- @component:editorial-image-top:start -->
|
|
864
948
|
#### Editorial Image Top
|
|
865
949
|
|
|
@@ -1115,7 +1199,7 @@ Rules:
|
|
|
1115
1199
|
- The left copy zone holds a kicker row followed by a `text-panel-body`. The body accepts prose `<p>`, an `<ul class="editorial-list">`, or both — choose based on content.
|
|
1116
1200
|
- The right visual slot is open: use a plain `media-frame img`, an `echart-container`, or a full `image-title` component. Choose based on content — there is no default.
|
|
1117
1201
|
- When using `editorial-list` inside `text-panel-body`, add `<strong>` around the first 2–5 words of each `<li>` to create a bold lead phrase for scannable hierarchy.
|
|
1118
|
-
- When the card carries a large statistic or callout number, place it between the header and the copy zone using an inline style (`font-size: 48px; font-family:
|
|
1202
|
+
- When the card carries a large statistic or callout number, place it between the header and the copy zone using an inline style (`font-size: 48px; font-family: var(--font-display); font-weight: 700; color: var(--accent-gold); line-height: 1;`).
|
|
1119
1203
|
|
|
1120
1204
|
##### Tips
|
|
1121
1205
|
- **Parent must supply height.** `.editorial-text-left` uses `height: 100%` and `flex: 1` internally. The parent slot must have a defined height (grid cell, `height:100%` chain, or `flex:1;min-height:0`).
|
|
@@ -1239,6 +1323,34 @@ Horizontal step or phase sequence. Use for process stages, numbered definitions,
|
|
|
1239
1323
|
```
|
|
1240
1324
|
|
|
1241
1325
|
```css
|
|
1326
|
+
/* Shared by flow-horizontal and flow-vertical */
|
|
1327
|
+
.flow-number {
|
|
1328
|
+
font-family: var(--font-display);
|
|
1329
|
+
font-size: 13px;
|
|
1330
|
+
font-weight: 700;
|
|
1331
|
+
letter-spacing: 0.12em;
|
|
1332
|
+
color: var(--text-muted);
|
|
1333
|
+
border: 1px solid var(--line-strong);
|
|
1334
|
+
width: 34px;
|
|
1335
|
+
height: 34px;
|
|
1336
|
+
display: flex;
|
|
1337
|
+
align-items: center;
|
|
1338
|
+
justify-content: center;
|
|
1339
|
+
flex-shrink: 0;
|
|
1340
|
+
}
|
|
1341
|
+
|
|
1342
|
+
.flow-body h4 {
|
|
1343
|
+
font-size: 20px;
|
|
1344
|
+
font-weight: 600;
|
|
1345
|
+
line-height: 1.14;
|
|
1346
|
+
}
|
|
1347
|
+
|
|
1348
|
+
.flow-body p {
|
|
1349
|
+
font-size: 14px;
|
|
1350
|
+
line-height: 1.6;
|
|
1351
|
+
color: var(--text-secondary);
|
|
1352
|
+
}
|
|
1353
|
+
|
|
1242
1354
|
.flow-horizontal {
|
|
1243
1355
|
position: relative;
|
|
1244
1356
|
display: flex;
|
|
@@ -1273,30 +1385,6 @@ Horizontal step or phase sequence. Use for process stages, numbered definitions,
|
|
|
1273
1385
|
position: relative;
|
|
1274
1386
|
z-index: 1;
|
|
1275
1387
|
background: var(--bg-page);
|
|
1276
|
-
font-family: 'IBM Plex Sans Condensed', sans-serif;
|
|
1277
|
-
font-size: 13px;
|
|
1278
|
-
font-weight: 700;
|
|
1279
|
-
letter-spacing: 0.12em;
|
|
1280
|
-
color: var(--text-muted);
|
|
1281
|
-
border: 1px solid var(--line-strong);
|
|
1282
|
-
width: 34px;
|
|
1283
|
-
height: 34px;
|
|
1284
|
-
display: flex;
|
|
1285
|
-
align-items: center;
|
|
1286
|
-
justify-content: center;
|
|
1287
|
-
flex-shrink: 0;
|
|
1288
|
-
}
|
|
1289
|
-
|
|
1290
|
-
.flow-horizontal .flow-body h4 {
|
|
1291
|
-
font-size: 20px;
|
|
1292
|
-
font-weight: 600;
|
|
1293
|
-
line-height: 1.14;
|
|
1294
|
-
}
|
|
1295
|
-
|
|
1296
|
-
.flow-horizontal .flow-body p {
|
|
1297
|
-
font-size: 14px;
|
|
1298
|
-
line-height: 1.6;
|
|
1299
|
-
color: var(--text-secondary);
|
|
1300
1388
|
}
|
|
1301
1389
|
```
|
|
1302
1390
|
|
|
@@ -1372,21 +1460,6 @@ Vertical step or timeline sequence. Use for chronological phases, execution stag
|
|
|
1372
1460
|
flex-shrink: 0;
|
|
1373
1461
|
}
|
|
1374
1462
|
|
|
1375
|
-
.flow-vertical .flow-number {
|
|
1376
|
-
font-family: 'IBM Plex Sans Condensed', sans-serif;
|
|
1377
|
-
font-size: 13px;
|
|
1378
|
-
font-weight: 700;
|
|
1379
|
-
letter-spacing: 0.12em;
|
|
1380
|
-
color: var(--text-muted);
|
|
1381
|
-
border: 1px solid var(--line-strong);
|
|
1382
|
-
width: 34px;
|
|
1383
|
-
height: 34px;
|
|
1384
|
-
display: flex;
|
|
1385
|
-
align-items: center;
|
|
1386
|
-
justify-content: center;
|
|
1387
|
-
flex-shrink: 0;
|
|
1388
|
-
}
|
|
1389
|
-
|
|
1390
1463
|
.flow-vertical .flow-line {
|
|
1391
1464
|
width: 1px;
|
|
1392
1465
|
flex: 1;
|
|
@@ -1404,17 +1477,11 @@ Vertical step or timeline sequence. Use for chronological phases, execution stag
|
|
|
1404
1477
|
}
|
|
1405
1478
|
|
|
1406
1479
|
.flow-vertical .flow-body h4 {
|
|
1407
|
-
font-size: 20px;
|
|
1408
|
-
font-weight: 600;
|
|
1409
|
-
line-height: 1.14;
|
|
1410
1480
|
margin-top: 4px;
|
|
1411
1481
|
}
|
|
1412
1482
|
|
|
1413
1483
|
.flow-vertical .flow-body p {
|
|
1414
1484
|
margin-top: 8px;
|
|
1415
|
-
font-size: 14px;
|
|
1416
|
-
line-height: 1.6;
|
|
1417
|
-
color: var(--text-secondary);
|
|
1418
1485
|
}
|
|
1419
1486
|
```
|
|
1420
1487
|
|
|
@@ -1502,7 +1569,7 @@ Annual-report format data table. Use for year-on-year comparisons, emissions dat
|
|
|
1502
1569
|
.data-table {
|
|
1503
1570
|
width: 100%;
|
|
1504
1571
|
border-collapse: collapse;
|
|
1505
|
-
font-family:
|
|
1572
|
+
font-family: var(--font-body);
|
|
1506
1573
|
font-size: 13px;
|
|
1507
1574
|
font-variant-numeric: tabular-nums;
|
|
1508
1575
|
color: var(--text-primary);
|
|
@@ -1907,7 +1974,7 @@ Flat editorial quote block. Wide and short (width > height). Transparent backgro
|
|
|
1907
1974
|
display: flex;
|
|
1908
1975
|
align-items: center;
|
|
1909
1976
|
justify-content: center;
|
|
1910
|
-
font-family:
|
|
1977
|
+
font-family: var(--font-display);
|
|
1911
1978
|
font-size: 14px;
|
|
1912
1979
|
font-weight: 700;
|
|
1913
1980
|
color: var(--text-muted);
|
|
@@ -2015,7 +2082,7 @@ Omit `--light` only on slides with a white/light background.
|
|
|
2015
2082
|
position: absolute;
|
|
2016
2083
|
bottom: 36px;
|
|
2017
2084
|
right: 52px;
|
|
2018
|
-
font-family:
|
|
2085
|
+
font-family: var(--font-display);
|
|
2019
2086
|
font-size: 11px;
|
|
2020
2087
|
font-weight: 700;
|
|
2021
2088
|
letter-spacing: 0.18em;
|
|
@@ -2149,7 +2216,7 @@ A horizontal milestone timeline with a central axis line. Nodes sit on the axis;
|
|
|
2149
2216
|
|
|
2150
2217
|
/* Date: inherits node colour via --tjh-item-color */
|
|
2151
2218
|
.tjh-date {
|
|
2152
|
-
font-family:
|
|
2219
|
+
font-family: var(--font-display);
|
|
2153
2220
|
font-size: 11px;
|
|
2154
2221
|
font-weight: 700;
|
|
2155
2222
|
letter-spacing: 0.16em;
|
|
@@ -2160,7 +2227,7 @@ A horizontal milestone timeline with a central axis line. Nodes sit on the axis;
|
|
|
2160
2227
|
}
|
|
2161
2228
|
|
|
2162
2229
|
.tjh-title {
|
|
2163
|
-
font-family:
|
|
2230
|
+
font-family: var(--font-display);
|
|
2164
2231
|
font-size: 16px;
|
|
2165
2232
|
font-weight: 600;
|
|
2166
2233
|
letter-spacing: -0.01em;
|
|
@@ -2344,7 +2411,7 @@ Can be placed inside any layout slot that provides a defined height (`narrative`
|
|
|
2344
2411
|
|
|
2345
2412
|
/* Date — colored per node via --tjv-item-color */
|
|
2346
2413
|
.tjv-date {
|
|
2347
|
-
font-family:
|
|
2414
|
+
font-family: var(--font-display);
|
|
2348
2415
|
font-size: 11px;
|
|
2349
2416
|
font-weight: 700;
|
|
2350
2417
|
letter-spacing: 0.16em;
|
|
@@ -2355,7 +2422,7 @@ Can be placed inside any layout slot that provides a defined height (`narrative`
|
|
|
2355
2422
|
}
|
|
2356
2423
|
|
|
2357
2424
|
.tjv-title {
|
|
2358
|
-
font-family:
|
|
2425
|
+
font-family: var(--font-display);
|
|
2359
2426
|
font-size: 18px;
|
|
2360
2427
|
font-weight: 600;
|
|
2361
2428
|
letter-spacing: -0.01em;
|