gp-dimm-city 1.1.0 → 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,153 @@ 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
+
10
157
  ## [1.1.0] - 2026-10-07
11
158
 
12
159
  **Layout note for books upgrading from 1.0.x:** the page margins now follow
package/components.yaml CHANGED
@@ -147,7 +147,7 @@ components:
147
147
  css: styles/components/data.css
148
148
  tokens: [--dc-definition-block-surface, --dc-definition-block-accent, --dc-definition-block-accent-width]
149
149
  breaks: "break-inside: avoid (via .dc-prose-panel)"
150
- notes: "04-components.md marks the macro as superseded by markdown definition lists; both books still use it."
150
+ notes: "The design guide (06-panels-and-cards) points a plain term list at a markdown definition list instead; both books still use the macro."
151
151
 
152
152
  - name: procedure
153
153
  status: live
@@ -333,7 +333,7 @@ components:
333
333
  origin: plugin
334
334
  recipe: "@learning-path / ### Title / > subtitle / - Skill A / - Skill B … @end-learning-path"
335
335
  emits:
336
- - div.dc-learning-path.dc-path-block > div.dc-path-shell > h2.dc-spray > span.dc-path-sticker
336
+ - div.dc-learning-path.dc-path-block > div.dc-path-shell > h3.dc-spray > span.dc-path-sticker + span.dc-path-sep
337
337
  - div.dc-path-shell > div.dc-intro
338
338
  - div.dc-stickers > span.dc-sticker > span.dc-sticker-ref
339
339
  - span.dc-arrow (between stickers)
@@ -345,14 +345,14 @@ components:
345
345
  - --dc-path-shell-padding-top
346
346
  - --dc-path-shell-padding-bottom
347
347
  - --dc-arrow-color
348
- breaks: "break-before/after: auto on the block; the h2 stays with what follows"
348
+ breaks: "break-before/after: auto on the block; the h3 stays with what follows"
349
349
 
350
350
  - name: skill
351
351
  status: live
352
352
  origin: plugin
353
353
  recipe: "@skill [id=…] [{.dc-allow-split}] [{.dc-two-col}] / #### Name | Tier / > flavor / 1. **N AP** *Ability:* text / ##### Sub-header … @end-skill (alias @end-skills)"
354
354
  emits:
355
- - div.dc-skill-card[name][data-break-inside=avoid] > div.dc-card-tab > span.dc-tab-title + span.dc-tab-tier
355
+ - div.dc-skill-card[name][data-break-inside=avoid] > div.dc-card-tab > h4.dc-tab-title + span.dc-tab-tier
356
356
  - div.dc-card-body > div.dc-card-inner > p.dc-flavor + div.dc-sub-header
357
357
  - div.dc-ability > span.dc-ap + p.dc-ability-text
358
358
  css: [styles/components/cards.css, styles/components/data.css, styles/components/specialty-identity.css, styles/dc-native.css]
@@ -471,7 +471,7 @@ components:
471
471
  recipe: "@section .dc-citizen-walkthrough [.gp-columns-2]"
472
472
  emits: div.section.dc-citizen-walkthrough
473
473
  css: [styles/components/section.css, styles/dc-native.css]
474
- notes: "KNOWN DRIFT (2026-09-01 audit, T2): 04-components.md tells authors to override --section-accent / --section-bg at the chapter id; no CSS declares either name. The chassis reads --dc-section-accent / --dc-section-bg (see section). Unprefixed names are outside the check's token scan, so this stays a note until the chapter is corrected."
474
+ notes: "Themed through the section chassis tokens --dc-section-accent / --dc-section-bg (see section), which the design guide documents."
475
475
 
476
476
  - name: citizen-file-page
477
477
  status: live
@@ -544,7 +544,7 @@ components:
544
544
  status: live
545
545
  origin: author
546
546
  recipe: "## Title {.dc-spray} (also emitted by @learning-path for its title)"
547
- emits: h2.dc-spray
547
+ emits: ["h2.dc-spray (authored)", "h3.dc-spray (a @learning-path title)"]
548
548
  css: [styles/components/chrome.css, styles/components/data.css]
549
549
  tokens: [--dc-spray-bg, --dc-spray-color]
