thurview 0.18.0 → 0.20.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.
@@ -4,6 +4,27 @@
4
4
  <meta charset="utf-8" />
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1" />
6
6
  <title>thurview</title>
7
+ <script>
8
+ // Before first paint, so the page never flashes the other palette: the
9
+ // reader's pick from the menu wins, and "system" follows the OS, live.
10
+ (() => {
11
+ const os = matchMedia("(prefers-color-scheme: dark)");
12
+ // `chosen` is the menu's pick, so it applies even where storage is blocked
13
+ const apply = (chosen) => {
14
+ let pick = typeof chosen === "string" ? chosen : "system";
15
+ if (typeof chosen !== "string")
16
+ try {
17
+ pick = localStorage.getItem("thurview.theme") || "system";
18
+ } catch {}
19
+ const root = document.documentElement;
20
+ root.dataset.themePick = pick;
21
+ root.dataset.theme = pick === "system" ? (os.matches ? "dark" : "light") : pick;
22
+ };
23
+ os.addEventListener("change", () => apply(document.documentElement.dataset.themePick));
24
+ window.thurviewTheme = apply;
25
+ apply();
26
+ })();
27
+ </script>
7
28
  <link rel="stylesheet" href="/app.css" />
8
29
  </head>
9
30
  <body>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "thurview",
3
- "version": "0.18.0",
3
+ "version": "0.20.0",
4
4
  "description": "Guided, evidence-anchored reviews of agent-written code. A coding agent authors the review; you read, ask, comment and decide in the browser.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -85,8 +85,7 @@ Read [Document authoring](references/document-authoring.md) before you write.
85
85
  Read [Components](references/components.md) before you edit `data.yaml` or add
86
86
  a fenced component. Read [Lifecycle](references/lifecycle.md) for statuses,
87
87
  storage and thread rules. Read [Software map](references/software-map.md)
88
- before you author `map.yaml`. Read [Theme](references/theme.md) before you
89
- write `theme.yaml`.
88
+ before you author `map.yaml`.
90
89
 
91
90
  ## Workflow
92
91
 
@@ -110,7 +109,7 @@ head), when you need to choose between several.
110
109
 
111
110
  Record from the output: `review.id` (the short id, accepted everywhere),
112
111
  `review.dir`, `review.base`, `review.head`, `files.document`, `files.data`,
113
- `files.map`, `files.theme`, `change` (files, additions, deletions) and
112
+ `files.map`, `change` (files, additions, deletions) and
114
113
  `guidance`.
115
114
 
116
115
  Resolve refs before passing them. Pass commit ids or plain ref names; do not
@@ -237,14 +236,7 @@ not, and publishes as "not assessed". See
237
236
  [Document authoring](references/document-authoring.md) and
238
237
  [Components](references/components.md).
239
238
 
240
- ### 6. Theme the review after the project
241
-
242
- Read [Theme](references/theme.md). Decide the look in its order: what the
243
- user asked for, then the reviewed project's own design system read from its
244
- files at head, then the default skin. Write `theme.yaml` in the review
245
- directory when steps 1 or 2 yield tokens; leave it empty otherwise.
246
-
247
- ### 7. Publish
239
+ ### 6. Publish
248
240
 
249
241
  ```sh
250
242
  thurview publish --review <id>
@@ -252,7 +244,7 @@ thurview publish --review <id>
252
244
 
253
245
  Read every row of `diagnostics`. Fix each `error` and publish again. A
254
246
  `warning` does not block. `publish` refuses (code `THREADS_OPEN`) when a
255
- submitted comment thread is still open (see step 10). On success `published`
247
+ submitted comment thread is still open (see step 9). On success `published`
256
248
  carries `rev` and `url`; the status becomes `awaiting-review`.
257
249
 
258
250
  Then open it for the reader, unless step 2 already did:
@@ -261,7 +253,7 @@ Then open it for the reader, unless step 2 already did:
261
253
  thurview open --review <id> # prints url; --view files|commits|map
262
254
  ```
