gp-dimm-city 1.0.1 → 1.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -7,6 +7,337 @@ cut a version that has no `## [X.Y.Z]` heading below.
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [1.1.1] - 2026-10-08
11
+
12
+ **Notes for books upgrading from 1.1.0:**
13
+
14
+ - A learning-path banner is now an `h3` (was `h2`), and a skill's title an
15
+ `h4` (was a `span`). A book stylesheet that targets `h2.dc-spray` or
16
+ `span.dc-tab-title` needs the new tag.
17
+ - Unused components were removed; check `docs/cleanup-backlog.md` and the
18
+ Removed list below before relying on any of them.
19
+ - Tested against gutterpress 0.11.15-alpha.1, whose `dtrpg` preset now
20
+ does the DriveThruRPG blank last page and K-only black text.
21
+
22
+ ### Added
23
+
24
+ - **Heading look classes `.dc-h3`–`.dc-h6`.** A heading keeps its outline
25
+ level and takes another level's look (`## Useful Items {.dc-h3}`), so a
26
+ book can stop skipping levels to get a smaller label: gutterpress flags
27
+ every skip. The section header bar and the in-section accent rule follow
28
+ the class, not the tag. On a paragraph, the class sets a line in
29
+ heading type outside the outline. The Field Guide's 13 skipped levels
30
+ are fixed this way and render pixel-identical. Documented in the
31
+ design guide's Typography chapter (Level and look).
32
+
33
+ ### Changed
34
+
35
+ - **Tested against gutterpress 0.11.15-alpha.1** (devDependency, was
36
+ 0.11.13), the release that upstreams this package's two DriveThruRPG
37
+ workarounds: `preset: dtrpg` now pads to a 4-page signature and always
38
+ ends on a blank reserved page (`print.reserveLastPage`,
39
+ dimm-city/gutterpress#332), and prints near-black text on the black plate
40
+ only in PDF/X builds (`pdfx.blackText: k-only`, dimm-city/gutterpress#331).
41
+ Verified on the Field Guide with the alpha: its 228 content pages render
42
+ pixel-identical to 0.11.13, and without any workaround the book ends on
43
+ 4 pure-white pages (232). The design guide's Publishing chapter documents
44
+ both settings.
45
+ - **Specialty chapters nest in the outline.** A learning path's title was
46
+ emitted as an `h2`, the same level as the specialty name, and a skill's
47
+ title as a plain `span`, so the app's contents panel and the PDF
48
+ bookmarks listed every skill tree beside its specialty and no skills at
49
+ all. The plugin now emits the heading levels the markdown is written
50
+ at: specialty (`##`) > learning path (`h3.dc-spray`) > skill
51
+ (`h4.dc-tab-title`). The CSS follows, and both books render
52
+ pixel-identical. A stylesheet that targeted `h2.dc-spray` or
53
+ `span.dc-tab-title` needs the new tag. A real space
54
+ (`span.dc-path-sep`, carrying the 10px gap the sticker's margin used to
55
+ give) separates a banner's tree code from its title, so the outline
56
+ reads "PRX1 Refuse Finality", not "PRX1Refuse Finality".
57
+
58
+ ### Fixed
59
+
60
+ - **DriveThruRPG PDF/X builds keep live text.** The brick wall was an RGBA
61
+ tile blended with `background-blend-mode: multiply`, so every walled page
62
+ carried transparency, which PDF/X-1a cannot represent: Ghostscript
63
+ flattened each one to a raster image — no live text or embedded fonts
64
+ (a one-page book failed validation outright), and black text left
65
+ four-colour, because `pdfx.blackText: k-only` only reaches vector text.
66
+ The wall is now `images/brick-wall.png`, the same tile multiplied into
67
+ `--bg` and flattened to an opaque image, painted with no blend mode:
68
+ it renders the same (design guide wall pages differ by 0.15/255 on
69
+ average), and with gutterpress 0.11.15-alpha.1 a DriveThruRPG build's
70
+ body text now prints on the black plate only (separations: C = M = Y = 0
71
+ under every glyph). A book that retints `--bg` no longer tints the
72
+ brick; see the note in `dc-native.css` for baking a tile.
73
+ - **Nothing in the package paints transparent.** The 25 other uses of
74
+ transparency — semi-transparent shadows, tinted fills, `opacity` on
75
+ stickers, rules, the tape dashes and the pull-quote mark — each flattened
76
+ their page in PDF/X-1a just as the wall did. Each is now pre-composited
77
+ with `color-mix()` onto the surface it sits on, so it prints the same
78
+ colour, opaque. Shadows on the wall mix against the new `--wall-tone`
79
+ (`#c1beb8`, the tile's measured mean). Measured on both books: layout and
80
+ page counts unchanged, and no page changes more than 0.7% of its pixels.
81
+ The AP chip loses its soft 6px blurred shadow, which has no opaque form,
82
+ and keeps its hard one. Every change, with where to look, is in
83
+ `docs/print-transparency-inventory.md`. A new convention test fails on
84
+ any transparency in the stylesheets, with no exemptions (the one
85
+ translucent holdout, the unused cover-page composite, was removed).
86
+
87
+ - **No stray ink line across the folio row.** A skill card, learning-path
88
+ banner or specialty intro that opened a page printed the top 2–4px of its
89
+ outline at the foot of the PREVIOUS page: a full-width black (or accent)
90
+ line between the folio and chapter chips. The outlines reached above
91
+ their component's box (`top: -4px`, `translateY(-2px)`), and Chromium
92
+ fragments that part onto the page before. Each outline now sits inside
93
+ its own box: the card starts 4px higher and pads its tab 4px down
94
+ (`padding-top: 4px; margin-top: -4px`), the banner 2px likewise, and
95
+ the intro pads its content 2px. Mid-page nothing moves; a component that
96
+ opens a page sits 2–4px lower. Measured: the line is gone from all 17 Field Guide pages and
97
+ the 1 design guide page that had it; page counts are unchanged (232, 132) and
98
+ no text changes page. (It became visible with 1.1.0's DriveThruRPG
99
+ margins, which moved the page breaks; the cause dates from 1.0.0.)
100
+
101
+ - **Accent rails print as vectors in PDF/X.** The 3–5px coloured rail down
102
+ the left of sections, ledes, path banners, the Panel and Shard blocks,
103
+ and the front-matter and intro panels was a hard-stop
104
+ `linear-gradient`. The PDF/X conversion turned each gradient into a
105
+ 45 ppi bitmap, so the rail's edge printed soft, and
106
+ `gutterpress preflight` flagged the pages as low-resolution. Each rail
107
+ is now an inset `box-shadow` over a flat fill: it looks the same and
108
+ prints as a vector.
109
+ - **Design guide: preflight checks the right page size.** Its manifest
110
+ declared 612 × 792 pt (the bare Letter trim), so `gutterpress preflight`
111
+ failed every build on page size. It now declares the sheet the CSS
112
+ prints: 621 × 810 pt, the trim plus DriveThruRPG's bleed.
113
+
114
+ - **`.gp-columns-flow` works.** Core declares it in its own layer, which
115
+ this package's `column-fill: balance` on every `.gp-columns-2/-3`
116
+ outranked, so a run marked to flow stayed balanced. The balance rule now
117
+ skips runs marked `.gp-columns-flow`.
118
+
119
+ - **Catalog statuses.** `plain`, `img-float`, `full-page` and
120
+ `printer-page` were marked `unused` although a book uses each: the
121
+ design guide renders the first two, SysOps uses `full-page`, and the
122
+ Field Guide still ends on `@page .dc-printer-page` until it builds on a
123
+ stable gutterpress 0.11.15. They are `live` now.
124
+ ### Removed
125
+
126
+ - `images/brick-bg-01.png`, the RGBA wall tile, is no longer published
127
+ (it now lives in the repository's `source-art/`). Neither Dimm City book
128
+ referenced it; a book that did should use `images/brick-wall.png`.
129
+ - **Dead styling, from an orphan audit of the package, the design guide and
130
+ the Field Guide.** Each item was used by no book (Field Guide, Design
131
+ Guide, SysOps), and both books render pixel-identical without it:
132
+ - components: the cover-page composite (`.dc-cover-*`, with
133
+ `--dc-cover-meta-border`), the contents-page rows (`.dc-toc-row/-no/
134
+ -title/-page`), `.dc-portrait` (with `--dc-portrait-*`), the roll badges
135
+ `.dc-roll-lucid/-surreal` (with their colour tokens), `.dc-path-subtitle`,
136
+ the glossary item `.dc-terms .dc-item` (with `--card-border-color`),
137
+ `.dc-dashed-rule`, `.dc-tape.dc-margin-sm`, `.dc-sidebar-box-divider`,
138
+ `.dc-outcome-table` and `.dc-callout`. Their catalog entries are now
139
+ `retired`.
140
+ - rules for markup the plugin no longer produces: `.dc-sticker.active`,
141
+ the `ol`/`li` rules under `.dc-ability` (abilities are no longer
142
+ lists), and `h5` and `ol > li` inside a two-column skill card (both
143
+ are converted before they get there).
144
+ - stale comments naming deleted files or classes (`dc-tokens-print.css`,
145
+ `components.css`, `tokens.css`, the `.pmd-*` utilities, `.dc-accent-X`,
146
+ old design-guide chapter names, undeclared tokens).
147
+ Styling the audit found unused but still reachable is listed in
148
+ `docs/cleanup-backlog.md` for review.
149
+
150
+ ### Deprecated
151
+
152
+ - **`@page .dc-printer-page`.** gutterpress 0.11.15+ reserves the blank
153
+ last page in core. The class still works — a book that keeps it gets one
154
+ printer page plus padding, still ending blank — and goes in the next
155
+ major.
156
+
157
+ ## [1.1.0] - 2026-10-07
158
+
159
+ **Layout note for books upgrading from 1.0.x:** the page margins now follow
160
+ DriveThruRPG's print specification (text at least 0.5in inside the trim),
161
+ which takes 0.25in off every page and reflows the whole book. Build and
162
+ review your book after upgrading; the Field Guide needed a short layout
163
+ pass (see `dc-op-manual`, branch `design/plugin-updates`). DriveThruRPG
164
+ books should also end with `@page .dc-printer-page` and set
165
+ `print: signature: 4` in `manifest.yaml`.
166
+
167
+ ### Added
168
+
169
+ - **`@page .dc-printer-page`**, a completely blank last page (no wall, no
170
+ footer). DriveThruRPG reserves a book's final page for printer
171
+ information: the interior must be one page short of its signature (4 for
172
+ US Letter) or end on a blank page. End the last chapter with this marker
173
+ and set `print: signature: 4` in the manifest — gutterpress pads with
174
+ blank pages to the next multiple of 4 — and the book always ends blank.
175
+ Verified in the Field Guide (228 content pages + 4 blank = 232).
176
+ - **Variant Gallery** (design guide chapter 11): every element with more than
177
+ one variant, its variants on one stage — all ten skill trees (each
178
+ specialty's first learning path with one skill card, Field Guide content
179
+ excerpted), the skill-card switches (tier override, both highlight forms,
180
+ two columns, outcome table), every AP chip, the ten specialty intros and
181
+ cards, class tags, alerts, blocks, choice cards, and the flush, heading,
182
+ section, sidebar and image-float variants.
183
+ - **The design guide lives here.** `design-guide/` is the Dimm City Design
184
+ Guide book, moved from `dimm-city/dc-op-manual`. Its manifest loads the
185
+ package from this checkout (`extensions: - ../`), so it documents and
186
+ renders the working copy: `npm run dev` previews it, `npm run build`
187
+ renders the PDF, and the test suite uses it as the fixture
188
+ (`test/design-guide.test.js`: every chapter renders clean, every macro and
189
+ alert type is demonstrated, and each chapter's HTML is snapshotted under
190
+ `test/__snapshots__/`). CI builds the PDF with the PR's plugin and CSS and
191
+ uploads it; the release workflow attaches it to the GitHub release; a
192
+ *Publish design guide* workflow deploys the HTML build to GitHub Pages.
193
+ - **`@glossary` is demonstrated** in the component gallery, which used raw
194
+ HTML for the term-list specimen before.
195
+
196
+ ### Changed
197
+
198
+ - **Page margins follow DriveThruRPG's print specification.** Its
199
+ [Quick Specifications for Print Books](https://help.drivethrupartners.com/hc/en-us/articles/12780800178583-Quick-Specifications-for-Print-Books)
200
+ require all text at least 0.5in inside the trim. The bleed (0.125in on
201
+ the three outside edges, none at the spine) and the outside and binding
202
+ margins already complied; the top did not (0.375in from the trim) and
203
+ neither did the footer chips (0.43in). Top margin 0.5in → 0.625in on the
204
+ sheet (0.5in from the trim); bottom 0.75in → 0.875in, as the new
205
+ `--bottom-margin` token, so the chips print 0.55in from the trim. The
206
+ "Citizen File" running head, which printed 0.1in from the trim, sits at
207
+ the foot of a 0.875in top margin. Footer chips re-homed by a `.gp-flush`
208
+ pin are top-aligned like native ones (gutterpress centres them, which put
209
+ them 0.24in from the trim). A card title too long for its card breaks
210
+ rather than running into the margin. **This reflows every book:** the
211
+ Field Guide goes from 221 to 238 pages and now has no text inside 0.5in
212
+ of the trim (it had 1,273 words on 204 pages); the design guide goes from
213
+ 126 to 131.
214
+ - **Design guide: explainer pages print plain, specimens sit on the wall.**
215
+ Part 1 pages (and the Part 2 overview) are `@page .dg-doc`, a named page
216
+ with a white background and neutral headings, tables and contents, so guide
217
+ text can't be mistaken for a component. Each rendered result is wrapped in
218
+ a framed `.dg-stage` that carries the brick wall; whole-page specimens and
219
+ the Part 2 example pages keep the full brick page. Chapter ledes, the
220
+ contents lists, and the explainer notes and column panels that used
221
+ package components are now plain guide markup. All of this lives in
222
+ `design-guide/` (markdown and `styles/guide.css`); the package is unchanged.
223
+ - **Design guide: print-design review pass.** Readability and finish fixes
224
+ from a review against the print-quality rubrics, all in `design-guide/`:
225
+ - Code boxes are set in IBM Plex Mono (OFL, bundled in
226
+ `design-guide/fonts/ibm-plex-mono/`), 9pt on 1.4 leading, without the
227
+ doubled blank lines; fences of 20+ lines may split across pages.
228
+ - Guide text is capped at a 5.1in measure (about 65–70 characters) on 1.4
229
+ leading; tables are 10pt and may run across pages.
230
+ - Chapters open with a "Chapter N" label; H1 26pt, H3 13pt. Doc pages
231
+ carry a plain running foot (folio and chapter title); the contents list
232
+ has page numbers; Part 2 has a title page and E.1–E.6 chapter badges.
233
+ - YOU WRITE / RESULT labels are 8pt; YOU WRITE is cream on blood (7.7:1).
234
+ - Specimen stages stay whole unless marked `dg-tall`; prose specimens sit
235
+ on paper (`dg-on-paper`); two Do/Don't pairs (flavor in bold italic,
236
+ body text on bare wall).
237
+ - Typeface specimens for lixdu, Titillium Web and Tomorrow; palette
238
+ swatches are 1in and each carries a CMYK build from the CGATS21_CRPC1
239
+ profile (the hand-entered four-row CMYK table is replaced).
240
+ - Fixed: the type-scale table listed H1–H4 at stale sizes; the guide's
241
+ inline-code style leaked into the Part 2 examples (invisible text on a
242
+ dark callout), and its `hr` rule replaced the package's dashed rule in
243
+ the specimen; the inset-sidebar and art-plate specimens no longer leave
244
+ a RESULT tab stranded at a page foot.
245
+ - **Tests run against gutterpress 0.11.13** (devDependency, was 0.10.11).
246
+ - **`test/fixtures/all-macros.md` and its snapshot are gone**; the design
247
+ guide is the fixture. `npm run test:update-snapshot` is now bun's own
248
+ `--update-snapshots`; `scripts/update-snapshot.mjs` is removed.
249
+
250
+ ### Fixed
251
+
252
+ - **No blank page after a two-column page that ends in a spanner.** A
253
+ `@page .gp-columns-2` page ending in a full-width section printed an
254
+ extra blank page under the DriveThruRPG margins (Field Guide: Quickstart
255
+ vs. Deep Dive): the section's bottom margin pushed the page box past its
256
+ one-sheet minimum. A multicol page's last child has no bottom margin.
257
+ Design guide unchanged; Field Guide loses the blank page.
258
+ - **The introduction page keeps the normal margins.** `.page-intro` shared
259
+ the `front-matter` named page with the Contents and Credits, whose side
260
+ and bottom margins are zeroed for their full-bleed masthead — so the
261
+ intro's chevron, lede and section sat flush on the sheet edge. It has its
262
+ own named page now, `front-matter-intro`: default margins, no footers.
263
+ The Field Guide writes its introduction as a plain `@page` and is
264
+ unaffected.
265
+ - **No more pages printed as images.** `filter: drop-shadow()` on the
266
+ intro page and on the labelled chapter-opener page made Chromium print
267
+ each of those pages as one 300ppi bitmap with a soft mask: no live text,
268
+ and a transparency mask PDF/X-1a forbids. Both shadows are vector now
269
+ (box-shadow on the lede, section and opener badge; the opener section's
270
+ own clipped `::after`). Design guide: 8 pages regain live text. The
271
+ Field Guide uses neither and is unaffected.
272
+ - **No hairline across the page after the credits.** The colophon fills to
273
+ the sheet's bottom edge, so its poster shadow's 3pt drop overflowed the
274
+ sheet and printed as a line across the top of the next page — over the
275
+ Field Guide's Contents masthead. The colophon keeps the shadow's side
276
+ offset and drops the downward one. (Clipping the page was rejected: it
277
+ would also clip a pinned or bleed plate.) Field Guide: p.2 loses the
278
+ line, and p.1 shows the colophon's side shadow starting level with its
279
+ top; nothing else changes.
280
+ - **Specialty art plates print full bleed.** The `.page` overflow guard
281
+ (page-templates.css) exempted pages holding `.gp-bleed`/`.gp-pin` art but
282
+ not `.dc-specialty-art` or `.dc-full-page`, so a plate on a page with no
283
+ other pinned art was cut at the text column — a 100pt strip of bare wall
284
+ down its outside edge (design guide p.45, p.105). The Field Guide's
285
+ plates were full width only because its specialty pages also carry
286
+ pinned art. Field Guide unchanged.
287
+ - **A long standalone banner title keeps its skew tab inside the margin.**
288
+ `.dc-spray`'s `::before` tab overhangs its right edge by 18px; a title
289
+ that filled its column pushed the tab past the margin, which is print
290
+ shrink-to-fit for the whole book once the page does not clip (found by
291
+ the build's width audit after the plate fix). Standalone banners cap at
292
+ the column less the tab; learning-path banners, which span their shell
293
+ with the tab pulled inside, are exempt. Field Guide unchanged.
294
+ - **A learning-path banner stays with its first card.** The shell is never
295
+ split and keeps with the next card, and the first path after a
296
+ specialty's art page drops its 8px top margin — moved into the package
297
+ from the Field Guide's own sheet, which measured both. Without them the
298
+ design guide printed the Biting Distance banner alone, with the edge of
299
+ the first card's tab at the page foot. The package's `break-before:
300
+ always` on `.dc-learning-path` is not a value Chromium supports and does
301
+ nothing; it is left as is (making it valid would put every path on a new
302
+ page). Field Guide unchanged.
303
+ - **A credits page that overflows no longer prints under the next page.**
304
+ `.page.page-credits` had an exact one-sheet `height`; when its colophon
305
+ did not fit, the colophon moved to a second sheet but the page box stayed
306
+ one sheet tall, so the following page started on that same sheet and was
307
+ painted over it (design guide: the Introduction over the colophon). It is
308
+ a `min-height` now: a page that fits is still exactly one sheet, so the
309
+ pinned plate still seats on the sheet edge, and the Field Guide renders
310
+ pixel-identical. The design guide's credits example also pins its plate
311
+ like the Field Guide's (`.gp-pin .gp-bottom .gp-full`) instead of placing
312
+ it in the colophon, which is what had made it overflow.
313
+ - **Variable AP chips print as variable.** The plugin emitted
314
+ `.dc-ap.variable` but the CSS only styled `.dc-ap.var`, and a `VAR AP`
315
+ cost got no variable class at all. Both spellings are styled now, and
316
+ `VAR` is detected alongside ranges and `X`. Visible change in the Field
317
+ Guide: 13 pages, each a range-cost chip (`2-X AP` and the like) turning
318
+ from standard blue to variable magenta; no layout change.
319
+ - **Short two-column runs no longer print full-page height.** `dc-native.css`
320
+ §10b set `column-fill: auto` on every `.gp-columns-*` run; with no fixed
321
+ height that fills the first column to the page foot, so a short column
322
+ panel became a full-height box with an empty right column, and a heading
323
+ above one was stranded alone when the box could not fit under it. The
324
+ rule is `balance` again, and the two per-shape `balance` exceptions it
325
+ made redundant are removed. A run that needs sequential fill opts in with
326
+ core's `.gp-columns-flow`. The Field Guide's 221 pages render
327
+ pixel-identical before and after.
328
+ - **A lede never splits** (`.dc-intro { break-inside: avoid }`), and the
329
+ section after a lede may start a new page. Core glues every section to
330
+ what precedes it, which chained heading → lede → section; when the section
331
+ could not fit, the lede split and painted an empty panel to the page foot.
332
+ - **`@sidebar .inset` with a single paragraph** set that paragraph in
333
+ centred display caps: the rail's closing-line rule matched it as the last
334
+ child. It now applies only from the second paragraph on. The inset rail
335
+ also keeps the sidebar's paper surface instead of a transparent one that
336
+ put its text on the brick wall.
337
+ - Two design guide chapters (`303`, `306`) closed `@procedure` on the line
338
+ right after a list item, which markdown folds into that item, so the
339
+ marker never closed and the chapter rendered with a layout warning.
340
+
10
341
  ## [1.0.1] - 2026-09-25
11
342
 
12
343
  ### Changed
package/README.md CHANGED
@@ -137,19 +137,59 @@ artwork and game text are not licensed by this package.
137
137
 
138
138
  ## Development
139
139
 
140
+ The short how-to is [docs/developing.md](./docs/developing.md): the edit → preview → test → release loop, in web-dev terms.
141
+
142
+ Everything you need to change the package and see the result is in this
143
+ repository: the plugin, the stylesheets, and `design-guide/` — the Dimm City
144
+ Design Guide, a Gutterpress book that documents every macro, token, component
145
+ and page template by rendering it. The guide's manifest loads the package from
146
+ this checkout (`extensions: - ../`), not from npm, so it is both the public
147
+ documentation and the test fixture: what it shows is what the working copy
148
+ renders.
149
+
140
150
  ```sh
141
151
  bun install
142
- bun test # snapshot, behaviour, package and convention tests
143
- bun run test:update-snapshot # only when the plugin's output is meant to change
144
- bun run pack:check # what npm would publish
152
+ npm run dev # live preview of the design guide, opens the browser
153
+ npm run build # lint + validate + render .build/design-guide.pdf (needs Chrome 148+)
154
+ npm run build:html # the guide as a static site, .build/design-guide-site/
155
+ bun test # plugin behaviour, design-guide render + snapshot, package, conventions
156
+ npm run test:update-snapshot # only when the plugin's output is meant to change
157
+ npm run pack:check # what npm would publish
145
158
  ```
146
159
 
147
- `plugin.js` imports nothing at runtime — `gutterpress/render` is a
148
- devDependency used only by the tests to run the plugin inside core's markdown
149
- pipeline. Releases are cut from the *Release* workflow (version in, npm and
150
- GitHub release out); it refuses a version with no `## [X.Y.Z]` heading in
151
- `CHANGELOG.md`.
152
-
153
- The design guide that documents this system in depth is a book in the
154
- `dimm-city/dc-op-manual` repository. Issues about the package — a macro, a
155
- sheet, a token, a font — belong here.
160
+ The loop is the usual web one. `npm run dev` runs `gutterpress preview
161
+ design-guide`: edit `plugin.js`, a sheet under `styles/`, a font or the brick
162
+ tile, or any chapter of the guide, and the preview re-renders (the CLI lists
163
+ each watched file as it starts). The Gutterpress desktop app does the same —
164
+ open the `design-guide/` folder in it. `npm run build` is the PDF the
165
+ reader gets; it runs Gutterpress's print-safety lint and source/PDF
166
+ validation and fails on an error. Set `CHROMIUM_PATH` if your Chrome is not
167
+ on a standard path.
168
+
169
+ The tests (`bun test`) are the CI gate:
170
+
171
+ - `test/design-guide.test.js` — every chapter renders through Gutterpress's
172
+ pipeline with no layout warning and no marker left unrendered; every macro
173
+ and alert type the plugin handles appears in the guide; each chapter's HTML
174
+ matches `test/__snapshots__/`. A change to the plugin's output fails here
175
+ until you run `npm run test:update-snapshot` and review the snapshot diff
176
+ with the code.
177
+ - `test/plugin.test.js` — the loader contract and the behavioural edge cases.
178
+ - `test/package.test.js` — the tarball `npm publish` would ship: every
179
+ declared path, every `url()` asset, one licence per font directory, the
180
+ cascade contract.
181
+ - `test/conventions.test.js` — one prefix (`dc-`), no runtime imports, only
182
+ allow-listed core hooks.
183
+
184
+ CI (`.github/workflows/ci.yml`) runs the tests and then builds the design
185
+ guide PDF with the PR's plugin and CSS, uploaded as the `design-guide-pdf`
186
+ artifact — open it to see what a change did to every page. On `main`, the
187
+ *Publish design guide* workflow deploys the HTML build to GitHub Pages
188
+ (enable it once under Settings → Pages → Source: GitHub Actions).
189
+
190
+ `plugin.js` imports nothing at runtime — `gutterpress` is a devDependency used
191
+ by the tests (`gutterpress/render`) and by the scripts (the CLI). Releases are
192
+ cut from the *Release* workflow (version in; npm, GitHub release and the
193
+ design guide PDF out); it refuses a version with no `## [X.Y.Z]` heading in
194
+ `CHANGELOG.md`. Issues about the package — a macro, a sheet, a token, a font,
195
+ or a page of the guide — belong here.