550
550
  breaks: "as a path-shell title: break-before avoid on the element after it"
@@ -614,6 +614,40 @@ components:
614
614
  css: styles/components/cards.css
615
615
  breaks: "list items and paragraphs break-inside: avoid within the columns"
616
616
 
617
+ - name: plain
618
+ status: live
619
+ origin: author
620
+ recipe: "@section .dc-plain"
621
+ emits: div.section.dc-plain
622
+ css: styles/components/section.css
623
+ notes: "The section-chrome escape hatch (dc#39). The design guide renders it (11-variants)."
624
+
625
+ - name: full-page
626
+ status: live
627
+ origin: author
628
+ recipe: "@page .dc-full-page"
629
+ emits: div.page.dc-full-page
630
+ css: [styles/page-templates.css, styles/page-rules.css, styles/dc-native.css]
631
+ breaks: "break-before: page; page: full"
632
+ notes: "Used by SysOps (chapter-00); the design guide documents it in a fenced example (08-page-templates)."
633
+
634
+ - name: printer-page
635
+ status: live
636
+ origin: author
637
+ recipe: "@page .dc-printer-page (the last marker of a book's last chapter)"
638
+ emits: div.page.dc-printer-page
639
+ css: [styles/page-rules.css, styles/dc-native.css]
640
+ breaks: "page: printer-blank; break-before: page"
641
+ notes: "DEPRECATED in 1.1.1: gutterpress 0.11.15+ reserves the blank last page itself (dtrpg preset, `print.reserveLastPage`). A completely blank final page — no wall, no footer — kept so books that still use it build unchanged. The Field Guide still ends with it (chapter-05) until it builds on a stable gutterpress 0.11.15; drop it then."
642
+
643
+ - name: img-float
644
+ status: live
645
+ origin: author
646
+ recipe: "![alt](src){.dc-img-float-left|.dc-img-float-right}"
647
+ emits: img.dc-img-float-left|.dc-img-float-right
648
+ css: styles/components/images.css
649
+ notes: "Documented and rendered in the design guide (04-layout, 11-variants); no Field Guide use."
650
+
617
651
  # ── Core-owned structure whose public tokens this library declares ─────
618
652
  - name: section
619
653
  status: live
@@ -642,23 +676,6 @@ components:
642
676
  notes: "There is no @chapter-opener macro."
643
677
 
644
678
  # ── Author classes currently unused by the books ──────────────────────────────
645
- - name: plain
646
- status: unused
647
- origin: author
648
- recipe: "@section .dc-plain"
649
- emits: div.section.dc-plain
650
- css: styles/components/section.css
651
- notes: "The section-chrome escape hatch (dc#39)."
652
-
653
- - name: full-page
654
- status: unused
655
- origin: author
656
- recipe: "@page .dc-full-page"
657
- emits: div.page.dc-full-page
658
- css: [styles/page-templates.css, styles/page-rules.css, styles/dc-native.css]
659
- breaks: "break-before: page; page: full"
660
- notes: "Documented in 05-page-templates.md; every occurrence in the guide is inside a fenced example."
661
-
662
679
  - name: suppress-footer
663
680
  status: unused
664
681
  origin: author
@@ -667,113 +684,86 @@ components:
667
684
  css: styles/page-rules.css
668
685
  breaks: "page: clean"
669
686
 
670
- - name: printer-page
671
- status: live
672
- origin: author
673
- recipe: "@page .dc-printer-page (the last marker of a book's last chapter)"
674
- emits: div.page.dc-printer-page
675
- css: [styles/page-rules.css, styles/dc-native.css]
676
- breaks: "page: printer-blank; break-before: page"
677
- notes: "A completely blank final page — no wall, no footer — for DriveThruRPG's reserved printer page. With `print: signature: 4` in the manifest, gutterpress pads to the next multiple of 4, so the book always ends blank. Used by the Field Guide."
678
-
687
+ # ── Retired: no CSS, no emission, no use (tombstone comments only) ─────
679
688
  - name: cover-page
680
- status: unused
689
+ status: retired
681
690
  origin: author
682
691
  recipe: "raw <div class=\"dc-cover-page dc-cover-layout\"> composite"