263
255
 
264
- ### 8. Hand over
256
+ ### 7. Hand over
265
257
 
266
258
  Tell the user, in a few lines and nothing more:
267
259
 
@@ -271,8 +263,6 @@ Tell the user, in a few lines and nothing more:
271
263
  - the interface delta `verdict`, in its own words
272
264
  - the `security` verdict, in one clause: what the change crosses, or that it
273
265
  crosses nothing
274
- - which theme source you used: the user's request, the project's design
275
- system (name the files), or the default skin
276
266
  - when the review has no map, why not, in one clause
277
267
  - that you are now waiting for their questions and their decision, and that
278
268
  a question asked after you stop waiting is queued rather than lost - the
@@ -280,7 +270,7 @@ Tell the user, in a few lines and nothing more:
280
270
 
281
271
  The page explains its own controls; do not describe them.
282
272
 
283
- ### 9. Wait for the reader
273
+ ### 8. Wait for the reader
284
274
 
285
275
  ```sh
286
276
  thurview wait --review <id> --timeout <seconds>
@@ -307,14 +297,14 @@ worktree.
307
297
  not change the document for a question. Wait again.
308
298
  - `awaiting-agent-updates`: the reader submitted with "Request changes".
309
299
  `threads` lists what to address and `wait.decision` the summary. Go to
310
- step 10.
300
+ step 9.
311
301
  - `accepted`: approved. Report and stop.
312
302
  - `closed`: the reader ended the review without approving it. Report and stop.
313
303
  - `review-dismissed` or `review-deleted`: stop.
314
304
  - `timeout`: nothing happened. Wait again, or tell the user the reader has not
315
305
  responded and stop.
316
306
 
317
- ### 10. Address requested changes
307
+ ### 9. Address requested changes
318
308
 
319
309
  For each thread in `thurview threads list --review <id> --open`:
320
310
 
@@ -327,10 +317,29 @@ For each thread in `thurview threads list --review <id> --open`:
327
317
  - `thurview threads resolve <threadId> --review <id>` once the requested
328
318
  change is present. Do not resolve a thread you did not address.
329
319
 
330
- Then publish again (step 7), tell the user what changed since the previous
331
- revision in a line or two, and wait again (step 9). A republish requires zero
320
+ Then publish again (step 6), tell the user what changed since the previous
321
+ revision in a line or two, and wait again (step 8). A republish requires zero
332
322
  open submitted comment threads; questions do not block.
333
323
 
324
+ ## Sharing a copy that needs no server
325
+
326
+ When the user asks to share, export or publish the rendered page somewhere -
327
+ a file to send, a Pages site, a static host - write it from the published
328
+ revision:
329
+
330
+ ```sh
331
+ thurview export --review <id> --out <file.html | folder> # --no-threads
332
+ ```
333
+
334
+ It writes one self-contained HTML file (a folder gets `index.html`): the same
335
+ page, read only, with every snippet, diagram and diff resolved at the pins,
336
+ fetching nothing, naming no server and no local path. The reader's sent
337
+ threads and decisions appear as static notes; their unsent drafts never do.
338
+ Pass `--no-threads` when the copy goes beyond the people in the conversation.
339
+ It refuses a document with no published revision, and a copy does not update:
340
+ export again after each publish. Committing or uploading the file is the
341
+ user's step - name where it was written and leave it there unless asked.
342
+
334
343
  ## Explaining a codebase rather than a change
335
344
 
336
345
  Do not pin the same commit as base and head to fake it. That leaves a review
@@ -148,7 +148,6 @@ sequence diagram beats one with four.
148
148
 
149
149
  ## Files you edit
150
150
 
151
- Only `review.md`, `data.yaml`, `map.yaml` and `theme.yaml` in the review
152
- directory. Never
151
+ Only `review.md`, `data.yaml` and `map.yaml` in the review directory. Never
153
152
  edit `review.json`, `threads.json` or `revisions/`. Threads change only
154
153
  through `thurview threads`.
@@ -139,7 +139,6 @@ ${THURVIEW_HOME:-~/.thurview}/
139
139
  ├── review.md you edit
140
140
  ├── data.yaml you edit
141
141
  ├── map.yaml you edit
142
- ├── theme.yaml you edit (project look; empty = default skin)
143
142
  ├── review.json binding, pins, status, presented revision
144
143
  ├── threads.json threads and decisions (use the CLI)
145
144
  └── revisions/<n>/ sealed copies plus compiled document.json, map.json
@@ -75,11 +75,11 @@ Read the guidance files that exist, in this order; the second wins on conflict.
75
75
  `thurview design` lists the ones it found under `guidance`.
76
76
 
77
77
  The `thurview` skill ships the references this one shares — components,
78
- software map, theme, lifecycle. `thurview skill` prints the path of every
78
+ software map, lifecycle. `thurview skill` prints the path of every
79
79
  bundled SKILL.md; the references sit beside each one. Read **Components**
80
80
  before you edit `data.yaml`, **Software map** before you author `map.yaml`,
81
- **Theme** before you write `theme.yaml`, and **Lifecycle** for statuses,
82
- storage and thread rules — they are identical for all three kinds.
81
+ and **Lifecycle** for statuses, storage and thread rules — they are identical
82
+ for all three kinds.
83
83
 
84
84
  ## Workflow
85
85
 
@@ -213,10 +213,7 @@ The Map tab is where a design shows structure. Put the structure it
213
213
  A design that changes one part in place does not raise the question: leave
214
214
  `nodes: []` and say so in the handover.
215
215
 
216
- ### 6. Theme, then publish
217
-
218
- Write `theme.yaml` per the `thurview` skill's Theme reference, or leave it
219
- empty for the default skin. Then:
216
+ ### 6. Publish
220
217
 
221
218
  ```sh
