remarque-tokens 0.5.0 → 0.6.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/CHANGELOG.md +31 -0
- package/REMARQUE.md +44 -1
- package/package.json +1 -1
- package/prose.css +26 -0
- package/scripts/audit.mjs +11 -2
- package/tokens-core.css +2 -2
- package/tokens-palette.css +8 -0
- package/tokens.json +10 -1
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,37 @@ 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.6.0 — 2026-07-20
|
|
8
|
+
|
|
9
|
+
### Added
|
|
10
|
+
- **`--weight-display`** (palette tier, theme-conditional): display faces
|
|
11
|
+
render at 400 in light mode and 500 in dark — light-on-dark text is
|
|
12
|
+
optically thinner (halation), and high-contrast serif hairlines were
|
|
13
|
+
disappearing at display sizes on dark backgrounds (#59).
|
|
14
|
+
`.text-display`/`.text-title` consume it with a 400 fallback, so
|
|
15
|
+
palettes that don't define it are unaffected.
|
|
16
|
+
- **The remarque mark** (`.remarque-endmark` in prose.css): the system's
|
|
17
|
+
namesake made visible — a small muted fleuron closing every essay.
|
|
18
|
+
One per essay, aria-hidden, deliberately outside the latin subsets so
|
|
19
|
+
it falls to the serif fallback stack.
|
|
20
|
+
|
|
21
|
+
## 0.5.1 — 2026-07-20
|
|
22
|
+
|
|
23
|
+
Two `remarque-audit` fixes found by the flagship site's adoption (its
|
|
24
|
+
first real-world run):
|
|
25
|
+
|
|
26
|
+
### Fixed
|
|
27
|
+
- The file passed via `--palette` now always counts as a token file for
|
|
28
|
+
the oklch-literal scan — previously a consumer palette named
|
|
29
|
+
`global.css` produced ~200 false positives against its own token
|
|
30
|
+
declarations. `theme-deck.css`-style generated palette files are also
|
|
31
|
+
allowlisted.
|
|
32
|
+
- The `--src` scans strip comments (line numbers preserved) before
|
|
33
|
+
matching, so prose like `(issue #324)` in a comment no longer trips
|
|
34
|
+
the hex-color regex.
|
|
35
|
+
|
|
36
|
+
No token values changed.
|
|
37
|
+
|
|
7
38
|
## 0.5.0 — 2026-07-20
|
|
8
39
|
|
|
9
40
|
Theme-convention unification (epic #47 item 4; ratified 3-0 by consensus
|
package/REMARQUE.md
CHANGED
|
@@ -222,6 +222,48 @@ Agents reviewing PRs should reject changes that violate any line above without e
|
|
|
222
222
|
|
|
223
223
|
---
|
|
224
224
|
|
|
225
|
+
## Lineage: Butterick's Five Rules
|
|
226
|
+
|
|
227
|
+
Remarque's core values descend from Matthew Butterick's [*Typography in
|
|
228
|
+
Ten Minutes*](https://practicaltypography.com/typography-in-ten-minutes.html)
|
|
229
|
+
(an acknowledged inspiration). The mapping, including where and why we
|
|
230
|
+
deviate — values below are asserted against `tokens.json` in CI:
|
|
231
|
+
|
|
232
|
+
| Butterick rule | His guidance | Remarque | Status |
|
|
233
|
+
|---|---|---|---|
|
|
234
|
+
| 1. Body text first | Typographic quality is determined largely by body text | AGENT_RULES.md Build Order steps 1–4 are tokens → typography → shell → prose, before any component | Aligned by construction |
|
|
235
|
+
| 2. Point size | 15–25 px on the web | `--text-body: 1.0625rem` (17px); lead paragraphs `--text-body-lg: 1.1875rem` (19px) | Aligned |
|
|
236
|
+
| 3. Line spacing | 120–145% of point size | `--leading-body: 1.75` (175%) | **Deliberate deviation** — see below |
|
|
237
|
+
| 4. Line length | 45–90 characters per line | `--content-reading: 46rem` ≈ 70 ch at 17px Inter; the measure-compensation table targets 66–72 ch for every approved body face | Aligned |
|
|
238
|
+
| 5. Font choice | Professional fonts, never default system faces | Newsreader (Production Type), Inter (Rasmus Andersson), JetBrains Mono — professionally designed, self-hosted | Aligned in spirit: these are free but professional-grade faces; Butterick's stricter preference is paid fonts |
|
|
239
|
+
|
|
240
|
+
### The line-spacing deviation, argued
|
|
241
|
+
|
|
242
|
+
Remarque's 175% body leading sits **outside Butterick's 120–145% range,
|
|
243
|
+
at the airy extreme of quality web practice (commonly 150–165%)**. We
|
|
244
|
+
own that plainly rather than argue it away. The reasons it is a
|
|
245
|
+
deliberate identity choice, not an oversight:
|
|
246
|
+
|
|
247
|
+
1. **Leading scales with measure.** Classic guidance ties looser leading
|
|
248
|
+
to longer lines; Remarque's ~70 ch measure sits in the upper-middle
|
|
249
|
+
of Butterick's own 45–90 ch range, and screen prose at 17px benefits
|
|
250
|
+
from more air than his print-derived band.
|
|
251
|
+
2. **Token-hierarchy coherence.** Literal conformance (≤145%) would put
|
|
252
|
+
body leading *below* `--leading-meta: 1.5` — which is pinned by the
|
|
253
|
+
USWDS/WCAG floors this spec also adopts. Body text reading tighter
|
|
254
|
+
than caption text is not a hierarchy this system will ship.
|
|
255
|
+
3. **Identity.** "Generous — this is what makes prose readable" predates
|
|
256
|
+
this audit; the spacious register is part of what makes a Remarque
|
|
257
|
+
page recognizable (see Signature Moves).
|
|
258
|
+
|
|
259
|
+
The trade-off is real: 1.75 spends more vertical space and reads calmer
|
|
260
|
+
and slower than 1.5–1.65. Sites wanting Butterick-tighter rhythm are
|
|
261
|
+
choosing a different identity — that is a fork, and an honorable one,
|
|
262
|
+
but it is not Remarque. (Ratified 3–0 by design-review panel, 2026-07-20,
|
|
263
|
+
over the alternative of changing the token.)
|
|
264
|
+
|
|
265
|
+
---
|
|
266
|
+
|
|
225
267
|
## Decision Order
|
|
226
268
|
|
|
227
269
|
When multiple design options are possible, choose in this order:
|
|
@@ -324,7 +366,8 @@ The homepage or entry point. Sets the tone.
|
|
|
324
366
|
|
|
325
367
|
These are the repeatable visual tells that make a Remarque site recognizable:
|
|
326
368
|
|
|
327
|
-
-
|
|
369
|
+
- The remarque mark: a small muted fleuron closing every essay (`.remarque-endmark`) — the namesake made visible, one per essay, never decorated further
|
|
370
|
+
- Serif hero/page titles (Newsreader at display scale; display weight bumps one step in dark mode to keep serif hairlines alive)
|
|
328
371
|
- Mono metadata rows beneath titles
|
|
329
372
|
- Constrained body width with generous margins
|
|
330
373
|
- Subtle `1px` section dividers using `--color-border`
|
package/package.json
CHANGED
package/prose.css
CHANGED
|
@@ -137,3 +137,29 @@
|
|
|
137
137
|
margin-top: var(--space-2);
|
|
138
138
|
}
|
|
139
139
|
|
|
140
|
+
|
|
141
|
+
/* ─── The Remarque Mark ─────────────────────────────────── */
|
|
142
|
+
/*
|
|
143
|
+
* The system's namesake, made visible: a small mark closing every
|
|
144
|
+
* essay, the way a printer's fleuron ends a chapter. Quiet by rule —
|
|
145
|
+
* muted color, meta scale, one per essay, nothing else on its line.
|
|
146
|
+
*
|
|
147
|
+
* Markup (aria-hidden — it is punctuation, not content):
|
|
148
|
+
* <div class="remarque-endmark" aria-hidden="true"></div>
|
|
149
|
+
* placed after the last element inside .remarque-prose.
|
|
150
|
+
*
|
|
151
|
+
* The fleuron (U+2766) is outside the latin font subsets by design;
|
|
152
|
+
* it intentionally falls through to the serif fallback stack.
|
|
153
|
+
*/
|
|
154
|
+
|
|
155
|
+
.remarque-endmark {
|
|
156
|
+
text-align: center;
|
|
157
|
+
margin-top: var(--space-7);
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
.remarque-endmark::after {
|
|
161
|
+
content: "\2766";
|
|
162
|
+
font-family: var(--font-display);
|
|
163
|
+
font-size: var(--text-body);
|
|
164
|
+
color: var(--color-muted);
|
|
165
|
+
}
|
package/scripts/audit.mjs
CHANGED
|
@@ -152,11 +152,20 @@ console.log(`\nsource scans (${SRC})`);
|
|
|
152
152
|
const FONT_FLOOR_REM = 0.8125, FONT_FLOOR_PX = 13;
|
|
153
153
|
// tokens.astro is the token *reference page* — its job is displaying literal
|
|
154
154
|
// values (issue #48 tracks generating it from a machine-readable source).
|
|
155
|
-
|
|
155
|
+
// The file passed via --palette is BY DEFINITION a token file, whatever
|
|
156
|
+
// its name (a consumer's palette is often global.css or similar).
|
|
157
|
+
const paletteRel = relative('.', PALETTE);
|
|
158
|
+
const isTokenFile = (p) =>
|
|
159
|
+
p === paletteRel ||
|
|
160
|
+
/tokens(-core|-palette)?\.css$|fonts\.css$|globals?\.css$|theme-deck\.css$|pages[\/\\]tokens\.astro$/.test(p);
|
|
156
161
|
|
|
157
162
|
for (const file of walk(SRC)) {
|
|
158
163
|
const rel = relative('.', file);
|
|
159
|
-
|
|
164
|
+
// Strip comments before scanning, preserving line numbers — otherwise
|
|
165
|
+
// prose like "(issue #324)" in a comment trips the hex-color regex.
|
|
166
|
+
const text = readFileSync(file, 'utf8')
|
|
167
|
+
.replace(/\/\*[\s\S]*?\*\//g, (m) => m.replace(/[^\n]/g, ' '))
|
|
168
|
+
.replace(/(^|[^:])\/\/[^\n]*/g, (m, p1) => p1 + ' '.repeat(m.length - p1.length));
|
|
160
169
|
const lines = text.split('\n');
|
|
161
170
|
lines.forEach((line, i) => {
|
|
162
171
|
// 2. font-size floor (static rem/px values), plus statically
|
package/tokens-core.css
CHANGED
|
@@ -130,7 +130,7 @@ html {
|
|
|
130
130
|
font-size: var(--text-display);
|
|
131
131
|
line-height: var(--leading-display);
|
|
132
132
|
letter-spacing: var(--tracking-display);
|
|
133
|
-
font-weight: var(--weight-regular);
|
|
133
|
+
font-weight: var(--weight-display, var(--weight-regular));
|
|
134
134
|
}
|
|
135
135
|
|
|
136
136
|
.text-title {
|
|
@@ -138,7 +138,7 @@ html {
|
|
|
138
138
|
font-size: var(--text-title);
|
|
139
139
|
line-height: var(--leading-title);
|
|
140
140
|
letter-spacing: var(--tracking-title);
|
|
141
|
-
font-weight: var(--weight-regular);
|
|
141
|
+
font-weight: var(--weight-display, var(--weight-regular));
|
|
142
142
|
}
|
|
143
143
|
|
|
144
144
|
.text-section {
|
package/tokens-palette.css
CHANGED
|
@@ -34,6 +34,12 @@
|
|
|
34
34
|
/* Reading measure — tuned to the body font (see REMARQUE.md measure table).
|
|
35
35
|
46rem ≈ 70 characters per line at 17px Inter. */
|
|
36
36
|
--content-reading: 46rem;
|
|
37
|
+
|
|
38
|
+
/* Display weight — palette-tier because it is theme-conditional:
|
|
39
|
+
light-on-dark text renders optically thinner (halation), so dark
|
|
40
|
+
mode bumps display faces one step to keep serif hairlines alive.
|
|
41
|
+
(issue #59) */
|
|
42
|
+
--weight-display: 400;
|
|
37
43
|
}
|
|
38
44
|
|
|
39
45
|
/* ─── Color: Light theme (default) ──────────────────────── */
|
|
@@ -89,6 +95,7 @@
|
|
|
89
95
|
--color-bg: oklch(0.16 0.01 80); /* warm charcoal, not black */
|
|
90
96
|
--color-bg-subtle: oklch(0.19 0.01 80);
|
|
91
97
|
--color-fg: oklch(0.90 0.005 80); /* soft white, not pure */
|
|
98
|
+
--weight-display: 500; /* compensate thin serif hairlines on dark */
|
|
92
99
|
--color-fg-muted: oklch(0.70 0.01 80); /* 7.26:1 bg (AAA) */
|
|
93
100
|
--color-muted: oklch(0.60 0.01 80); /* 4.92:1 bg / 4.68:1 surface (AA with margin) */
|
|
94
101
|
--color-border: oklch(0.25 0.005 80); /* decorative only — see light-theme note */
|
|
@@ -116,6 +123,7 @@
|
|
|
116
123
|
light-dark(), which obsoletes both selectors. */
|
|
117
124
|
[data-theme="dark"],
|
|
118
125
|
:root.dark {
|
|
126
|
+
--weight-display: 500;
|
|
119
127
|
--color-bg: oklch(0.16 0.01 80);
|
|
120
128
|
--color-bg-subtle: oklch(0.19 0.01 80);
|
|
121
129
|
--color-fg: oklch(0.90 0.005 80);
|
package/tokens.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"$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.",
|
|
3
3
|
"$extensions": {
|
|
4
4
|
"remarque": {
|
|
5
|
-
"version": "0.
|
|
5
|
+
"version": "0.6.0",
|
|
6
6
|
"tiers": {
|
|
7
7
|
"core": "immutable identity — overriding forks the system",
|
|
8
8
|
"palette": "sanctioned personalization surface — override freely, then run remarque-audit"
|
|
@@ -236,6 +236,15 @@
|
|
|
236
236
|
}
|
|
237
237
|
}
|
|
238
238
|
},
|
|
239
|
+
"weight-display": {
|
|
240
|
+
"$type": "fontWeight",
|
|
241
|
+
"light": {
|
|
242
|
+
"$value": 400
|
|
243
|
+
},
|
|
244
|
+
"dark": {
|
|
245
|
+
"$value": 500
|
|
246
|
+
}
|
|
247
|
+
},
|
|
239
248
|
"color-bg": {
|
|
240
249
|
"$type": "color",
|
|
241
250
|
"light": {
|