683
692
  emits:
684
693
  - div.dc-cover-page.dc-cover-layout > div.dc-cover-bg + div.dc-cover-num + h1.dc-cover-bigword + p.dc-cover-strap
685
694
  - div.dc-cover-body + div.dc-cover-meta-row
686
- css: styles/components/data.css
687
- tokens: [--dc-cover-meta-border]
688
- notes: "Documented in 05-page-templates.md inside a fenced example only."
695
+ notes: "Removed 2026-10-08 (data.css): no book used it, and its translucent gradients were the PDF/X transparency test's only exemption."
689
696
 
690
697
  - name: toc-rows
691
- status: unused
698
+ status: retired
692
699
  origin: author
693
700
  recipe: "raw <div class=\"dc-toc-row\"> > .dc-toc-no + .dc-toc-title + .dc-toc-page inside .dc-toc"
694
701
  emits: div.dc-toc-row > span.dc-toc-no + span.dc-toc-title + span.dc-toc-page
695
- css: styles/components/data.css
696
- notes: "Both books' contents pages use a plain list inside .dc-toc."
697
-
698
- - name: img-float
699
- status: unused
700
- origin: author
701
- recipe: "![alt](src){.dc-img-float-left|.dc-img-float-right}"
702
- emits: img.dc-img-float-left|.dc-img-float-right
703
- css: styles/components/images.css
704
- notes: "Documented in 06-layout.md and 07-markdown-reference.md; no live use."
702
+ notes: "Removed 2026-10-08 (data.css): both books' contents pages use a plain list inside .dc-toc."
705
703
 
706
704
  - name: portrait
707
- status: unused
705
+ status: retired
708
706
  origin: author
709
707
  recipe: "raw <div class=\"dc-portrait\"><img></div>"
710
708
  emits: div.dc-portrait > img
711
- css: styles/components/chrome.css
712
- tokens: [--dc-portrait-border, --dc-portrait-surface]
709
+ notes: "Removed 2026-10-08 (chrome.css) with its --dc-portrait-* tokens: never used."
713
710
 
714
711
  - name: dashed-rule
715
- status: unused
712
+ status: retired
716
713
  origin: author
717
714
  recipe: "raw <hr class=\"dc-dashed-rule\">"
718
715
  emits: hr.dc-dashed-rule
719
- css: styles/components/chrome.css
716
+ notes: "Removed 2026-10-08: plain `hr` keeps the dashed rule (chrome.css)."
720
717
 
721
718
  - name: margin-sm
722
- status: unused
719
+ status: retired
723
720
  origin: author
724
721
  recipe: ".dc-margin-sm modifier (e.g. on .dc-tape)"
725
722
  emits: .dc-margin-sm
726
- css: styles/components/chrome.css
723
+ notes: "Removed 2026-10-08 (chrome.css): never used."
727
724
 
728
725
  - name: path-subtitle
729
- status: unused
726
+ status: retired
730
727
  origin: author
731
728
  recipe: "raw <div class=\"dc-path-subtitle\">"
732
729
  emits: div.dc-path-subtitle
733
- css: styles/components/chrome.css
734
- notes: "@learning-path emits .dc-intro for its subtitle, not this."
730
+ notes: "Removed 2026-10-08 (chrome.css): @learning-path emits .dc-intro for its subtitle."
735
731
 
736
732
  - name: outcome-table
737
- status: unused
733
+ status: retired
738
734
  origin: author
739
735
  recipe: "(none — no macro or markdown path emits it)"
740
736
  emits: .dc-outcome-table
741
- css: styles/components/cards.css
742
- notes: "A column-span rule inside .dc-two-col; the plugin emits .dc-outcomes."
737
+ notes: "Removed 2026-10-08 (cards.css): nothing emitted it; the plugin emits .dc-outcomes."
743
738
 
744
739
  - name: roll-badges
745
- status: unused
740
+ status: retired
746
741
  origin: author
747
742
  recipe: "(none — no current authoring path)"
748
743
  emits: [span.dc-roll-lucid, span.dc-roll-surreal]
