remarque-tokens 0.24.0 → 0.25.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.
package/AGENT_RULES.md CHANGED
@@ -323,6 +323,30 @@ the documented DTCG divergences.
323
323
 
324
324
  ---
325
325
 
326
+ ## Installing the Skills
327
+
328
+ This package ships two Claude Code skills under the npm subpath exports
329
+ `remarque-tokens/skills/remarque` and `remarque-tokens/skills/adopt`
330
+ (resolving to `skills/remarque/SKILL.md` and `skills/remarque-adopt/
331
+ SKILL.md` in the installed package). Claude Code only discovers skills
332
+ from a project's own `.claude/skills/` (or `~/.claude/skills/`), never
333
+ from `node_modules` — copy them in explicitly, one `cp` per skill:
334
+
335
+ ```bash
336
+ mkdir -p .claude/skills
337
+ cp -r node_modules/remarque-tokens/skills/remarque .claude/skills/remarque
338
+ cp -r node_modules/remarque-tokens/skills/remarque-adopt .claude/skills/remarque-adopt
339
+ ```
340
+
341
+ The copies are versioned with the installed package, not auto-updating —
342
+ re-copy both after a MAJOR bump, or any time this file's
343
+ "Machine-Readable Output" shape changes.
344
+
345
+ - `remarque` — the build/review contract for pages on the current version (tier rules, archetypes, pitfalls #6/#7).
346
+ - `remarque-adopt` — the version-bump/migration playbook (this file's "Machine-Readable Output" section is its main dependency): verify the resolved version past the 0.x caret freeze, discover newly-required tokens from `remarque-audit --json`, solve missing values against the consumer's own backgrounds, classify `remarque-drift --json` output, report against a fixed PR-body contract.
347
+
348
+ ---
349
+
326
350
  ## How to Reference This System
327
351
 
328
352
  In prompts, issues, or agent instructions, use:
package/CHANGELOG.md CHANGED
@@ -4,6 +4,19 @@ All notable changes to `remarque-tokens` are documented here. Token value
4
4
  changes always state the design rationale — downstream sites pin against
5
5
  these entries when syncing.
6
6
 
7
+ ## 0.25.0 — 2026-07-23
8
+
9
+ `remarque-adopt` skill + skills npm export (closes #107) — ratified 3-0 (skill-suite vote, 2026-07-23), the anchor item of the skill suite. Codifies the consumer-conformance playbook run five times in one day as hand-written agent briefs (williamzujkowski.github.io#381, tsundoku#243/#237, remarque-starter#7/#8) into a procedural, machine-gated skill.
10
+
11
+ ### Added
12
+
13
+ - **`.claude/skills/remarque-adopt/SKILL.md`** — a new Claude Code skill, distinct from the existing `remarque` loader skill: triggers on "bump remarque-tokens" / "upgrade the design system" / "adopt remarque in an existing site" / an audit failing after a version bump, not on ordinary page work. Five steps, each ending in a machine gate: (1) bump the pin and verify the *resolved* version, not the range typed — 0.x caret ranges never cross a minor below 1.0, the exact trap that froze remarque-starter at 0.10.x through 0.18.0; (2) discover newly-required tokens mechanically from `remarque-audit --json`'s `failures`, never by reading the CHANGELOG and guessing; (3) add missing tokens solved against *the consumer's own* `--color-bg`/`--color-surface`/`--color-code-bg` (keep-if-passing against the package default; the tsundoku#243 hue-collision case — the default viz "red" landing on top of that site's terracotta accent and its own `--color-error` — is the worked example for checking hue collisions as a distinct failure mode from contrast); (4) run `remarque-drift --json` and classify FAIL (undocumented core-tier override, fix it) / WARN (documented in `DESIGN-DEVIATIONS.md`/`DESIGN-NOTES.md`, ratified) / INFO (palette-tier personalization, expected); (5) a fixed PR-body contract (what changed, token decisions table, drift summary, gate results, anything explicitly declined). Acceptance throughout is pinned to `passed: true` in the JSON output, never agent judgment.
14
+ - **Both skills now ship in the npm tarball.** `.claude/skills/{remarque,remarque-adopt}/SKILL.md` remain the ONE canonical, hand-authored copies (also what a Claude Code session working in this repo reads directly); `scripts/build-skills.mjs` copies them byte-for-byte into `skills/remarque/SKILL.md` and `skills/remarque-adopt/SKILL.md` for packaging — the same single-source-plus-generated-copy relationship `tokens.json` already has to the CSS tiers, kept fresh the same way (`--check` gates CI freshness; a `prepack` script hook runs the plain copy automatically on every `npm pack`/`npm publish`, so a stale packaged copy can't ship even if someone forgets to re-run the script by hand). New exports: `remarque-tokens/skills/remarque` and `remarque-tokens/skills/adopt`. `package.json`'s `files` gains `skills/`, `scripts/build-skills.mjs`, and `scripts/lib/skills.mjs`.
15
+ - **README + AGENT_RULES.md: "Installing the skills"** — Claude Code only discovers skills from a project's own `.claude/skills/` (or `~/.claude/skills/`), never `node_modules`, so installing the npm package alone does nothing for a consumer's Claude Code session. Both docs now give the exact `cp -r node_modules/remarque-tokens/skills/<name> .claude/skills/<name>` pair and note the copies are versioned with the installed package, not auto-updating — re-copy on a MAJOR bump.
16
+ - **`scripts/test-skills.mjs`** (enforce-not-instruct applied to the skills themselves, panel condition) — asserts, per skill: frontmatter parses with a non-empty `name`/`description`; every CLI flag referenced alongside a `remarque-audit`/`remarque-drift`/`remarque-theme` command line is grepped straight out of `scripts/audit.mjs`/`scripts/drift-check.mjs`/`scripts/theme.mjs`'s own arg parsing (not hand-maintained separately, so a renamed flag fails this test instead of shipping a stale doc); every backticked package-relative file path referenced (`*.md`/`*.mjs`/`*.js`/`*.json`/`*.css`, excluding consumer-side conventions like `DESIGN-DEVIATIONS.md`/`DESIGN-NOTES.md` and `node_modules`/subpath-export forms) resolves to a real file in this repo; the packaged `skills/<name>/SKILL.md` copy is byte-identical to the canonical file. Wired into `deploy.yml` alongside `scripts/build-skills.mjs --check`.
17
+ - **`scripts/test-pack.mjs` extended** — the real npm-tarball smoke test now also asserts (via `tar -tzf`) that `package/skills/remarque/SKILL.md` and `package/skills/remarque-adopt/SKILL.md` land in the packed tarball, and that both resolve inside the scratch consumer's `node_modules/remarque-tokens/skills/` after a real `npm install` — proving the `prepack` hook actually fires during a real pack/publish, not just that the files exist in the working tree.
18
+ - Version-only regeneration of `tokens.json`/`tokens.d.ts`/`tokens.schema.json` and `registry.json`/`registry/*.json` (no token or registry content changes this release).
19
+
7
20
  ## 0.24.0 — 2026-07-23
8
21
 
9
22
  `light-dark()` + `color-scheme` palette migration (closes #95) and a `:has()` zero-JS forms enhancement layer (closes #97) — the ratified program's last two items.
package/README.md CHANGED
@@ -69,10 +69,32 @@ The agent rules define build order, non-negotiable rules, disallowed patterns, a
69
69
 
70
70
  Packaging for agent tooling:
71
71
  - **npm exports:** `remarque-tokens/agent-rules` (→ `AGENT_RULES.md`) and `remarque-tokens/spec` (→ `REMARQUE.md`), alongside the existing `remarque-tokens/tokens.json`, so a project can point an agent at `node_modules/remarque-tokens/AGENT_RULES.md` without hardcoding a filename.
72
- - **Claude Code skill:** [`.claude/skills/remarque/SKILL.md`](.claude/skills/remarque/SKILL.md) — triggers on "remarque" / "design system" / new-page work, loads all three files, and states the tier rules, the audit command, and the two build-time pitfalls (unlayered-token-import, string-form `@import`) that pass a green build while silently breaking.
72
+ - **Claude Code skills (two):**
73
+ - [`.claude/skills/remarque/SKILL.md`](.claude/skills/remarque/SKILL.md) — triggers on "remarque" / "design system" / new-page work, loads all three files, and states the tier rules, the audit command, and the two build-time pitfalls (unlayered-token-import, string-form `@import`) that pass a green build while silently breaking.
74
+ - [`.claude/skills/remarque-adopt/SKILL.md`](.claude/skills/remarque-adopt/SKILL.md) — triggers on "bump remarque-tokens" / "upgrade the design system" / "adopt remarque in an existing site" / an audit that starts failing after a version bump. The consumer-conformance playbook (issue #107): verify the resolved version past the 0.x caret freeze, discover newly-required tokens from `remarque-audit --json` mechanically, solve missing values against the *consumer's own* backgrounds (keep-if-passing), classify `remarque-drift --json` output (FAIL/WARN/INFO), and report against a fixed PR-body contract. Every step ends in a machine gate — `passed: true`, not agent judgment.
75
+
76
+ Both ship in the npm tarball under `skills/` (see "Installing the skills" below) as well as living at `.claude/skills/` in this repo.
73
77
  - **Live tokens endpoint:** the demo site serves the current `tokens.json` at **https://williamzujkowski.github.io/remarque/tokens.json**, and its schema at **https://williamzujkowski.github.io/remarque/tokens.schema.json** — a remote agent can fetch current token values (and validate their shape) directly instead of trusting training data.
74
78
  - **Markup-contract registry:** a shadcn-`registry-item.json`-shaped, version-pinned, hash-verified registry of known-good markup for the Essay/Broadsheet/Forms/Palette Deck modules — **https://williamzujkowski.github.io/remarque/registry.json** (index) and **https://williamzujkowski.github.io/remarque/registry/essay.json** (per item; also `broadsheet`/`forms`/`palette-deck`). Fetch and apply the markup instead of transcribing it from spec prose — see REMARQUE.md's "The Registry" and AGENT_RULES.md's "Prefer the Registry Over Transcribing Prose."
75
79
 
80
+ ### Installing the skills
81
+
82
+ `npm install remarque-tokens` does not put anything into your project's
83
+ `.claude/skills/` automatically — Claude Code only reads skills from
84
+ there (or from `~/.claude/skills/`), never from `node_modules`. Copy them
85
+ in explicitly, one `cp` per skill:
86
+
87
+ ```bash
88
+ mkdir -p .claude/skills
89
+ cp -r node_modules/remarque-tokens/skills/remarque .claude/skills/remarque
90
+ cp -r node_modules/remarque-tokens/skills/remarque-adopt .claude/skills/remarque-adopt
91
+ ```
92
+
93
+ The copies are versioned with whatever `remarque-tokens` version is
94
+ installed at copy time, not auto-updating — re-run both `cp` commands
95
+ after any MAJOR bump (and any time `AGENT_RULES.md`'s "Machine-Readable
96
+ Output" shape changes) to pick up the current playbook.
97
+
76
98
  ## Files
77
99
 
78
100
  | File | Purpose |
@@ -89,6 +111,7 @@ Packaging for agent tooling:
89
111
  | `tokens.schema.json` | Generated JSON Schema (draft 2020-12) for `tokens.json`, published alongside it |
90
112
  | `registry.json` + `registry/` | Generated markup-contract registry index + per-item files for essay/broadsheet/forms/palette-deck (`scripts/build-registry.mjs`) — see REMARQUE.md "The Registry" |
91
113
  | `registry-item.schema.json` + `registry.schema.json` | Generated JSON Schemas (draft 2020-12) for the per-item and index registry files |
114
+ | `skills/remarque/SKILL.md` + `skills/remarque-adopt/SKILL.md` | Generated packaging copies of the two Claude Code skills (`scripts/build-skills.mjs`) — canonical source is `.claude/skills/*/SKILL.md`; see "Installing the skills" above |
92
115
  | `fonts.css` + `fonts/` | Self-hosted @font-face declarations and woff2 files (no CDN requests) |
93
116
  | `tailwind.config.js` | Tailwind CSS **v3** configuration (v4 projects use an `@theme` block instead) |
94
117
  | `package.json` | npm package manifest for `remarque-tokens` |
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "remarque-tokens",
3
- "version": "0.24.0",
3
+ "version": "0.25.0",
4
4
  "engines": {
5
5
  "node": ">=18"
6
6
  },
@@ -29,7 +29,8 @@
29
29
  },
30
30
  "scripts": {
31
31
  "audit": "node scripts/audit.mjs",
32
- "drift": "node scripts/drift-check.mjs"
32
+ "drift": "node scripts/drift-check.mjs",
33
+ "prepack": "node scripts/build-skills.mjs"
33
34
  },
34
35
  "devDependencies": {
35
36
  "@williamzujkowski/oklch-terminal-themes": "0.5.0",
@@ -84,6 +85,8 @@
84
85
  "./registry-item.schema.json": "./registry-item.schema.json",
85
86
  "./registry.schema.json": "./registry.schema.json",
86
87
  "./registry/*": "./registry/*.json",
88
+ "./skills/remarque": "./skills/remarque/SKILL.md",
89
+ "./skills/adopt": "./skills/remarque-adopt/SKILL.md",
87
90
  "./package.json": "./package.json"
88
91
  },
89
92
  "files": [
@@ -117,6 +120,9 @@
117
120
  "registry-item.schema.json",
118
121
  "registry.schema.json",
119
122
  "scripts/build-registry.mjs",
120
- "scripts/lib/registry-extract.mjs"
123
+ "scripts/lib/registry-extract.mjs",
124
+ "skills/",
125
+ "scripts/build-skills.mjs",
126
+ "scripts/lib/skills.mjs"
121
127
  ]
122
128
  }
@@ -4,7 +4,7 @@
4
4
  "type": "remarque:contract",
5
5
  "title": "Broadsheet Pattern",
6
6
  "description": "The editorial Landing/archive pattern: masthead, lead article, numbered entry list, and post-header kicker. Entry numerals are generated from `data-entry-number` via `attr()`, never `counter()`, and every kicker/dateline row is true `font-variant-caps: all-small-caps`, never `text-transform: uppercase`.",
7
- "version": "0.24.0",
7
+ "version": "0.25.0",
8
8
  "integrity": "sha256-BZea38PRdob4OfmdGN0eDw3U0adl7SEsdrjKgSewK9A=",
9
9
  "dependencies": [
10
10
  "remarque-tokens"
@@ -4,7 +4,7 @@
4
4
  "type": "remarque:contract",
5
5
  "title": "Essay Module",
6
6
  "description": "Sidenotes + sticky TOC rail for long-form Essay pages: margin notes relocated into real DOM order, right after the paragraph that cites them, numbered by CSS counter and labeled `aria-label=\"Note N\"` in the same order the counter advances — the mechanism that prevents the sidenote aria-label/DOM-order transcription bug found in the flagship migration (#89, williamzujkowski.github.io#380).",
7
- "version": "0.24.0",
7
+ "version": "0.25.0",
8
8
  "integrity": "sha256-zr04H0+0xf01OWLk6B2A9ziZOYJd4Sq5q5/cib65lbU=",
9
9
  "dependencies": [
10
10
  "remarque-tokens"
@@ -4,7 +4,7 @@
4
4
  "type": "remarque:contract",
5
5
  "title": "Forms Primitives",
6
6
  "description": "Native field/input/checkbox/radio/button primitives with state-color wiring. Every `.remarque-input` pairs `for`/`id` with its `.remarque-field-label`, and every `.remarque-field-message` is wired via `aria-describedby` on the control — the paint-layer `data-state` attribute is never the only signal; `aria-invalid`/`aria-describedby` on the input carry the real accessibility contract.",
7
- "version": "0.24.0",
7
+ "version": "0.25.0",
8
8
  "integrity": "sha256-WfYjcf04Dxxx7X21U5b6DrY90Qw95p0zkCQszoh77tE=",
9
9
  "dependencies": [
10
10
  "remarque-tokens"
@@ -4,7 +4,7 @@
4
4
  "type": "remarque:contract",
5
5
  "title": "Palette Deck (markup contract only — no executable content)",
6
6
  "description": "Markup/wiring contract for the Palette Deck: set `data-palette` on the same root element as `data-theme` and the two compose independently. This item ships ONLY that HTML fragment. `deck.js` — the runtime module itself, a dependency-free ~60-line ESM file — is deliberately NOT embedded here: the registry’s blocking no-executable-content condition is held to an unambiguous zero-`<script>`-tag bar across every item, so neither `deck.js` nor the FOUC-restore `<script>` sample documented alongside it in REMARQUE.md is included. Consume `deck.js` the normal way, via the `remarque-tokens/deck` package import (`dependencies` below); read the FOUC-restore snippet from the `docs` URL.",
7
- "version": "0.24.0",
7
+ "version": "0.25.0",
8
8
  "integrity": "sha256-WGgBZ2j0VnLPRAZlzv/4G1Wu9rKqTdXf1536dWWu8nU=",
9
9
  "dependencies": [
10
10
  "remarque-tokens"
package/registry.json CHANGED
@@ -2,14 +2,14 @@
2
2
  "$schema": "https://williamzujkowski.github.io/remarque/registry.schema.json",
3
3
  "name": "remarque-tokens",
4
4
  "homepage": "https://williamzujkowski.github.io/remarque/",
5
- "version": "0.24.0",
5
+ "version": "0.25.0",
6
6
  "items": [
7
7
  {
8
8
  "name": "essay",
9
9
  "type": "remarque:contract",
10
10
  "title": "Essay Module",
11
11
  "description": "Sidenotes + sticky TOC rail for long-form Essay pages: margin notes relocated into real DOM order, right after the paragraph that cites them, numbered by CSS counter and labeled `aria-label=\"Note N\"` in the same order the counter advances — the mechanism that prevents the sidenote aria-label/DOM-order transcription bug found in the flagship migration (#89, williamzujkowski.github.io#380).",
12
- "version": "0.24.0",
12
+ "version": "0.25.0",
13
13
  "integrity": "sha256-zr04H0+0xf01OWLk6B2A9ziZOYJd4Sq5q5/cib65lbU=",
14
14
  "file": "registry/essay.json"
15
15
  },
@@ -18,7 +18,7 @@
18
18
  "type": "remarque:contract",
19
19
  "title": "Broadsheet Pattern",
20
20
  "description": "The editorial Landing/archive pattern: masthead, lead article, numbered entry list, and post-header kicker. Entry numerals are generated from `data-entry-number` via `attr()`, never `counter()`, and every kicker/dateline row is true `font-variant-caps: all-small-caps`, never `text-transform: uppercase`.",
21
- "version": "0.24.0",
21
+ "version": "0.25.0",
22
22
  "integrity": "sha256-BZea38PRdob4OfmdGN0eDw3U0adl7SEsdrjKgSewK9A=",
23
23
  "file": "registry/broadsheet.json"
24
24
  },
@@ -27,7 +27,7 @@
27
27
  "type": "remarque:contract",
28
28
  "title": "Forms Primitives",
29
29
  "description": "Native field/input/checkbox/radio/button primitives with state-color wiring. Every `.remarque-input` pairs `for`/`id` with its `.remarque-field-label`, and every `.remarque-field-message` is wired via `aria-describedby` on the control — the paint-layer `data-state` attribute is never the only signal; `aria-invalid`/`aria-describedby` on the input carry the real accessibility contract.",
30
- "version": "0.24.0",
30
+ "version": "0.25.0",
31
31
  "integrity": "sha256-WfYjcf04Dxxx7X21U5b6DrY90Qw95p0zkCQszoh77tE=",
32
32
  "file": "registry/forms.json"
33
33
  },
@@ -36,7 +36,7 @@
36
36
  "type": "remarque:contract",
37
37
  "title": "Palette Deck (markup contract only — no executable content)",
38
38
  "description": "Markup/wiring contract for the Palette Deck: set `data-palette` on the same root element as `data-theme` and the two compose independently. This item ships ONLY that HTML fragment. `deck.js` — the runtime module itself, a dependency-free ~60-line ESM file — is deliberately NOT embedded here: the registry’s blocking no-executable-content condition is held to an unambiguous zero-`<script>`-tag bar across every item, so neither `deck.js` nor the FOUC-restore `<script>` sample documented alongside it in REMARQUE.md is included. Consume `deck.js` the normal way, via the `remarque-tokens/deck` package import (`dependencies` below); read the FOUC-restore snippet from the `docs` URL.",
39
- "version": "0.24.0",
39
+ "version": "0.25.0",
40
40
  "integrity": "sha256-WGgBZ2j0VnLPRAZlzv/4G1Wu9rKqTdXf1536dWWu8nU=",
41
41
  "file": "registry/palette-deck.json"
42
42
  }
@@ -0,0 +1,55 @@
1
+ #!/usr/bin/env node
2
+ /*
3
+ * Packages the canonical Claude Code skills for npm distribution.
4
+ *
5
+ * node scripts/build-skills.mjs # (re)write skills/<name>/SKILL.md
6
+ * node scripts/build-skills.mjs --check # exit 1 if any packaged copy is stale (CI)
7
+ *
8
+ * `.claude/skills/<name>/SKILL.md` is the ONE hand-authored copy (also
9
+ * what a Claude Code session working in this repo reads directly, no
10
+ * indirection). This script copies it byte-for-byte into `skills/<name>/
11
+ * SKILL.md`, the location published in the npm tarball (package.json
12
+ * "files" + the "./skills/remarque" / "./skills/adopt" exports) — the
13
+ * same single-source-of-truth-plus-generated-copy relationship
14
+ * tokens.json has to tokens-core.css/tokens-palette.css (scripts/
15
+ * tokens-json.mjs --check), kept fresh by the same convention: run this
16
+ * script whenever a canonical SKILL.md changes, --check gates CI so a
17
+ * stale packaged copy can't ship silently.
18
+ */
19
+
20
+ import { readFileSync, writeFileSync, mkdirSync, existsSync } from 'node:fs';
21
+ import { dirname } from 'node:path';
22
+ import { SKILLS } from './lib/skills.mjs';
23
+
24
+ const CHECK = process.argv.includes('--check');
25
+ let bad = 0;
26
+
27
+ for (const { name, canonical, packaged } of SKILLS) {
28
+ if (!existsSync(canonical)) {
29
+ console.error(`✗ ${name}: canonical file missing: ${canonical}`);
30
+ bad++;
31
+ continue;
32
+ }
33
+ const src = readFileSync(canonical, 'utf8');
34
+
35
+ if (CHECK) {
36
+ const current = existsSync(packaged) ? readFileSync(packaged, 'utf8') : null;
37
+ if (current === src) {
38
+ console.log(`✓ ${packaged} is fresh (matches ${canonical})`);
39
+ } else {
40
+ console.error(`✗ ${packaged} is STALE vs ${canonical} — run \`node scripts/build-skills.mjs\` and commit the result`);
41
+ bad++;
42
+ }
43
+ continue;
44
+ }
45
+
46
+ mkdirSync(dirname(packaged), { recursive: true });
47
+ writeFileSync(packaged, src);
48
+ console.log(`wrote ${packaged} (from ${canonical})`);
49
+ }
50
+
51
+ if (bad) {
52
+ console.error(`\nbuild-skills ${CHECK ? '--check' : ''} FAILED — ${bad} issue(s)`);
53
+ process.exit(1);
54
+ }
55
+ if (!CHECK) console.log('\nskills/ packaging copies up to date.');
@@ -0,0 +1,66 @@
1
+ /*
2
+ * Shared table + tiny helpers for the two Claude Code skills this package
3
+ * ships and packages — used by scripts/build-skills.mjs (prepack copy +
4
+ * CI freshness gate) and scripts/test-skills.mjs (content validation).
5
+ *
6
+ * `.claude/skills/<name>/SKILL.md` is the ONE canonical, hand-authored
7
+ * copy of each skill (also what a local Claude Code session in this repo
8
+ * reads directly). `skills/<name>/SKILL.md` is a generated packaging
9
+ * copy — same relationship tokens.json has to the CSS tiers: one source
10
+ * of truth, a derived artifact kept fresh by a --check gate, never
11
+ * hand-edited independently.
12
+ */
13
+
14
+ export const SKILLS = [
15
+ {
16
+ name: 'remarque',
17
+ canonical: '.claude/skills/remarque/SKILL.md',
18
+ packaged: 'skills/remarque/SKILL.md',
19
+ exportName: './skills/remarque',
20
+ },
21
+ {
22
+ name: 'remarque-adopt',
23
+ canonical: '.claude/skills/remarque-adopt/SKILL.md',
24
+ packaged: 'skills/remarque-adopt/SKILL.md',
25
+ exportName: './skills/adopt',
26
+ },
27
+ ];
28
+
29
+ /*
30
+ * Minimal frontmatter reader — enough to check required keys are present
31
+ * and non-empty. Handles the one YAML shape these files actually use:
32
+ * plain `key: value` scalars, and a folded block scalar (`key: >`)
33
+ * followed by indented continuation lines, which is how both skills
34
+ * author their (long) `description` field.
35
+ */
36
+ export function readFrontmatter(text) {
37
+ const m = text.match(/^---\r?\n([\s\S]*?)\r?\n---/);
38
+ if (!m) return null;
39
+ const lines = m[1].split(/\r?\n/);
40
+ const fm = {};
41
+ let currentKey = null;
42
+ let buf = [];
43
+ const flush = () => {
44
+ if (currentKey) fm[currentKey] = buf.join(' ').trim();
45
+ buf = [];
46
+ };
47
+ for (const line of lines) {
48
+ const kv = line.match(/^([a-zA-Z0-9_-]+):\s*(.*)$/);
49
+ if (kv) {
50
+ flush();
51
+ currentKey = kv[1];
52
+ const rest = kv[2].trim();
53
+ if (rest === '>' || rest === '|' || rest === '>-' || rest === '|-') {
54
+ buf = [];
55
+ } else {
56
+ buf = rest ? [rest] : [];
57
+ flush();
58
+ currentKey = null;
59
+ }
60
+ } else if (currentKey && /^\s+\S/.test(line)) {
61
+ buf.push(line.trim());
62
+ }
63
+ }
64
+ flush();
65
+ return fm;
66
+ }
@@ -0,0 +1,92 @@
1
+ ---
2
+ name: remarque
3
+ description: >
4
+ Load the Remarque design system's implementation contract before building,
5
+ editing, or reviewing any page in a Remarque-based project — a
6
+ typography-first system for editorial, technical, and personal sites (17px
7
+ body floor, three-font system, four-then-seven page archetypes, strict
8
+ token tiers). Use when the user says "remarque", "design system", "build a
9
+ new page", "new archetype page", "style this like the site", or asks for
10
+ a page/component in a project that imports `remarque-tokens`. Also use
11
+ before reviewing a PR that touches design-system tokens or page layout in
12
+ such a project.
13
+ license: MIT
14
+ ---
15
+
16
+ # Remarque
17
+
18
+ Remarque is a typography-first design system. This skill tells you which
19
+ files define it, how to load them, and the two mistakes that cause the most
20
+ downstream breakage.
21
+
22
+ ## Load these three files before writing or reviewing any page
23
+
24
+ Prefer the installed package if this project depends on `remarque-tokens`;
25
+ fall back to the repo root if you are working inside `williamzujkowski/remarque`
26
+ itself.
27
+
28
+ | File | Where (consumer project) | Where (this repo) | Purpose |
29
+ |---|---|---|---|
30
+ | `AGENT_RULES.md` | `node_modules/remarque-tokens/AGENT_RULES.md` (or `remarque-tokens/agent-rules`) | `./AGENT_RULES.md` | Implementation contract — build order, non-negotiable rules, disallowed patterns, quality checklist |
31
+ | `REMARQUE.md` | `node_modules/remarque-tokens/REMARQUE.md` (or `remarque-tokens/spec`) | `./REMARQUE.md` | Full specification — philosophy, token tiers, page archetypes, acceptance criteria |
32
+ | `tokens.json` | `node_modules/remarque-tokens/tokens.json` (or `remarque-tokens/tokens.json`) | `./tokens.json` | Machine-readable token values (both themes) — read this instead of guessing a hex/oklch value from memory |
33
+
34
+ Read all three before generating code. `AGENT_RULES.md` says *how to build*;
35
+ `REMARQUE.md` says *what the system is*; `tokens.json` says *what the
36
+ current values actually are* — don't trust training data for token values,
37
+ the CSS (and this generated file) is the single source of truth and it
38
+ changes across releases.
39
+
40
+ ## Tier rules (non-negotiable)
41
+
42
+ Tokens live in two tiers with different contracts — get this wrong and the
43
+ project has silently forked the system:
44
+
45
+ - **Core** (`tokens-core.css`): type scale, the 17px body floor, line
46
+ heights, tracking, weights, spacing scale, `--content-standard` /
47
+ `--content-wide`, radius ceiling, motion durations, prose/typography
48
+ machinery. **Never overridden.** A project that changes a core value is
49
+ no longer a Remarque project, by definition.
50
+ - **Palette** (`tokens-palette.css`): font slots (`--font-display/body/mono`
51
+ — from the approved pairings only), all `--color-*`, `--content-reading`
52
+ (the measure, which moves with the body font). **Override freely** in a
53
+ stylesheet loaded after the tokens — this is the sanctioned
54
+ personalization surface.
55
+
56
+ Every page must also map to one of the seven archetypes (Essay, Project
57
+ Dossier, Notebook, Landing, Reference/Docs, Changelog, Gallery) — see
58
+ `REMARQUE.md`'s "Page Archetypes" section. Do not invent an eighth.
59
+
60
+ ## Audit command (run after any palette change)
61
+
62
+ - Inside this repo: `npm run audit`
63
+ - Inside a consumer project: `npx remarque-audit --palette <file> --src <dir>`
64
+
65
+ A palette change that doesn't pass the audit does not ship — contrast,
66
+ gamut, font-size floors, and hardcoded-color checks are mechanical gates,
67
+ not suggestions.
68
+
69
+ ## Pitfalls #6 and #7 (the two that cause silent, buildable breakage)
70
+
71
+ These pass a normal build with no error and no warning, so verify them
72
+ explicitly rather than trusting a green build:
73
+
74
+ **#6 — String-form `@import` only.** Always write `@import './tokens.css';`
75
+ (string form). Tailwind v4 / Lightning CSS silently **drops**
76
+ `@import url(...)` for local files — the build succeeds while the entire
77
+ token cascade vanishes from the output. Verify the built CSS contains
78
+ `.remarque-prose` after changing any import.
79
+
80
+ **#7 — Tokens must be imported unlayered (Tailwind v4).** Never
81
+ `@import "remarque-tokens" layer(...)`. `theme.css`'s `@theme inline`
82
+ mappings emit same-named self-referencing declarations inside
83
+ `@layer theme`; the real token values win only because unlayered
84
+ declarations beat layered ones. Layering the tokens makes every mapped
85
+ utility circular and invalid — again, with no build error.
86
+
87
+ ## When you're unsure
88
+
89
+ Apply `REMARQUE.md`'s decision protocol in order: more readable > more
90
+ typographically disciplined > quieter > more tokenized/reusable > less
91
+ visual noise. If still unsure, choose the option that looks more like a
92
+ well-typeset book and less like a web application.
@@ -0,0 +1,124 @@
1
+ ---
2
+ name: remarque-adopt
3
+ description: >
4
+ Run the remarque-tokens consumer-conformance playbook — the exact
5
+ procedure for bumping a project's remarque-tokens pin and getting back
6
+ to a passing audit. Use when the user says "bump remarque-tokens",
7
+ "upgrade the design system", "adopt remarque in an existing site",
8
+ "update to the latest remarque-tokens", or when `remarque-audit`/`npm
9
+ run audit` starts failing after a version bump (missing-token
10
+ failures). Distinct from the `remarque` skill, which is the
11
+ build/review contract for pages already on the current version — load
12
+ this one specifically for the migration itself, then defer to
13
+ `remarque` for any actual page work the migration surfaces.
14
+ license: MIT
15
+ ---
16
+
17
+ # remarque-adopt
18
+
19
+ Five steps, each ending in a machine gate. This codifies the playbook run
20
+ across williamzujkowski.github.io#381, tsundoku#243/#237, and
21
+ remarque-starter#7/#8 — read one of those PR bodies for the fullest worked
22
+ example if a step below is unclear.
23
+
24
+ ## 1. Bump the pin
25
+
26
+ Bump `remarque-tokens` in `package.json`, install, then **verify the
27
+ RESOLVED version, not the range you typed.** This package is pre-1.0:
28
+ caret ranges (`^0.NN.0`) never cross a minor below 1.0 (npm's own rule —
29
+ `^0.24.0` means `>=0.24.0 <0.25.0`), so a stale `^0.1x.0` pin silently
30
+ freezes a site for dozens of releases (remarque-starter#7 was frozen at
31
+ 0.10.x through 0.18.0). Bump the pin's own minor to the target, don't
32
+ just re-run install against the old range.
33
+
34
+ - Gate: `npm ls remarque-tokens` (or your lockfile) shows the exact
35
+ target version resolved — not just "install succeeded." A
36
+ lockfile-verified install (`npm ci` after committing the lockfile
37
+ change, not a bare `npm install` you never diff) is the acceptance;
38
+ see the panel's security condition in AGENT_RULES.md.
39
+
40
+ ## 2. Discover what's newly required — mechanically
41
+
42
+ Do not read the CHANGELOG and guess which tokens are new. Run the audit
43
+ against the site's current palette and let it tell you:
44
+
45
+ ```
46
+ npx remarque-audit --palette <your-palette-file> --src <dir> --json
47
+ ```
48
+
49
+ Parse `failures` (and `srcScans`) from the JSON — every missing/failing
50
+ token family the new version requires shows up here. See
51
+ AGENT_RULES.md's "Machine-Readable Output" for the full shape.
52
+
53
+ - Gate: you have a concrete list of failing checks, not an impression
54
+ from prose.
55
+
56
+ ## 3. Add the missing tokens — solved against THIS site's backgrounds
57
+
58
+ Start from the package's own default values (`tokens-palette.css` /
59
+ `tokens.json` in the target version) and add them to every theme block
60
+ the site's palette maintains. **Keep-if-passing:** if a default value
61
+ already clears its required ratio against *this site's own*
62
+ `--color-bg`/`--color-surface`/`--color-code-bg` (not the package demo's),
63
+ keep it verbatim — most slots need no change at all (tsundoku#237: 16 of
64
+ 16 new tokens were the package default byte-for-byte). Only re-solve a
65
+ value when the site's own backgrounds make the default fail (flagship#381:
66
+ 1 of 13 tokens needed a new lightness because that site's surface sits
67
+ closer to its bg than the package demo's does).
68
+
69
+ **Hue collisions are a second, distinct failure mode from contrast** —
70
+ check for them even when contrast passes. A new categorical/state hue can
71
+ land visually on top of a site's own accent or another semantic color.
72
+ Worked example, tsundoku#243: the default viz "red" (H24.6 light / H25.4
73
+ dark) sat almost on top of both tsundoku's terracotta accent (H35) and its
74
+ `--color-error` (H25/H26) — a chart category would have read as "the
75
+ accent" or "an error." Rotated to H350 (rose-red) in each theme
76
+ independently, re-solving lightness to hold the same contrast band the
77
+ untouched slots hit.
78
+
79
+ - **Acceptance is pinned to the audit output, not agent judgment.** This
80
+ step ends when:
81
+ ```
82
+ npx remarque-audit --palette <file> --src <dir> --json
83
+ ```
84
+ reports `passed: true`. Not "looks close," not "should be fine" — the
85
+ JSON's `passed` field, checked.
86
+
87
+ ## 4. Run the drift check
88
+
89
+ ```
90
+ npx remarque-drift --css-file <your-palette-file> --package-dir . --json
91
+ ```
92
+
93
+ Classify every record per REMARQUE.md "Token Tiers" / AGENT_RULES.md
94
+ "Machine-Readable Output":
95
+
96
+ | Class | Tier | Meaning | Action |
97
+ |---|---|---|---|
98
+ | `fail` | core | Undocumented core-tier override — the site has forked Remarque | Fix: revert to the core value (never ship a FAIL) |
99
+ | `warn` | core | Core-tier override, but the token name is mentioned in a `DESIGN-DEVIATIONS.md`/`DESIGN-NOTES.md` in the consumer | Ratified, documented deviation — not a build failure, but still surfaced |
100
+ | `info` | palette | Palette-tier divergence from the package default | Sanctioned personalization — expected, not an error |
101
+
102
+ Any new palette-tier value from step 3 that differs from the package
103
+ default (the tsundoku hue rotation, the flagship lightness re-solve) will
104
+ show up as `info` — that's correct, not a regression. If a value must
105
+ diverge from a *core*-tier token (rare, and usually means step 3 touched
106
+ the wrong tier), record it under a `--token-name` heading in the
107
+ project's `DESIGN-DEVIATIONS.md` (or `DESIGN-NOTES.md`) *before* running
108
+ drift again, so it reclassifies from `fail` to `warn`.
109
+
110
+ - Gate: `passed: true` (zero `fail` records). `warn`/`info` never block.
111
+
112
+ ## 5. PR body contract
113
+
114
+ Report, in this order — every consumer PR in the source list follows this
115
+ shape:
116
+
117
+ 1. **What changed** — old pin → new pin, which token families were added and why (which version introduced the audit requirement).
118
+ 2. **Token decisions** — a table of any value that needed solving (not kept-as-default), with the before/after values and the contrast numbers that justified the change. Note any hue collision found and how it was resolved, even if unrelated to contrast.
119
+ 3. **Drift summary** — the `summary: {fail, warn, info}` counts, with a one-line explanation of any non-zero `warn`.
120
+ 4. **Gate results** — the project's own full local suite (typecheck/tests/build) plus this playbook's two gates (audit `passed: true`, drift `fail: 0`), each stated as pass/fail, not just "ran."
121
+ 5. **Anything explicitly declined** — a new token family evaluated but not adopted into existing UI (tsundoku#243 declined recoloring an ordinal chart with new categorical hues), or a related upgrade opportunity noted but out of scope for this bump.
122
+
123
+ If any of steps 2-4's gates don't pass, the PR isn't ready — this
124
+ playbook has no "close enough."
package/tokens.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  /*
2
2
  * Remarque design tokens — GENERATED from tokens.json by
3
- * scripts/tokens-json.mjs (v0.24.0). Do not edit — the CSS
3
+ * scripts/tokens-json.mjs (v0.25.0). Do not edit — the CSS
4
4
  * (tokens-core.css + tokens-palette.css) is the source of truth;
5
5
  * tokens.json is the intermediate machine-readable form this file is
6
6
  * generated from. Regenerate with: node scripts/tokens-json.mjs
package/tokens.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "$description": "Remarque design tokens — GENERATED from tokens-core.css + tokens-palette.css by scripts/tokens-json.mjs. Do not edit; the CSS is the source of truth.",
4
4
  "$extensions": {
5
5
  "remarque": {
6
- "version": "0.24.0",
6
+ "version": "0.25.0",
7
7
  "tiers": {
8
8
  "core": "immutable identity — overriding forks the system",
9
9
  "palette": "sanctioned personalization surface — override freely, then run remarque-audit"