remarque-tokens 0.15.0 → 0.17.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 +6 -0
- package/CHANGELOG.md +121 -0
- package/README.md +8 -4
- package/REMARQUE.md +204 -0
- package/broadsheet.css +441 -0
- package/essay.css +3 -0
- package/package.json +4 -1
- package/print.css +30 -0
- package/scripts/audit.mjs +14 -0
- package/scripts/theme.mjs +137 -0
- package/scripts/tokens-json.mjs +1 -0
- package/theme.css +8 -0
- package/tokens-core.css +16 -0
- package/tokens-palette.css +45 -0
- package/tokens.d.ts +52 -3
- package/tokens.json +92 -1
package/AGENT_RULES.md
CHANGED
|
@@ -62,12 +62,14 @@ These are not guidelines. Agents must follow them literally.
|
|
|
62
62
|
- Within the centered column, use `.content-reading` for prose-width sections (46rem, auto-centered within the 72rem column)
|
|
63
63
|
- Do NOT use Tailwind's `max-w-reading` or `max-w-standard` on page sections — these only set max-width without centering. Use the CSS classes `.content-reading` / `.content-standard` instead, which include `margin-inline: auto`
|
|
64
64
|
- Code blocks (`<pre>`) inherit the width of their parent container — no special wrapping needed when the parent is already constrained
|
|
65
|
+
- Stacking order is structural, not personalization: never author a bare `z-index` number — reference `tokens-core.css`'s `--z-*` scale (`--z-base`/`--z-sticky`/`--z-dropdown`/`--z-overlay`/`--z-modal`/`--z-toast`/`--z-skip-link`). Tailwind v4 has no `--z-index-*` theme namespace, so use arbitrary values (`z-[var(--z-modal)]`) rather than bare Tailwind numbers. See REMARQUE.md "Stacking."
|
|
65
66
|
|
|
66
67
|
### Color
|
|
67
68
|
|
|
68
69
|
- Accent color is used for exactly two things: inline links and one interactive element per viewport
|
|
69
70
|
- Dark mode is not an inverted light mode — it must be independently tuned for readability
|
|
70
71
|
- Background colors use `--color-bg`, never pure white (#fff) or pure black (#000)
|
|
72
|
+
- State colors (`--color-error`/`--color-success`/`--color-warning`/`--color-disabled`, plus the `-subtle` banner-background companions on the first three) are for feedback moments only — form validation, status banners, disabled controls — never for decoration. The one-accent rule above still governs everything else. See REMARQUE.md "State Colors."
|
|
71
73
|
|
|
72
74
|
### Components
|
|
73
75
|
|
|
@@ -142,6 +144,7 @@ project/
|
|
|
142
144
|
├── tokens-palette.css # PALETTE tier: font slots, colors, accent, reading measure. Override freely, then run the audit
|
|
143
145
|
├── prose.css # .remarque-prose long-form styling (aggregated by tokens.css; own subpath for opt-out)
|
|
144
146
|
├── essay.css # Optional Essay module: sidenotes + sticky TOC rail (own subpath, NOT aggregated — import explicitly)
|
|
147
|
+
├── broadsheet.css # Optional Broadsheet pattern: masthead, lead, entry list, post kicker (own subpath, NOT aggregated — import explicitly)
|
|
145
148
|
├── print.css # Print stylesheet (own subpath, NOT aggregated — import explicitly)
|
|
146
149
|
├── theme.css # Tailwind v4 adapter (@theme inline) — import after tailwindcss + tokens
|
|
147
150
|
├── tailwind.config.js # Tailwind v3 ONLY — v4 projects use theme.css instead
|
|
@@ -203,6 +206,7 @@ Before considering any implementation complete, verify:
|
|
|
203
206
|
- [ ] Every image has a 1px border and mono caption
|
|
204
207
|
- [ ] Every page maps to an archetype (Essay, Dossier, Notebook, Landing, Reference/Docs, Changelog, Gallery)
|
|
205
208
|
- [ ] If the Essay uses sidenotes/a TOC rail (`remarque-tokens/essay`): `.remarque-sidenote-ref`/`.remarque-sidenote` alternate in strict DOM order, the rail never intrudes into `.remarque-prose`'s own measure, and the page renders correctly with `essay.css`'s `@media` block deleted (the narrow-viewport/no-JS fallback)
|
|
209
|
+
- [ ] If a Landing/archive page uses the Broadsheet pattern (`remarque-tokens/broadsheet`): entry numerals are generated from `data-entry-number` via `attr()` (not `counter()`), the entry list stays a `<ul>` (not `<ol>` — the numeral is `aria-hidden` and decorative), and every kicker/dateline row uses `font-variant-caps: all-small-caps`, never `text-transform: uppercase`
|
|
206
210
|
- [ ] Mobile version is roomy — not a compressed desktop layout
|
|
207
211
|
- [ ] Mobile nav links have ≥44px touch targets
|
|
208
212
|
- [ ] No pure white or pure black backgrounds
|
|
@@ -210,6 +214,8 @@ Before considering any implementation complete, verify:
|
|
|
210
214
|
- [ ] Muted text placed on `--color-surface` still meets 4.5:1 (check the surface pairing, not just bg)
|
|
211
215
|
- [ ] All transitions use the motion duration tokens (reduced-motion support depends on it)
|
|
212
216
|
- [ ] Skip-to-content link present and functional
|
|
217
|
+
- [ ] If state colors are used (error/success/warning/disabled): only for feedback moments (validation, banners, disabled controls), never decoration; every state text color and `-subtle` companion passes `npm run audit`
|
|
218
|
+
- [ ] No bare `z-index` numbers anywhere in the page's CSS — every stacking layer references `tokens-core.css`'s `--z-*` scale
|
|
213
219
|
- [ ] OG meta tags present (og:title, og:description, og:image)
|
|
214
220
|
- [ ] `<html lang="en">` attribute set
|
|
215
221
|
- [ ] The site looks more like a book than a web app
|
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,127 @@ 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.17.0 — 2026-07-23
|
|
8
|
+
|
|
9
|
+
Semantic state colors + z-index scale (closes #26, closes #29).
|
|
10
|
+
|
|
11
|
+
### Added
|
|
12
|
+
- **State colors (`tokens-palette.css`, PALETTE tier)** — four semantic slots for feedback
|
|
13
|
+
moments (form validation, status banners, disabled controls), never decoration; the
|
|
14
|
+
one-accent rule still governs everything else. Hand-authored from the house ANSI hue
|
|
15
|
+
conventions, both themes, all three dark-mode conventions (`@media
|
|
16
|
+
prefers-color-scheme: dark`, `[data-theme="dark"]`, `:root.dark`):
|
|
17
|
+
- `--color-error` (hue 25, ANSI red) — light `oklch(0.52 0.12 25)` 5.44:1 bg / 5.28:1
|
|
18
|
+
surface; dark `oklch(0.62 0.11 26)` 5.07:1 bg / 4.82:1 surface.
|
|
19
|
+
- `--color-success` (hue 145, ANSI green) — light `oklch(0.51 0.12 145)` 5.08:1 bg /
|
|
20
|
+
4.93:1 surface; dark `oklch(0.61 0.11 145)` 5.36:1 bg / 5.10:1 surface.
|
|
21
|
+
- `--color-warning` (hue 85, ANSI yellow) — light `oklch(0.52 0.105 85)` 5.17:1 bg /
|
|
22
|
+
5.02:1 surface; dark `oklch(0.62 0.11 85)` 5.29:1 bg / 5.03:1 surface. The hard case:
|
|
23
|
+
yellow's low luminance-contrast means this slot solves noticeably darker in light
|
|
24
|
+
mode than error/success, the same shape as `--color-syntax-constant`'s solve.
|
|
25
|
+
- `--color-disabled` — aliased to `var(--color-muted)` in both themes: neutral
|
|
26
|
+
hue-80 muted family, deliberately **not** ANSI-derived.
|
|
27
|
+
- `-subtle` banner-background companions on the first three (`--color-error-subtle`/
|
|
28
|
+
`--color-success-subtle`/`--color-warning-subtle`, modeled on `--color-accent-subtle`
|
|
29
|
+
— near-bg lightness, state hue, low chroma) verified so `--color-fg` stays ≥4.5:1 on
|
|
30
|
+
them (the pairing that matters for callout/banner body text). No `-subtle` for
|
|
31
|
+
`--color-disabled` — a disabled control is quieter, not tinted.
|
|
32
|
+
- Every state text color ≥4.5:1 against `--color-bg` **and** `--color-surface`, both
|
|
33
|
+
themes; `scripts/audit.mjs` gains the 11 new pairings, `scripts/test-audit.mjs`'s
|
|
34
|
+
fixtures cover all seven tokens plus a must-fail case (`state-color-fails.css`).
|
|
35
|
+
- `scripts/theme.mjs` (`remarque-theme`) derives error/success/warning from a source
|
|
36
|
+
theme's red/green/yellow ANSI slots — keep-if-passing lightness checked against the
|
|
37
|
+
**stricter** of `--color-bg`/`--color-surface` at once (a new dual-target solver,
|
|
38
|
+
`keepOrSolveDual`/`solveDual`), not just one target like every other slot. Disabled
|
|
39
|
+
aliases the already-derived `--color-muted`. `-subtle` companions derive like
|
|
40
|
+
`--color-accent-subtle` (fixed 0.95 / bg+0.06 starting lightness — not the theme's
|
|
41
|
+
own solved bg lightness, which can exceed 0.95), nudged toward the extreme only if a
|
|
42
|
+
pathological theme doesn't already clear 4.5:1 against `--color-fg`. Self-verify
|
|
43
|
+
`CHECKS` mirrors `audit.mjs`'s new pairings exactly.
|
|
44
|
+
- `scripts/palette-golden.mjs` golden-gates all seven new tokens for free (it already
|
|
45
|
+
iterates whatever the bridge emits) — ΔE2000 ≤ 2.0 against `remarque-light`/
|
|
46
|
+
`remarque-dark`'s ANSI derivation, same identity/serialization contract as the rest
|
|
47
|
+
of the default palette. All new tokens land at ΔE ≤ 0.5 (see the PR description for
|
|
48
|
+
the full per-token table).
|
|
49
|
+
- REMARQUE.md "State Colors" — semantics, usage table, derivation note; Enforcement
|
|
50
|
+
Checklist gains the state-color pairing line.
|
|
51
|
+
- **Z-index scale (`tokens-core.css`, CORE tier)** — stacking is structural, not
|
|
52
|
+
personalization. A small ordinal scale, sparse gaps of 10: `--z-base` (0), `--z-sticky`
|
|
53
|
+
(10), `--z-dropdown` (20), `--z-overlay` (30), `--z-modal` (40), `--z-toast` (50),
|
|
54
|
+
`--z-skip-link` (60, tops everything). Wired into `essay.css`'s sticky TOC rail
|
|
55
|
+
(`z-index: var(--z-sticky)`) and the demo site's skip-to-content link
|
|
56
|
+
(`focus:z-[var(--z-skip-link)]`, replacing a hardcoded Tailwind `focus:z-50`).
|
|
57
|
+
`theme.css`'s header comment documents the Tailwind v4 workaround — v4 has no
|
|
58
|
+
`--z-index-*` theme namespace, so `z-*` utilities can't map to these directly; use
|
|
59
|
+
arbitrary values (`z-[var(--z-modal)]`) instead, same pattern as the motion durations.
|
|
60
|
+
REMARQUE.md "Stacking" — the scale, and the rule that consumer CSS must never author a
|
|
61
|
+
bare `z-index` number. AGENT_RULES.md's Layout/Quality Checklist sections gain matching
|
|
62
|
+
lines.
|
|
63
|
+
|
|
64
|
+
### Changed
|
|
65
|
+
- **`scripts/tokens-json.mjs`** — `typeOf()` now types `--z-*` tokens as `number`
|
|
66
|
+
(unitless stacking-order integers), matching the existing `--leading-*` treatment,
|
|
67
|
+
instead of falling through to the generic `string` type.
|
|
68
|
+
|
|
69
|
+
## 0.16.0 — 2026-07-23
|
|
70
|
+
|
|
71
|
+
Broadsheet pattern — masthead, lead article, numbered entry list, post-header kicker, graduated from the flagship (closes #36).
|
|
72
|
+
|
|
73
|
+
### Added
|
|
74
|
+
- **`broadsheet.css`** (new subpath: `remarque-tokens/broadsheet`, `remarque-tokens/broadsheet.css`) —
|
|
75
|
+
optional editorial Landing/archive pattern, not aggregated into `tokens.css` or `prose.css`.
|
|
76
|
+
Validated downstream on williamzujkowski.github.io (landing PR #213, archive/tag/post-header
|
|
77
|
+
PR #214) before upstreaming. Adds four primitives:
|
|
78
|
+
- `.remarque-masthead` — centered nameplate: mono small-caps kicker, oversized mixed
|
|
79
|
+
roman + italic `--font-display` title, mono dateline with hairline-rule separators.
|
|
80
|
+
**Fluid-type decision:** the flagship's `clamp(3.5rem, 9vw, 7.5rem)` title exceeds
|
|
81
|
+
`--text-display` (tokens-core.css's largest rung, `clamp(2.75rem, 5.5vw, 5rem)`) — no
|
|
82
|
+
existing token reaches it, so `.remarque-masthead` declares a file-scoped
|
|
83
|
+
`--remarque-masthead-size` whose min/max bounds are arithmetic on existing core spacing
|
|
84
|
+
tokens (`--space-7 + --space-2` = 3.5rem, `--space-10 - --space-2` = 7.5rem) rather than
|
|
85
|
+
new literals or a new core token — both resolve to the exact flagship values already
|
|
86
|
+
validated (contrast/gamut/font-floor audits + axe).
|
|
87
|
+
- `.remarque-lead` — mono kicker, large `--font-display` title (reuses `--text-display`
|
|
88
|
+
as-is — its range covers the flagship's closely enough that no exception was needed
|
|
89
|
+
here), underline-grow hover (`--motion-normal`/`--motion-easing`, reduced-motion-safe
|
|
90
|
+
for free via tokens-core.css's existing zeroing), italic lede with an italic drop cap
|
|
91
|
+
(same 3.5em/`initial-letter` mechanics as `.remarque-prose--dropcap` — one drop-cap
|
|
92
|
+
voice, not a second bespoke number).
|
|
93
|
+
- `.remarque-entry-list` / `.remarque-entry` — numbered entries via `data-entry-number`
|
|
94
|
+
+ `attr()`, NOT `counter()` (counter-generated content doesn't reliably receive the
|
|
95
|
+
OpenType oldstyle-figure treatment across Newsreader's weights — a graduation finding
|
|
96
|
+
worth keeping). Numeral column sized in `ch` units (intrinsic to the glyphs) rather
|
|
97
|
+
than an asserted rem literal. `<ul>`, not `<ol>` — the numeral is `aria-hidden` and
|
|
98
|
+
decorative, an `<ol>` would double-announce the position. Collapses to one column via
|
|
99
|
+
a container query at `40rem` (exactly `--space-10` x 5, matching the flagship's `640px`
|
|
100
|
+
— container-query conditions can't reference custom properties/`calc()`, so this is
|
|
101
|
+
the literal the multiple resolves to).
|
|
102
|
+
- `.remarque-post-kicker` — the same mono kicker voice, scaled to sit above an
|
|
103
|
+
individual post's own title.
|
|
104
|
+
- `font-variant-caps: all-small-caps` on every kicker/dateline row, not
|
|
105
|
+
`text-transform: uppercase` — the flagship predates the Small Caps rule and used
|
|
106
|
+
uppercase throughout this pattern; corrected on the way upstream, same as the Essay
|
|
107
|
+
Module's TOC summary.
|
|
108
|
+
- **`print.css`** — caps the masthead/lead title point sizes for print (28pt/18pt, matching
|
|
109
|
+
this file's existing `body { font-size: 11pt; }` convention) instead of printing the
|
|
110
|
+
on-screen fluid nameplate size; adds `.remarque-masthead`/`.remarque-lead`/
|
|
111
|
+
`.remarque-entry-list` to the existing full-width-on-print selector list.
|
|
112
|
+
- **REMARQUE.md "Patterns"** — new top-level section (Broadsheet is its first entry),
|
|
113
|
+
markup contract, the fluid-type decision writeup, and when-to-use guidance. Landing
|
|
114
|
+
archetype's "Optionally includes" list now references it.
|
|
115
|
+
- **AGENT_RULES.md** — File Structure Convention lists `broadsheet.css`; Quality Checklist
|
|
116
|
+
gains a Broadsheet-pattern line (`attr()` not `counter()`, `<ul>` not `<ol>`, small caps
|
|
117
|
+
not uppercase).
|
|
118
|
+
- **Demo site (`site/`)** — `site/src/components/BroadsheetEntry.astro` (reference
|
|
119
|
+
lead/entry component); `writing/index` restyled as a broadsheet archive (masthead + lead
|
|
120
|
+
+ entry list); `writing/against-decoration` gains the post-header kicker. New VR baseline:
|
|
121
|
+
`broadsheet-{light,dark}-{desktop,mobile}.png` (4 files, `writing` path added to `PAGES`).
|
|
122
|
+
|
|
123
|
+
### Documentation
|
|
124
|
+
- **README.md "Graduation"** — adds this release to the "Historical examples" list; the
|
|
125
|
+
"optional module" destination list now names the Broadsheet pattern alongside sidenotes/
|
|
126
|
+
TOC rail/palette deck.
|
|
127
|
+
|
|
7
128
|
## 0.15.0 — 2026-07-23
|
|
8
129
|
|
|
9
130
|
Essay module — sidenotes + sticky TOC rail, graduated from the flagship (closes #52).
|
package/README.md
CHANGED
|
@@ -133,9 +133,10 @@ margin and should stay there. A local invention is upstreamable when **all four*
|
|
|
133
133
|
spec amendment arguing the change.
|
|
134
134
|
|
|
135
135
|
**Three destinations.** Core spec (rare — core is identity, the bar is a fork-level
|
|
136
|
-
argument); optional module (sidenotes, TOC rail, palette deck); or
|
|
137
|
-
pattern* — explicitly not shared. The zine layer that inspired this
|
|
138
|
-
exemplar of the third: sanctioned personality that would be diluted by
|
|
136
|
+
argument); optional module (sidenotes, TOC rail, palette deck, the Broadsheet pattern); or
|
|
137
|
+
*documented site-local pattern* — explicitly not shared. The zine layer that inspired this
|
|
138
|
+
checklist is the exemplar of the third: sanctioned personality that would be diluted by
|
|
139
|
+
generalizing it.
|
|
139
140
|
|
|
140
141
|
**Process (single-maintainer scale, no ceremony):** open an issue with before/after
|
|
141
142
|
screenshots and the token-purity check; record the decision in the changelog. Historical
|
|
@@ -143,7 +144,10 @@ examples: measure compensation and the Gallery archetype graduated; the essay
|
|
|
143
144
|
sidenotes/sticky-TOC-rail pair graduated as an optional module
|
|
144
145
|
([#52](https://github.com/williamzujkowski/remarque/issues/52)); the theme deck was
|
|
145
146
|
re-scoped on the way up ([#56](https://github.com/williamzujkowski/remarque/issues/56));
|
|
146
|
-
the
|
|
147
|
+
the Broadsheet editorial pattern (masthead, lead article, numbered entry list, post-header
|
|
148
|
+
kicker) graduated as an optional pattern module
|
|
149
|
+
([#36](https://github.com/williamzujkowski/remarque/issues/36)); the zine layer
|
|
150
|
+
deliberately stayed local.
|
|
147
151
|
|
|
148
152
|
**Standing rulings** (ratified 3-0, 2026-07-23) on patterns the reviews kept re-flagging:
|
|
149
153
|
|
package/REMARQUE.md
CHANGED
|
@@ -90,6 +90,23 @@ The audit remains the gate regardless of provenance — `remarque-theme` self-ve
|
|
|
90
90
|
|
|
91
91
|
---
|
|
92
92
|
|
|
93
|
+
## State Colors
|
|
94
|
+
|
|
95
|
+
Four semantic slots — `--color-error`, `--color-success`, `--color-warning`, `--color-disabled` — for feedback moments: form validation, status banners, disabled controls. **These are for feedback, not decoration.** The one-accent rule ("Visual Rules" / "Changing the Accent Hue") still governs expressive color everywhere else — a state color says "this specific thing failed/succeeded/needs attention/can't be used right now," not "this section is important." Don't recolor headings, borders, or chrome with a state color; reserve it for the actual feedback element (an inline error message, a success toast, a disabled button's text).
|
|
96
|
+
|
|
97
|
+
Three of the four carry a `-subtle` companion — `--color-error-subtle`, `--color-success-subtle`, `--color-warning-subtle` — a faint tinted background for callout/banner-style feedback (an error banner, a success toast), sized the same way `--color-accent-subtle` is: near-`--color-bg` lightness, the state's hue, low chroma. `--color-disabled` has no `-subtle` companion — a disabled control is quieter than its enabled state, not tinted; use `--color-surface`/`--color-bg-subtle` for a disabled control's background if it needs one.
|
|
98
|
+
|
|
99
|
+
| Slot | Use for | `-subtle` companion |
|
|
100
|
+
|---|---|---|
|
|
101
|
+
| `--color-error` | Validation errors, failure states, destructive-action confirmation text | `--color-error-subtle` (banner/callout background) |
|
|
102
|
+
| `--color-success` | Confirmation messages, completed states | `--color-success-subtle` |
|
|
103
|
+
| `--color-warning` | Caution messages, states needing attention before proceeding | `--color-warning-subtle` |
|
|
104
|
+
| `--color-disabled` | Text/icon color for a disabled control | — (no subtle background; see above) |
|
|
105
|
+
|
|
106
|
+
**Derivation:** hand-authored in `tokens-palette.css` from the house ANSI hue conventions — error hue 25 (red), success hue 145 (green), warning hue 85 (yellow) — the same conventions `--color-syntax-string`/`--color-syntax-constant` already use for green/yellow. `scripts/remarque-theme` derives all three from a source theme's `red`/`green`/`yellow` ANSI slots (keep-if-passing lightness, checked against the **stricter** of `--color-bg` and `--color-surface` at once, not just one), exactly like every other slot in "Color Providers." `--color-disabled` is deliberately **not** ANSI-derived — it aliases the already-derived neutral `--color-muted` family, since a disabled state is a muted/quiet register, not a hue. Warning (hue 85, yellow) is the hard case in light mode — yellow has low luminance-contrast against a light background, so its solved lightness sits noticeably darker than the other two states, the same shape as `--color-syntax-constant`'s solve. Every state text color holds ≥ 4.5:1 against `--color-bg` **and** `--color-surface` in both themes; every `-subtle` background holds `--color-fg` ≥ 4.5:1 on it (the pairing that matters for a callout's body text) — both enforced by `scripts/audit.mjs` and golden-gated (ΔE2000 ≤ 2.0) against the upstream themes like the rest of the default palette.
|
|
107
|
+
|
|
108
|
+
---
|
|
109
|
+
|
|
93
110
|
## Font Slots
|
|
94
111
|
|
|
95
112
|
Remarque uses a three-slot font system. Each slot has a strict role, and each slot accepts a small set of approved faces — swap the face, keep the role.
|
|
@@ -365,6 +382,26 @@ Motion in Remarque is nearly invisible. The only permitted motion:
|
|
|
365
382
|
|
|
366
383
|
---
|
|
367
384
|
|
|
385
|
+
## Stacking
|
|
386
|
+
|
|
387
|
+
Stacking order is structural, not personalization — `tokens-core.css` (CORE tier, never overridden) carries a small ordinal `--z-*` scale:
|
|
388
|
+
|
|
389
|
+
| Token | Value | Use for |
|
|
390
|
+
|---|---:|---|
|
|
391
|
+
| `--z-base` | 0 | Default stacking context — the implicit baseline |
|
|
392
|
+
| `--z-sticky` | 10 | Sticky headers/rails (essay.css's TOC rail) |
|
|
393
|
+
| `--z-dropdown` | 20 | Dropdown/select menus |
|
|
394
|
+
| `--z-overlay` | 30 | Overlays/backdrops |
|
|
395
|
+
| `--z-modal` | 40 | Modal dialogs |
|
|
396
|
+
| `--z-toast` | 50 | Toast/notification stacks |
|
|
397
|
+
| `--z-skip-link` | 60 | The skip-to-content link — tops everything; it must never be obscured when focused |
|
|
398
|
+
|
|
399
|
+
**The rule: never a bare `z-index` number in consumer CSS.** Reference one of these seven tokens instead — an unnamed `z-index: 999` (or any other asserted integer) can't be reasoned about against the rest of the page's stacking contexts, and it's the same "hardcoded value bypasses the token system" problem as a literal hex color or a bare font-size. The scale is deliberately sparse (gaps of 10) so a future layer can be inserted between two existing rungs without renumbering everything above it.
|
|
400
|
+
|
|
401
|
+
Tailwind v4 ships `z-*` as a static, non-themable utility scale — there's no `--z-index-*` entry in its default `@theme` to map these into. `theme.css` (the Tailwind v4 adapter) documents the workaround in its header comment: use arbitrary values with the tokens, `z-[var(--z-modal)]` / `focus:z-[var(--z-skip-link)]`, the same pattern already used for motion durations (`duration-[var(--motion-fast)]`).
|
|
402
|
+
|
|
403
|
+
---
|
|
404
|
+
|
|
368
405
|
## USWDS Accessibility Compliance
|
|
369
406
|
|
|
370
407
|
Remarque adopts typography and accessibility standards from the [US Web Design System (USWDS)](https://designsystem.digital.gov/documentation/accessibility/) and [WCAG 2.1](https://www.w3.org/WAI/WCAG21/Understanding/):
|
|
@@ -419,6 +456,8 @@ Every PR that ships Remarque pages MUST pass (`npm run audit` automates the colo
|
|
|
419
456
|
- [ ] No hardcoded hex/rgb colors — only `var(--color-*)` tokens.
|
|
420
457
|
- [ ] Body line-height ≥ 1.5 (Remarque target: 1.75).
|
|
421
458
|
- [ ] Every `--color-syntax-*` slot ≥ 4.5:1 against `--color-code-bg` in both themes (see "Syntax Highlighting").
|
|
459
|
+
- [ ] Every `--color-error`/`--color-success`/`--color-warning`/`--color-disabled` ≥ 4.5:1 against `--color-bg` **and** `--color-surface` in both themes; every `-subtle` background keeps `--color-fg` ≥ 4.5:1 on it (see "State Colors"). State colors used only for feedback moments, never decoration.
|
|
460
|
+
- [ ] No bare `z-index` number in consumer CSS — reference `tokens-core.css`'s `--z-*` scale (see "Stacking").
|
|
422
461
|
|
|
423
462
|
Agents reviewing PRs should reject changes that violate any line above without explicit rationale.
|
|
424
463
|
|
|
@@ -556,6 +595,7 @@ The homepage or entry point. Sets the tone.
|
|
|
556
595
|
- Recent entries or updates (3–5 max)
|
|
557
596
|
- A brief "about" line
|
|
558
597
|
- **CLI-tool landing only:** a single mono install command block (styled as prose `<pre>`, copy button allowed) — the one sanctioned interactive element on an otherwise CTA-free page — and an optional `--help`-output figure (follows the Plate convention, see Image Treatment)
|
|
598
|
+
- **Editorial/archive landing:** the Broadsheet pattern's masthead + lead article + numbered entry list (own module, `remarque-tokens/broadsheet`) — see "Patterns" below
|
|
559
599
|
|
|
560
600
|
**Never includes:**
|
|
561
601
|
- Hero images or banners
|
|
@@ -774,6 +814,170 @@ applied so the next consumer doesn't rediscover it.
|
|
|
774
814
|
|
|
775
815
|
---
|
|
776
816
|
|
|
817
|
+
## Patterns
|
|
818
|
+
|
|
819
|
+
Optional, opt-in composition patterns for specific contexts — unlike the
|
|
820
|
+
Essay Module above (one archetype, two related features), a "pattern" in
|
|
821
|
+
this section is a small family of primitives meant to be composed
|
|
822
|
+
together, shipped as its own subpath rather than aggregated.
|
|
823
|
+
|
|
824
|
+
### Broadsheet
|
|
825
|
+
|
|
826
|
+
The editorial Landing/archive pattern: a newspaper-broadsheet voice for
|
|
827
|
+
the typography-maximalist end of the system. Own subpath,
|
|
828
|
+
`remarque-tokens/broadsheet` (`broadsheet.css`) — not aggregated into
|
|
829
|
+
`tokens.css` or `prose.css`.
|
|
830
|
+
|
|
831
|
+
**Provenance.** Graduated from williamzujkowski.github.io's landing
|
|
832
|
+
masthead and archive/tag/post-header implementation, validated in
|
|
833
|
+
[PR #213](https://github.com/williamzujkowski/williamzujkowski.github.io/pull/213)
|
|
834
|
+
(landing) and [PR #214](https://github.com/williamzujkowski/williamzujkowski.github.io/pull/214)
|
|
835
|
+
(archive/tag/post-header) — all Remarque tokens, all audits + axe passing
|
|
836
|
+
downstream before upstreaming — ratified in
|
|
837
|
+
[issue #36](https://github.com/williamzujkowski/remarque/issues/36) per
|
|
838
|
+
the "Graduation" checklist in the package README. No site-specific
|
|
839
|
+
literal was copied; every dimension is re-derived from tokens this
|
|
840
|
+
package already ships (see `broadsheet.css`'s header comment for the
|
|
841
|
+
value-by-value mapping and the fluid-type decision below).
|
|
842
|
+
|
|
843
|
+
Four primitives, composed independently — a page can use any subset:
|
|
844
|
+
|
|
845
|
+
1. **Masthead** (`.remarque-masthead`) — centered nameplate: mono
|
|
846
|
+
small-caps kicker, an oversized mixed roman + italic `--font-display`
|
|
847
|
+
title, mono dateline with hairline-rule separators.
|
|
848
|
+
2. **Lead article** (`.remarque-lead`) — a featured story: mono kicker
|
|
849
|
+
(`Section · N min read · Date`), a large `--font-display` title with
|
|
850
|
+
underline-grow hover, an italic lede paragraph with an italic drop cap.
|
|
851
|
+
3. **Numbered entry list** (`.remarque-entry-list` / `.remarque-entry`) —
|
|
852
|
+
italic oldstyle-figure numerals in the outer margin (via
|
|
853
|
+
`data-entry-number`), a two-column grid (numeral / kicker+title+excerpt),
|
|
854
|
+
a hairline between entries, collapsing to one column in a narrow
|
|
855
|
+
container.
|
|
856
|
+
4. **Post-header kicker** (`.remarque-post-kicker`) — the same mono
|
|
857
|
+
`Section · Reading time · Date` line, scaled down to sit above an
|
|
858
|
+
individual post's own title.
|
|
859
|
+
|
|
860
|
+
### Markup contract
|
|
861
|
+
|
|
862
|
+
```html
|
|
863
|
+
<header class="remarque-masthead">
|
|
864
|
+
<p class="remarque-masthead-kicker"><span>Field Notes</span></p>
|
|
865
|
+
<h1 class="remarque-masthead-title">Quiet <em>Signals</em></h1>
|
|
866
|
+
<p class="remarque-masthead-dateline">
|
|
867
|
+
<span class="remarque-rule" aria-hidden="true"></span>
|
|
868
|
+
<span>July 23, 2026</span>
|
|
869
|
+
<span class="remarque-rule" aria-hidden="true"></span>
|
|
870
|
+
</p>
|
|
871
|
+
</header>
|
|
872
|
+
|
|
873
|
+
<article class="remarque-lead">
|
|
874
|
+
<p class="remarque-lead-kicker">
|
|
875
|
+
<span class="remarque-lead-section">Essay</span>
|
|
876
|
+
<span class="remarque-dot" aria-hidden="true">·</span>
|
|
877
|
+
<span>8 min read</span>
|
|
878
|
+
<span class="remarque-dot" aria-hidden="true">·</span>
|
|
879
|
+
<time datetime="2026-04-08">Apr 8, 2026</time>
|
|
880
|
+
</p>
|
|
881
|
+
<h2 class="remarque-lead-title"><a href="/writing/x">Title</a></h2>
|
|
882
|
+
<p class="remarque-lead-lede">Lede paragraph…</p>
|
|
883
|
+
</article>
|
|
884
|
+
|
|
885
|
+
<ul class="remarque-entry-list">
|
|
886
|
+
<li class="remarque-entry">
|
|
887
|
+
<span class="remarque-entry-numeral" data-entry-number="2" aria-hidden="true"></span>
|
|
888
|
+
<div class="remarque-entry-body">
|
|
889
|
+
<p class="remarque-entry-kicker">
|
|
890
|
+
<span class="remarque-entry-section">Essay</span>
|
|
891
|
+
<span class="remarque-dot" aria-hidden="true">·</span>
|
|
892
|
+
<span>6 min read</span>
|
|
893
|
+
<span class="remarque-dot" aria-hidden="true">·</span>
|
|
894
|
+
<time datetime="2026-03-29">Mar 29, 2026</time>
|
|
895
|
+
</p>
|
|
896
|
+
<h3 class="remarque-entry-title"><a href="/writing/y">Title</a></h3>
|
|
897
|
+
<p class="remarque-entry-excerpt">Excerpt…</p>
|
|
898
|
+
</div>
|
|
899
|
+
</li>
|
|
900
|
+
</ul>
|
|
901
|
+
|
|
902
|
+
<header class="remarque-post-header">
|
|
903
|
+
<p class="remarque-post-kicker">
|
|
904
|
+
<span class="remarque-post-kicker-section">Essay</span>
|
|
905
|
+
<span class="remarque-dot" aria-hidden="true">·</span>
|
|
906
|
+
<span>8 min read</span>
|
|
907
|
+
<span class="remarque-dot" aria-hidden="true">·</span>
|
|
908
|
+
<time datetime="2026-04-08">Apr 8, 2026</time>
|
|
909
|
+
</p>
|
|
910
|
+
<h1 class="text-display font-display">Post Title</h1>
|
|
911
|
+
</header>
|
|
912
|
+
```
|
|
913
|
+
|
|
914
|
+
Requirements the CSS depends on:
|
|
915
|
+
|
|
916
|
+
- `.remarque-entry-list` uses `<ul>`, not `<ol>` — the visual numeral is
|
|
917
|
+
decorative (`aria-hidden`) and generated from `data-entry-number`; an
|
|
918
|
+
`<ol>` would have a screen reader announce "1 of 2" alongside it, a
|
|
919
|
+
second voice for the same information.
|
|
920
|
+
- Entry numerals are generated via `content: attr(data-entry-number)` on
|
|
921
|
+
`.remarque-entry-numeral::before`, NOT CSS `counter()`. `attr()` reads
|
|
922
|
+
the attribute of the element the pseudo-content is generated on, so
|
|
923
|
+
`data-entry-number` goes on `.remarque-entry-numeral` itself, not the
|
|
924
|
+
parent `<li>`.
|
|
925
|
+
- Every kicker/dateline row (`.remarque-masthead-kicker`,
|
|
926
|
+
`.remarque-masthead-dateline`, `.remarque-lead-kicker`,
|
|
927
|
+
`.remarque-entry-kicker`, `.remarque-post-kicker`) uses
|
|
928
|
+
`font-variant-caps: all-small-caps` — never `text-transform: uppercase`
|
|
929
|
+
(the flagship predates the Small Caps rule and used uppercase
|
|
930
|
+
throughout this pattern; corrected on the way upstream, same as the
|
|
931
|
+
Essay Module's TOC summary).
|
|
932
|
+
|
|
933
|
+
### Fluid-type decision: the masthead title
|
|
934
|
+
|
|
935
|
+
The flagship's masthead title is `clamp(3.5rem, 9vw, 7.5rem)` — bigger
|
|
936
|
+
than `--text-display` (tokens-core.css's largest type-scale rung,
|
|
937
|
+
`clamp(2.75rem, 5.5vw, 5rem)`) ever reaches. Per issue #36's required
|
|
938
|
+
call: express via an existing type token if the scale reaches that size,
|
|
939
|
+
else a documented fluid exception using core tokens as bounds — never a
|
|
940
|
+
new core token.
|
|
941
|
+
|
|
942
|
+
The scale does not reach it, so `.remarque-masthead` declares a
|
|
943
|
+
file-scoped custom property whose min/max bounds are arithmetic on
|
|
944
|
+
tokens already in `tokens-core.css`, not new literals:
|
|
945
|
+
|
|
946
|
+
```css
|
|
947
|
+
--remarque-masthead-size: clamp(
|
|
948
|
+
calc(var(--space-7) + var(--space-2)), /* 3rem + 0.5rem = 3.5rem */
|
|
949
|
+
9vw,
|
|
950
|
+
calc(var(--space-10) - var(--space-2)) /* 8rem - 0.5rem = 7.5rem */
|
|
951
|
+
);
|
|
952
|
+
```
|
|
953
|
+
|
|
954
|
+
Both bounds resolve to the exact flagship values already validated
|
|
955
|
+
downstream (contrast/gamut/font-floor audits + axe). The `9vw` rate is
|
|
956
|
+
unchanged from the flagship — it continues the same escalating per-tier
|
|
957
|
+
vw progression `tokens-core.css`'s own scale already uses (2.25vw
|
|
958
|
+
section → 3.5vw title → 5.5vw display), one step further for a register
|
|
959
|
+
one step past display. This property is declared inside `broadsheet.css`
|
|
960
|
+
only, never added to `tokens-core.css` — it is local arithmetic on
|
|
961
|
+
existing core tokens, not a new one.
|
|
962
|
+
|
|
963
|
+
Everywhere else in the pattern, an existing token already covers the
|
|
964
|
+
register: `.remarque-lead-title` uses `--text-display` as-is (its
|
|
965
|
+
2.75–5rem range covers the flagship's 2.25–3.75rem closely enough that
|
|
966
|
+
no exception is warranted), and `.remarque-entry-title` uses
|
|
967
|
+
`--text-section` as-is (1.375–2rem vs. the flagship's 1.5–1.875rem).
|
|
968
|
+
|
|
969
|
+
### When to use
|
|
970
|
+
|
|
971
|
+
Landing/archive contexts only — a Landing page's masthead, or an
|
|
972
|
+
archive/tag-listing page's lead-plus-entry-list. Typography-maximalist:
|
|
973
|
+
this is the one pattern in Remarque where a title is allowed to outgrow
|
|
974
|
+
`--text-display`, and it is deliberately reserved for exactly one
|
|
975
|
+
register, not a general-purpose "big heading" utility. The post-header
|
|
976
|
+
kicker is the one primitive meant for individual post pages rather than
|
|
977
|
+
the archive itself.
|
|
978
|
+
|
|
979
|
+
---
|
|
980
|
+
|
|
777
981
|
## Signature Moves
|
|
778
982
|
|
|
779
983
|
These are the repeatable visual tells that make a Remarque site recognizable:
|