749
- css: styles/components/data.css
750
- tokens: [--dc-roll-lucid-color, --dc-roll-surreal-color]
744
+ notes: "Removed 2026-10-08 (data.css) with --dc-roll-lucid-color/--dc-roll-surreal-color: no authoring path."
751
745
 
752
746
  - name: sidebar-box-divider
753
- status: unused
747
+ status: retired
754
748
  origin: author
755
749
  recipe: "raw <hr class=\"dc-sidebar-box-divider\"> inside a sidebar-box"
756
750
  emits: hr.dc-sidebar-box-divider
757
- css: styles/components/data.css
751
+ notes: "Removed 2026-10-08: a plain `hr` inside a sidebar box is the divider (data.css)."
758
752
 
759
753
  - name: glossary-item
760
- status: unused
754
+ status: retired
761
755
  origin: author
762
756
  recipe: "raw <div class=\"dc-item\"> inside .dc-terms"
763
757
  emits: div.dc-item
764
- css: styles/components/images.css
765
- breaks: "break-inside: avoid"
766
- notes: "The class the CSS styles; the docs and gallery author .dc-terms-item instead (see glossary-item-authored)."
758
+ notes: "Removed 2026-10-08 (images.css, with --card-border-color): never used; see glossary-item-authored for the open naming question."
767
759
 
768
760
  - name: callout-generic
769
- status: unused
761
+ status: retired
770
762
  origin: author
771
763
  recipe: "(none — no macro or markdown path emits it)"
772
764
  emits: .dc-callout
773
- css: styles/dc-native.css
774
- notes: "One stale first-child glue rule in the engine sheet; the alert family emits .dc-alert. Adjacency rules for it were removed 2026-06-21 (chrome.css)."
765
+ notes: "Removed 2026-10-08 (dc-native.css): nothing emits .dc-callout; the alert family is .dc-alert."
775
766
 
776
- # ── Retired: no CSS, no emission, no use (tombstone comments only) ─────
777
767
  - name: roll-table
778
768
  status: retired
779
769
  origin: plugin
@@ -827,7 +817,7 @@ components:
827
817
  - name: skill-card-continuation-marker
828
818
  status: unimplemented
829
819
  origin: plugin
830
- recipe: "(described in 04-components.md, 09-component-gallery.md and docs/components-and-palette-reference.md as automatic ▸ / ◂ markers on split skill cards)"
820
+ recipe: "(described in docs/components-and-palette-reference.md as automatic ▸ / ◂ markers on split skill cards)"
831
821
  emits: [.dc-card-cont-marker, .dc-card-fwd-marker]
832
822
  notes: "Nothing ever emitted these; they needed a runtime script hook gutterpress does not have (cards.css comment, removed 2026-07-25). The docs describing them are stale."
833
823
 
Binary file
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gp-dimm-city",
3
- "version": "1.1.0",
3
+ "version": "1.1.1",
4
4
  "description": "Dimm City design system for Gutterpress: the markdown-it macros (@skill, @specialty, @learning-path, @callout, …), print stylesheets, design tokens, fonts and page templates the Dimm City TTRPG books are set in.",
5
5
  "type": "module",
6
6
  "main": "plugin.js",
@@ -68,7 +68,7 @@
68
68
  "pack:check": "npm pack --dry-run"
69
69
  },
70
70
  "devDependencies": {
71
- "gutterpress": "0.11.13",
71
+ "gutterpress": "0.11.15-alpha.1",
72
72
  "markdown-it": "^14.1.0"
73
73
  },