222
219
  thurview publish --review <id>
@@ -230,6 +227,10 @@ reader sees above the document, and `published.url` is the page.
230
227
  thurview open --review <id>
231
228
  ```
232
229
 
230
+ To share it beyond the browser, `thurview export --review <id> --out <path>`
231
+ writes a static, read-only copy - see the `thurview` skill's **Sharing a copy
232
+ that needs no server**.
233
+
233
234
  ### 7. Hand over
234
235
 
235
236
  In a few lines, and nothing more: the `url`; the commit and scope it argues
@@ -62,12 +62,12 @@ Read the guidance files that exist, in this order; the second wins on conflict.
62
62
  `thurview explain` lists the ones it found under `guidance`.
63
63
 
64
64
  The `thurview` skill ships the references this one shares - document authoring,
65
- components, software map, searching the code, theme, lifecycle. `thurview skill` prints the path of
65
+ components, software map, searching the code, lifecycle. `thurview skill` prints the path of
66
66
  every bundled SKILL.md; the references sit beside each one. Read **Document
67
67
  authoring** before you write `review.md`, **Components** before you edit
68
68
  `data.yaml`, **Software map** before you author `map.yaml`, **Searching the
69
- code** before you look for callers, tests or importers, **Theme** before you
70
- write `theme.yaml`, and **Lifecycle** for statuses, storage and thread rules -
69
+ code** before you look for callers, tests or importers, and **Lifecycle** for
70
+ statuses, storage and thread rules -
71
71
  they are identical for all three kinds.
72
72
 
73
73
  Run the CLI as `thurview`; `npx -y thurview` runs the published package with
@@ -212,13 +212,15 @@ the code" - not a finding.
212
212
  `interfaces` in `data.yaml` is an error. So is `security`, which is what a
213
213
  change carries input across and an explainer has no change. So is
214
214
  `graph: base` on an anchor - there is one commit.
215
- 5. `theme.yaml` as usual - see **Theme**.
216
- 6. `thurview publish --review <id>`. Read `coverage` and `notExamined`. If the
215
+ 5. `thurview publish --review <id>`. Read `coverage` and `notExamined`. If the
217
216
  split is not the one you meant, anchor, place or search more and publish
218
217
  again.
219
- 7. `thurview open --review <id>`, then `thurview wait --review <id>`. The loop,
218
+ 6. `thurview open --review <id>`, then `thurview wait --review <id>`. The loop,
220
219
  the statuses and the thread rules are identical to a review; see
221
220
  **Lifecycle**.
221
+ 7. To share it beyond the browser, `thurview export --review <id> --out <path>`
222
+ writes a static, read-only copy - see the `thurview` skill's **Sharing a
223
+ copy that needs no server**.
222
224
 
223
225
  ## Hand over
224
226
 
package/dist/theme.js DELETED
@@ -1,290 +0,0 @@
1
- import { createHash } from "node:crypto";
2
- import { parse as parseYaml } from "yaml";
3
- import { z } from "zod";
4
- const color = z.string().min(1).max(64);
5
- export const ThemeSchema = z
6
- .object({
7
- name: z.string().min(1),
8
- /** where the tokens came from: files inspected in the project, or "default" */
9
- source: z.string().optional(),
10
- mode: z.enum(["dark", "light"]).default("dark"),
11
- colors: z
12
- .object({
13
- bg: color.optional(),
14
- bg2: color.optional(),
15
- bg3: color.optional(),
16
- code: color.optional(),
17
- fg: color.optional(),
18
- fg2: color.optional(),
19
- muted: color.optional(),
20
- line: color.optional(),
21
- accent: color.optional(),
22
- link: color.optional(),
23
- ok: color.optional(),
24
- warn: color.optional(),
25
- del: color.optional(),
26
- add: color.optional(),
27
- remove: color.optional(),
28
- select: color.optional(),
29
- })
30
- .strict()
31
- .prefault({}),
32
- fonts: z
33
- .object({
34
- display: z.string().optional(),
35
- body: z.string().optional(),
36
- mono: z.string().optional(),
37
- /** external stylesheets, e.g. Google Fonts css2 urls */
38
- stylesheets: z.array(z.string().url()).default([]),
39
- /** font files inside the reviewed repository at the head commit */
40
- files: z
41
- .array(z
42
- .object({
43
- family: z.string().min(1),
44
- path: z.string().min(1),
45
- weight: z.string().optional(),
46
- style: z.string().optional(),
47
- })
48
- .strict())
49
- .default([]),
50
- })
51
- .strict()
52
- .prefault({}),
53
- shape: z
54
- .object({
55
- radius: z.string().optional(),
56
- bevel: z.boolean().optional(),
57
- glow: z.boolean().optional(),
58
- scanlines: z.boolean().optional(),
59
- /** text-transform for display headings, e.g. none or uppercase */
60
- headingTransform: z.string().optional(),
61
- })
62
- .strict()
63
- .prefault({}),
64
- code: z
65
- .object({
66
- keyword: color.optional(),
67
- string: color.optional(),
68
- function: color.optional(),
69
- type: color.optional(),
70
- variable: color.optional(),
71
- number: color.optional(),
72
- comment: color.optional(),
73
- punctuation: color.optional(),
74
- operator: color.optional(),
75
- tag: color.optional(),
76
- fg: color.optional(),
77
- })
78
- .strict()
79
- .prefault({}),
80
- /** extra rules appended verbatim */
81
- css: z.string().optional(),
82
- })
83
- .strict();
84
- export function parseTheme(yaml) {
85
- const diagnostics = [];
86
- let raw;
87
- try {
88
- raw = parseYaml(yaml);
89
- }
90
- catch (e) {
91
- diagnostics.push({
92
- level: "error",
93
- file: "theme.yaml",
94
- message: `YAML: ${e.message}`,
95
- });
96
- return { theme: null, diagnostics };
97
- }
98
- if (raw === null || raw === undefined)
99
- return { theme: null, diagnostics };
100
- const r = ThemeSchema.safeParse(raw);
101
- if (!r.success) {
102
- for (const i of r.error.issues)
103
- diagnostics.push({
104
- level: "error",
105
- file: "theme.yaml",
106
- message: `${i.path.join(".") || "root"}: ${i.message}`,
107
- });
108
- return { theme: null, diagnostics };
109
- }
110
- return { theme: r.data, diagnostics };
111
- }
112
- const DEFAULT_CODE = {
113
- fg: "#e6e8eb",
114
- keyword: "#ff7b72",
115
- string: "#a5d6ff",
116
- function: "#d2a8ff",
117
- type: "#ffa657",
118
- variable: "#79c0ff",
119
- number: "#79c0ff",
120
- comment: "#8b949e",
121
- punctuation: "#8b949e",
122
- operator: "#ff7b72",
123
- tag: "#7ee787",
124
- };
125
- const DEFAULT_CODE_BG = "#0b0d10";
126
- export function shikiTheme(name, code, mode, bg = DEFAULT_CODE_BG) {
127
- const c = { ...DEFAULT_CODE, ...code };
128
- return {
129
- name,
130
- type: mode,
131
- colors: { "editor.background": bg, "editor.foreground": c.fg },
132
- tokenColors: [
133
- {
134
- scope: ["comment", "punctuation.definition.comment", "string.comment"],
135
- settings: { foreground: c.comment, fontStyle: "italic" },
136
- },
137
- {
138
- scope: ["punctuation", "meta.brace", "punctuation.separator", "punctuation.terminator"],
139
- settings: { foreground: c.punctuation },
140
- },
141
- {
142
- scope: [
143
- "keyword",
144
- "storage",
145
- "storage.type",
146
- "storage.modifier",
147
- "keyword.control",
148
- "constant.language",
149
- "variable.language",
150
- ],
151
- settings: { foreground: c.keyword },
152
- },
153
- {
154
- scope: ["keyword.operator", "keyword.operator.assignment", "keyword.operator.arrow"],
155
- settings: { foreground: c.operator },
156
- },
157
- {
158
- scope: [
159
- "string",
160
- "string.quoted",
161
- "string.template",
162
- "punctuation.definition.string",
163
- "markup.inserted",
164
- ],
165
- settings: { foreground: c.string },
166
- },
167
- {
168
- scope: [
169
- "entity.name.function",
170
- "support.function",
171
- "meta.function-call entity.name.function",
172
- ],
173
- settings: { foreground: c.function },
174
- },
175
- {
176
- scope: [
177
- "entity.name.type",
178
- "entity.name.class",
179
- "support.class",
180
- "support.type",
181
- "entity.other.inherited-class",
182
- "entity.name.namespace",
183
- ],
184
- settings: { foreground: c.type },
185
- },
186
- {
187
- scope: [
188
- "constant.numeric",
189
- "constant.character",
190
- "constant.other",
191
- "constant.language.boolean",
192
- ],
193
- settings: { foreground: c.number },
194
- },
195
- {
196
- scope: [
197
- "entity.name.tag",
198
- "support.type.property-name",
199
- "meta.object-literal.key",
200
- "entity.other.attribute-name",
201
- "meta.property-name",
202
- ],
203
- settings: { foreground: c.tag },
204
- },
205
- {
206
- scope: [
207
- "variable",
208
- "variable.parameter",
209
- "variable.other",
210
- "meta.definition.variable",
211
- "entity.name.variable",
212
- ],
213
- settings: { foreground: c.variable },
214
- },
215
- { scope: ["markup.deleted"], settings: { foreground: c.operator } },
216
- {
217
- scope: ["markup.heading", "entity.name.section"],
218
- settings: { foreground: c.tag, fontStyle: "bold" },
219
- },
220
- { scope: ["markup.bold"], settings: { fontStyle: "bold" } },
221
- { scope: ["markup.italic"], settings: { fontStyle: "italic" } },
222
- ],
223
- };
224
- }
225
- /** Build the stylesheet and highlighter theme for a review. `blobUrl` maps a repo path to a served url. */
226
- export function compileTheme(theme, blobUrl) {
227
- const hash = createHash("sha1").update(JSON.stringify(theme)).digest("hex").slice(0, 8);
228
- const name = `theme-${hash}`;
229
- const v = [];
230
- const c = theme.colors;
231
- const map = {
232
- "--bg": c.bg,
233
- "--bg2": c.bg2,
234
- "--bg3": c.bg3,
235
- "--bg-code": c.code,
236
- "--fg": c.fg,
237
- "--fg2": c.fg2,
238
- "--muted": c.muted,
239
- "--line": c.line,
240
- "--line2": c.line,
241
- "--accent": c.accent,
242
- "--link": c.link,
243
- "--ok": c.ok,
244
- "--warn": c.warn,
245
- "--del": c.del,
246
- "--font-display": theme.fonts.display,
247
- "--font-body": theme.fonts.body,
248
- "--font-mono": theme.fonts.mono,
249
- "--radius": theme.shape.radius,
250
- "--heading-transform": theme.shape.headingTransform,
251
- };
252
- for (const [k, val] of Object.entries(map))
253
- if (val)
254
- v.push(`${k}: ${val};`);
255
- if (c.add)
256
- v.push(`--add-bg: ${c.add};`);
257
- if (c.remove)
258
- v.push(`--del-bg: ${c.remove};`);
259
- if (c.select)
260
- v.push(`--sel: ${c.select};`);
261
- if (c.accent)
262
- v.push(`--accent-bg: color-mix(in srgb, ${c.accent} 16%, transparent);`);
263
- if (theme.mode === "light")
264
- v.push("color-scheme: light; --shadow: 0 1px 2px rgb(0 0 0 / 0.08); --shadow-lg: 0 12px 32px rgb(0 0 0 / 0.14);");
265
- // retro options, each off in the default skin
266
- if (theme.shape.glow)
267
- v.push("--glow: 0 0 5px color-mix(in srgb, var(--accent) 70%, transparent), 0 0 12px color-mix(in srgb, var(--accent) 40%, transparent);");
268
- if (theme.shape.bevel)
269
- v.push("--shadow: 0 0 0 1px rgb(0 0 0 / 0.6), inset 1px 1px 0 0 rgb(255 255 255 / 0.14), inset -1px -1px 0 0 rgb(0 0 0 / 0.6);");
270
- const out = [];
271
- for (const s of theme.fonts.stylesheets)
272
- out.push(`@import url("${s}");`);
273
- for (const f of theme.fonts.files) {
274
- const ext = f.path.split(".").pop()?.toLowerCase() ?? "";
275
- const fmt = ext === "woff2" ? "woff2" : ext === "woff" ? "woff" : ext === "otf" ? "opentype" : "truetype";
276
- out.push(`@font-face { font-family: "${f.family}"; src: url("${blobUrl(f.path)}") format("${fmt}"); font-weight: ${f.weight ?? "400"}; font-style: ${f.style ?? "normal"}; font-display: swap; }`);
277
- }
278
- out.push(`:root { ${v.join(" ")} }`);
279
- if (theme.shape.scanlines)
280
- out.push("body::after { content: ''; position: fixed; inset: 0; z-index: 9999; pointer-events: none; background: repeating-linear-gradient(to bottom, transparent 0, transparent 2px, rgb(0 0 0 / 0.1) 2px, rgb(0 0 0 / 0.1) 3px); mix-blend-mode: multiply; }");
281
- if (theme.css)
282
- out.push(theme.css);
283
- return {
284
- name: theme.name,
285
- ...(theme.source ? { source: theme.source } : {}),
286
- css: out.join("\n"),
287
- shiki: shikiTheme(name, theme.code, theme.mode, c.code ?? (theme.mode === "light" ? "#ffffff" : DEFAULT_CODE_BG)),
288
- };
289
- }
290
- //# sourceMappingURL=theme.js.map
package/dist/theme.js.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"file":"theme.js","sourceRoot":"","sources":["../src/theme.ts"],"names":[],"mappings":"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"}
@@ -1,89 +0,0 @@
1
- # Theme
2
-
3
- A review looks like the project it reviews. `theme.yaml` in the review
4
- directory carries the tokens; `publish` validates it and seals it with the
5
- revision. An empty or absent file gives the default skin.
6
-
7
- ## Decide the look, in this order
8
-
9
- Move to the next step only when the current one yields nothing.
10
-
11
- 1. The user asked for a specific look or named a design system: use that.
12
- 2. Inspect the reviewed project at the head commit and match its own design
13
- system: a Tailwind or theme config, CSS custom properties or design
14
- tokens, a component library theme, brand assets, an existing styled page
15
- or website directory, font files it ships. Read the real values; do not
16
- guess. Record what you read in `source`.
17
- 3. Nothing found: keep the default skin. Do not invent a palette.
18
-
19
- State which of the three you used when you hand over the review.
20
-
21
- ## theme.yaml
22
-
23
- ```yaml
24
- name: acme-web # shown in the review menu
25
- source: tailwind.config.ts, src/styles/tokens.css
26
- mode: light # dark (default) or light
27
-
28
- colors: # any CSS color; every key optional
29
- bg: "#ffffff" # page
30
- bg2: "#f6f7f9" # panels, bars
31
- bg3: "#eef0f3" # hover
32
- code: "#f8fafc" # code surfaces
33
- fg: "#111827" # text
34
- fg2: "#4b5563" # secondary text
35
- muted: "#9ca3af"
36
- line: "#e5e7eb" # borders
37
- accent: "#2563eb" # headings, primary actions, status
38
- link: "#2563eb" # links and anchor links
39
- ok: "#16a34a"
40
- warn: "#d97706"
41
- del: "#dc2626"
42
- add: "rgb(22 163 74 / .12)" # added-line background
43
- remove: "rgb(220 38 38 / .12)" # deleted-line background
44
- select: "rgb(217 119 6 / .18)" # highlighted-line background
45
-
46
- fonts:
47
- display: "Inter, sans-serif" # brand, buttons, document headings
48
- body: "Inter, sans-serif"
49
- mono: "'JetBrains Mono', monospace"
50
- stylesheets: # external font css, loaded by the page
51
- - https://fonts.googleapis.com/css2?family=Inter:wght@400;700&display=swap
52
- files: # font files the project ships, read at head
53
- - { family: Acme Sans, path: web/public/fonts/acme-sans.woff2, weight: "400 700" }
54
-
55
- shape:
56
- radius: 8px # 6px in the default skin
57
- headingTransform: none # none in the default skin
58
- bevel: true # retro extras, all off unless set: pixel
59
- glow: true # bevels on panels, neon glow on headings
60
- scanlines: true # and tabs, a CRT overlay
61
-
62
- code: # syntax palette; any key optional
63
- keyword: "#7c3aed"
64
- string: "#15803d"
65
- function: "#b45309"
66
- type: "#b45309"
67
- variable: "#0369a1"
68
- number: "#b45309"
69
- comment: "#9ca3af"
70
- punctuation: "#6b7280"
71
- operator: "#374151"
72
- tag: "#be185d"
73
- fg: "#111827"
74
-
75
- css: | # optional extra rules, appended last
76
- .doc h1 { letter-spacing: 0; }
77
- ```
78
-
79
- Rules:
80
-
81
- - Keep contrast readable: body text against `bg`, code against `code`.
82
- - A light project gets `mode: light` and light backgrounds; the default skin
83
- is dark and neutral, with one blue accent.
84
- - `fonts.files` paths must exist at the pinned head commit; `publish`
85
- rejects a missing one. Font stylesheets are fetched by the reader's
86
- browser.
87
- - Map the project's semantic roles, not its whole palette: primary to
88
- `accent` and `link`, success/warning/danger to `ok`/`warn`/`del`.
89
- - Unknown keys fail validation.