74
74
  "peerDependencies": {
package/plugin.js CHANGED
@@ -1565,10 +1565,9 @@ export default function dimmCityPlugin(md, options = {}) {
1565
1565
  }
1566
1566
 
1567
1567
  // Removed 2026-05-17: @two-column / @three-column / @no-break.
1568
- // Use @section .gp-columns-2 / @section .gp-columns-3 / @section .pmd-no-break
1569
- // instead — markers.js emits identical layout semantics, with the
1570
- // added `.section` class that picks up `break-inside: avoid` from MARKER_CSS.
1571
- // See docs/migrations/2026-05-removing-container-syntax.md for the rationale.
1568
+ // Use @section .gp-columns-2 / @section .gp-columns-3 instead — markers.js
1569
+ // emits identical layout semantics, with the added `.section` class that
1570
+ // picks up `break-inside: avoid` from MARKER_CSS.
1572
1571
 
1573
1572
  // --- @gear / @end-gear ---
1574
1573
  // Shorthand for @card .dc-gear — emits a bare `.dc-card.dc-gear`.
@@ -1753,12 +1752,17 @@ export default function dimmCityPlugin(md, options = {}) {
1753
1752
 
1754
1753
  // Inside @learning-path section
1755
1754
  if (inLearningPath && !inSkillMode) {
1756
- // H3 = Learning path title (banner)
1755
+ // H3 = Learning path title (banner). Emitted as an h3, the level it
1756
+ // was written at: the outline (the app's contents panel, PDF
1757
+ // bookmarks) nests specialty (##) > learning path (###) > skill (####).
1758
+ // .dc-path-sep is a real space between the sticker and the title, so
1759
+ // the heading's text reads "PRX1 Refuse Finality" (outline, bookmarks,
1760
+ // copy, search, screen readers); chrome.css gives it the printed gap.
1757
1761
  if (tok.type === 'heading_open' && tok.tag === 'h3') {
1758
1762
  const inlineTok = tokens[i + 1];
1759
1763
  const titleText = inlineTok && inlineTok.content ? inlineTok.content : '';
1760
1764
  currentLearningPathName = titleText;
1761
- newTokens.push(makeToken('html_block', '<h2 class="dc-spray"><span class="dc-path-sticker">' + esc(currentLearningPathRef) + '</span>' + esc(titleText) + '</h2>\n'));
1765
+ newTokens.push(makeToken('html_block', '<h3 class="dc-spray"><span class="dc-path-sticker">' + esc(currentLearningPathRef) + '</span><span class="dc-path-sep"> </span>' + esc(titleText) + '</h3>\n'));
1762
1766
  learningPathHasTitle = true;
1763
1767
  i += 2; // Skip heading_open, inline, heading_close
1764
1768
  continue;
@@ -1896,7 +1900,7 @@ export default function dimmCityPlugin(md, options = {}) {
1896
1900
 
1897
1901
  // Mark image-only paragraphs so layout rules can target them without
1898
1902
  // relying on p:has(img). The base CSS rule
1899
- // (p.dc-img-wrapper { padding:0; margin:0 }) lives in components.css.
1903
+ // (p.dc-img-wrapper { padding:0; margin:0 }) lives in components/data.css.
1900
1904
  // Per-page rules can further refine position via .page.my-class p.dc-img-wrapper.
1901
1905
  if (tok.type === 'paragraph_open') {
1902
1906
  const inlineTok = tokens[i + 1];
@@ -1967,7 +1971,10 @@ export default function dimmCityPlugin(md, options = {}) {
1967
1971
  const tabBaseClass = 'dc-card-tab' + (parsed.highlight ? ' dc-highlight' : '');
1968
1972
  cardHtml += ' <div class="' + tabBaseClass + '">\n';
1969
1973
  const autoTier = currentLearningPathRef ? currentLearningPathRef + '.' + currentSkillIndex : '';
1970
- cardHtml += ' <span class="dc-tab-title">' + esc(parsed.name) + '</span>\n';
1974
+ // The skill's name is its `####` heading, kept a heading so the
1975
+ // outline lists it under its learning path. (A continuation card's
1976
+ // repeated title stays a span: it is not a new entry.)
1977
+ cardHtml += ' <h4 class="dc-tab-title">' + esc(parsed.name) + '</h4>\n';
1971
1978
  cardHtml += ' <span class="dc-tab-tier">' + esc(parsed.tier || autoTier) + '</span>\n';
1972
1979
  cardHtml += ' </div>\n';
1973
1980
 
@@ -8,7 +8,6 @@
8
8
  ── ARCHITECTURAL CONTRACT ────────────────────────────────────────────────
9
9
  OWNS:
10
10
  - Every .dc-* component class (base + thin variants)
11
- - Every .pmd-* utility class
12
11
  - Specialty parent-scoped overrides:
13
12
  .dc-specialty.<name> .dc-skill-card { … }
14
13
  .dc-specialty.<name> .dc-path-shell { … }
@@ -80,7 +79,7 @@
80
79
  (`.dc-ap.free`, `.dc-sidebar.inset`, `.dc-specialty.<name> .dc-X`) —
81
80
  never by re-declaring the token on the base component selector itself.
82
81
 
83
- AGENT RULE: "Is this a .dc-* or .pmd-* component style, or a
82
+ AGENT RULE: "Is this a .dc-* component style, or a
84
83
  .dc-specialty.<name> scope block for a component?" — if NO, use another file.
85
84
  ──────────────────────────────────────────────────────────────────────── */
86
85
 
@@ -50,6 +50,13 @@
50
50
  Augmerc BODYCOVER/BLITZ seam). Same class of fix as .fg-art-portrait's
51
51
  margin-bottom in the book's own sheet (unlayered). */
52
52
  margin-bottom: calc(var(--dc-card-gap) + 6px);
53
+ /* The tab's outline reaches 4px above the tab (.dc-card-tab::after). Above
54
+ the CARD it printed at the foot of the previous page whenever the card
55
+ opened a page — a full-width ink-and-accent line across the folio row.
56
+ The card starts 4px higher and pads the tab 4px down, so the outline
57
+ stays inside the card's box and nothing moves. */
58
+ padding-top: 4px;
59
+ margin-top: -4px;
53
60
  max-width: 100%;
54
61
  /* 4-way ink outline (2px on each side) + HARD offset poster shadow. The
55
62
  hard shadow (2pt 3pt 0, no blur) pins the card to the brick wall as a
@@ -71,9 +78,7 @@
71
78
  script-injection hook (no manifest `scripts` key, no plugin `scripts`
72
79
  export, and assemble.ts's <head> template is fixed), so the file was dead
73
80
  and has been deleted. Split-card continuation markers are therefore an
74
- UNIMPLEMENTED feature; docs that describe them (04-components.md,
75
- 09-component-gallery.md, docs/components-and-palette-reference.md) are
76
- stale. Wiring this up requires a script hook in print-md itself. */
81
+ UNIMPLEMENTED feature (components.yaml: skill-card-continuation-marker). Wiring this up requires a script hook in print-md itself. */
77
82
 
78
83
  /* ── Card tab ─────────────────────────────────────────────────────────── */
79
84
  .dc-card-tab {
@@ -163,6 +168,11 @@
163
168
  letter-spacing: 0.05em;
164
169
  line-height: 1.2;
165
170
  word-break: break-word;
171
+ /* The title is the skill's h4 (plugin.js): clear what the h4 look adds
172
+ (dc-core.css) so the tab sets exactly as the span it used to be. */
173
+ margin: 0;
174
+ font-weight: inherit;
175
+ text-wrap: wrap;
166
176
  }
167
177
 
168
178
  .dc-tab-tier {
@@ -248,7 +258,7 @@
248
258
  right: calc(-2pt - 2px);
249
259
  bottom: calc(-3pt - 2px);
250
260
  left: calc(2pt - 2px);
251
- background: rgba(0, 0, 0, 0.28);
261
+ background: color-mix(in srgb, #000 28%, var(--wall-tone));
252
262
  clip-path: var(--dc-skill-body-shape);
253
263
  z-index: -4;
254
264
  }
@@ -301,11 +311,9 @@
301
311
  column-fill: balance;
302
312
  }
303
313
 
304
- /* Inside 2-col body, force outcome tables and full-width elements to span
305
- both columns so the visual chrome doesn't break across the gap. */
306
- .dc-skill-card.dc-two-col .dc-card-inner .dc-outcome-table,
307
- .dc-skill-card.dc-two-col .dc-card-inner table,
308
- .dc-skill-card.dc-two-col .dc-card-inner h5 {
314
+ /* Inside 2-col body, a table spans both columns so its chrome doesn't break
315
+ across the gap. */
316
+ .dc-skill-card.dc-two-col .dc-card-inner table {
309
317
  column-span: all;
310
318
  }
311
319
 
@@ -314,7 +322,6 @@
314
322
  together in a single column even when the column boundary lands in
315
323
  the middle of one. Paragraphs immediately following list items also
316
324
  stay glued so their text doesn't strand from its anchor item. */
317
- .dc-skill-card.dc-two-col .dc-card-inner ol > li,
318
325
  .dc-skill-card.dc-two-col .dc-card-inner ul > li,
319
326
  .dc-skill-card.dc-two-col .dc-card-inner p {
320
327
  break-inside: avoid;
@@ -334,8 +341,7 @@
334
341
  right: 16px;
335
342
  width: 28px;
336
343
  height: 2px;
337
- background: var(--dc-card-body-mark);
338
- opacity: 0.15;
344
+ background: color-mix(in srgb, var(--dc-card-body-mark) 15%, var(--dc-card-surface));
339
345
  transform: rotate(-3deg);
340
346
  z-index: 2;
341
347
  }
@@ -367,13 +373,13 @@
367
373
 
368
374
  .dc-skill-card.dc-highlight .dc-highlight-body > .dc-card-inner::after {
369
375
  background:
370
- linear-gradient(to bottom, rgba(180, 40, 40, 0.10) 0%, rgba(180, 40, 40, 0) 45%),
376
+ linear-gradient(to bottom, color-mix(in srgb, rgb(180 40 40) 10%, var(--dc-card-surface)) 0%, var(--dc-card-surface) 45%),
371
377
  var(--dc-card-surface);
372
378
  }
373
379
 
374
380
  /* ── Continuation card variants ───────────────────────────────────────── */
375
381
  .dc-skill-card-cont {
376
- margin-top: 0;
382
+ margin-top: -4px; /* the card's own offset: see .dc-skill-card */
377
383
  }
378
384
 
379
385
  .dc-card-tab-cont {
@@ -452,9 +458,9 @@
452
458
  CSS rectangle. */
453
459
  background:
454
460
  linear-gradient(180deg,
455
- color-mix(in srgb, var(--dc-ap-bg) 90%, #fff 10%) 0%, /* PDF/X-1a: pre-composite to ~90% bg + 10% white; e.g. on --crimson (#e1261c) → #e64030; on Ingram submission replace with static opaque value in dc-tokens-print.css */
461
+ color-mix(in srgb, var(--dc-ap-bg) 90%, #fff 10%) 0%, /* PDF/X-1a: pre-composite to ~90% bg + 10% white; e.g. on --crimson (#e1261c) → #e64030 */
456
462
  var(--dc-ap-bg) 50%,
457
- color-mix(in srgb, var(--dc-ap-bg) 94%, #000 6%) 100%); /* PDF/X-1a: pre-composite to ~94% bg + 6% black; e.g. on --crimson (#e1261c) → #d42419; on Ingram submission replace with static opaque value in dc-tokens-print.css */
463
+ color-mix(in srgb, var(--dc-ap-bg) 94%, #000 6%) 100%); /* PDF/X-1a: pre-composite to ~94% bg + 6% black; e.g. on --crimson (#e1261c) → #d42419 */
458
464
  color: var(--dc-ap-fg);
459
465
  /* 1pt ink-dark hairline gives registration grip — without it, adjacent
460
466
  red-family AP chips (free/var/increased) merge under CMYK dot gain
@@ -465,10 +471,9 @@
465
471
  is the #2 amateur tell after flat fills. The layered version gives depth
466
472
  that reads as "card lifted off page". */
467
473
  box-shadow:
468
- inset 0 1px 0 rgba(255, 255, 255, 0.15),
469
- 2px 2px 0 rgba(0, 0, 0, 0.10),
470
- 3px 3px 6px rgba(0, 0, 0, 0.08);
471
- text-shadow: 0 1px 0 rgba(0, 0, 0, 0.20);
474
+ inset 0 1px 0 color-mix(in srgb, #fff 15%, var(--dc-ap-bg)),
475
+ 2px 2px 0 color-mix(in srgb, #000 10%, var(--dc-card-surface));
476
+ text-shadow: 0 1px 0 color-mix(in srgb, #000 20%, var(--dc-ap-bg));
472
477
  letter-spacing: 1px;
473
478
  flex-shrink: 0;
474
479
  align-self: flex-start;