@bongos/core 1.19.448 → 1.19.450
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/.bongos-core.json +96 -36
- package/docs/copy-inventory.md +121 -114
- package/docs/copy-registry.json +377 -331
- package/docs/file-map.md +1 -1
- package/docs/module-api-changelog.md +4 -0
- package/modules/hall-ui/public/diagram-viewer.css +51 -34
- package/modules/hall-ui/public/diagram-viewer.js +4 -1
- package/modules/hall-ui/public/diagrams.css +45 -0
- package/modules/hall-ui/public/diagrams.html +12 -20
- package/modules/hall-ui/public/diagrams.states.json +28 -0
- package/modules/hall-ui/public/idea.css +138 -71
- package/modules/hall-ui/public/idea.html +13 -3
- package/modules/hall-ui/public/idea.js +17 -4
- package/modules/hall-ui/public/idea.states.json +14 -0
- package/modules/hall-ui/public/ideas.css +148 -107
- package/modules/hall-ui/public/ideas.html +15 -5
- package/modules/hall-ui/public/ideas.states.json +15 -0
- package/modules/hall-ui/public/primer.css +92 -400
- package/modules/hall-ui/public/primer.html +68 -26
- package/modules/hall-ui/public/primer.js +107 -308
- package/modules/hall-ui/public/primer.states.json +38 -0
- package/modules/hall-ui/public/ranks.html +9 -1
- package/modules/hall-ui/public/ranks.states.json +1 -1
- package/modules/hall-ui/public/record.css +324 -0
- package/modules/hall-ui/public/roadmap.css +152 -86
- package/modules/hall-ui/public/roadmap.html +6 -1
- package/modules/hall-ui/public/roadmap.states.json +31 -0
- package/modules/hall-ui/public/room.css +441 -0
- package/modules/hall-ui/public/style.css +269 -63
- package/modules/hall-ui/public/task.css +71 -0
- package/modules/hall-ui/public/task.html +15 -32
- package/modules/hall-ui/public/task.js +142 -39
- package/modules/hall-ui/public/task.states.json +14 -0
- package/modules/hall-ui/public/work.css +4 -15
- package/modules/ui-design/kit/serve.js +7 -1
- package/package-lock.json +2 -2
- package/package.json +1 -1
- package/scripts/hall-preview/server.js +34 -0
- package/src/module-api.js +1 -1
- package/tests/hall_audit.mjs +18 -11
- package/tests/hall_reading_world.mjs +430 -0
- package/tests/hall_record_world.mjs +412 -0
|
@@ -0,0 +1,441 @@
|
|
|
1
|
+
/* room.css — the READING-ROOM archetype: a long document read end to end
|
|
2
|
+
(task 1003306, goal 1000081). Shared by the primer (primer.html) and the
|
|
3
|
+
diagrams index (diagrams.html).
|
|
4
|
+
|
|
5
|
+
THE ARCHETYPE is v3 "the glass hall", the owner's pick from the composition
|
|
6
|
+
round — docs/design/hall-direction-v2.md §6, mock
|
|
7
|
+
docs/design/mocks/hall/reading/v3.html. Reading order, top to bottom: a
|
|
8
|
+
progress hairline under the topbar; the room's name alone over the ground
|
|
9
|
+
(the shell's .page-head--room); then a GLASS table of contents beside a
|
|
10
|
+
--bg-card article card. The glass/card split is the composition's argument:
|
|
11
|
+
wayfinding is chrome and belongs to the same material as the rail and the
|
|
12
|
+
topbar, the document is content and belongs on a panel the ground can never
|
|
13
|
+
reach the ink on.
|
|
14
|
+
|
|
15
|
+
WHY IT IS ITS OWN SHEET rather than more of primer.css: the primer and the
|
|
16
|
+
diagrams index are the same room over different documents — one renders
|
|
17
|
+
markdown, one renders five figures — and the framed figure is literally the
|
|
18
|
+
same object on both (diagram-viewer.js upgrades `figure.diagram img,
|
|
19
|
+
figure.primer-figure img` with one selector). Ranks, Economy, Repo Atlas and
|
|
20
|
+
Modules inherit this archetype next. Page-specific shapes stay page-local:
|
|
21
|
+
primer.css keeps the acknowledge gate, diagrams.css keeps the legend strip.
|
|
22
|
+
|
|
23
|
+
WHY THE CLASSES ARE STILL `primer-`: two live surfaces spell them —
|
|
24
|
+
diagram-viewer.js's upgrade selector and tests/hall_audit.mjs's pinned
|
|
25
|
+
phone-overflow rule — so the sheet is named for the ROOM and the prefix is
|
|
26
|
+
left alone. Renaming would churn a JS selector and a pinned test to buy a
|
|
27
|
+
reader nothing.
|
|
28
|
+
|
|
29
|
+
THE PANEL IS THE SHELL'S. The article, the failure notes and the skeleton all
|
|
30
|
+
carry `.scroll` in their markup and this sheet only adds the reading padding:
|
|
31
|
+
v3 has exactly three card levels and a fourth is a design decision, not a
|
|
32
|
+
local override (modules/hall-ui/CLAUDE.md, Hard rules).
|
|
33
|
+
|
|
34
|
+
Everything below spends the world's real token names. No compat alias
|
|
35
|
+
(--surface / --surface-2 / --border / --border-strong / --accent-weak /
|
|
36
|
+
--accent-text) appears here — they exist for pages nobody has re-skinned, so
|
|
37
|
+
spending one is legal CSS that quietly opts this sheet back out of the world.
|
|
38
|
+
`--line` is a WIDTH; the hairline's colour is --rule / --rule-soft. */
|
|
39
|
+
|
|
40
|
+
/* ---- the room's composition tokens ---------------------------------------
|
|
41
|
+
On `body`, never in a page `:root`: the branding pack's :root is spliced at
|
|
42
|
+
the end of <head> at (0,1,0), so a page-local one is outranked one way and
|
|
43
|
+
defeats re-branding the other.
|
|
44
|
+
--measure is NOT redeclared. It is the shell's measured 48ch, and a `ch`
|
|
45
|
+
scales with the font size — so the same token renders the same ~60 characters
|
|
46
|
+
whether the room reads at 15px or 17px. Re-deriving it per page size is the
|
|
47
|
+
`ch` arithmetic that put 90 characters on this page in the first place. */
|
|
48
|
+
body.room {
|
|
49
|
+
--room-gap: var(--sp-lg);
|
|
50
|
+
--room-toc-w: 246px;
|
|
51
|
+
--room-pad: clamp(24px, 3.4vw, 58px);
|
|
52
|
+
--room-size: 17px;
|
|
53
|
+
--room-lead: 1.75;
|
|
54
|
+
--room-h2: clamp(24px, 2.8vw, 34px);
|
|
55
|
+
--room-h3: 20px;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/* ---- 1. the reading hairline --------------------------------------------
|
|
59
|
+
Sticky rather than fixed: it belongs to the content column, so it scrolls out
|
|
60
|
+
of the way with the head instead of hovering over the whole viewport. Under
|
|
61
|
+
the topbar in the z ladder (--z-progress < --z-topbar) for the same reason —
|
|
62
|
+
it is the article's progress, not app chrome. */
|
|
63
|
+
.primer-progress {
|
|
64
|
+
position: sticky;
|
|
65
|
+
top: var(--topbar-h);
|
|
66
|
+
z-index: var(--z-progress);
|
|
67
|
+
height: 3px;
|
|
68
|
+
background: color-mix(in srgb, var(--accent) 14%, transparent);
|
|
69
|
+
pointer-events: none;
|
|
70
|
+
}
|
|
71
|
+
.primer-progress__bar {
|
|
72
|
+
height: 100%;
|
|
73
|
+
width: 0;
|
|
74
|
+
background: var(--accent);
|
|
75
|
+
transition: width 200ms cubic-bezier(.2, .7, .3, 1);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/* ---- 2. the reading column ----------------------------------------------
|
|
79
|
+
ONE ceiling for the room, on the room's own body scope. --content-max (1120)
|
|
80
|
+
is a working surface's width; a document read at it is more empty ground than
|
|
81
|
+
page. The cap sits on the room's main rather than on each page's wrapper so
|
|
82
|
+
the primer's two columns and the diagrams index's stacked figures end at the
|
|
83
|
+
same edge — a reading room that changes width between its own pages reads as
|
|
84
|
+
two different rooms.
|
|
85
|
+
This is the room's own composition, not a shell override: it is scoped to the
|
|
86
|
+
body class a page opts into, and it sets a measure, not shell layout (the
|
|
87
|
+
rule tests/hall_record_world.mjs pins is `.app-content > main`, which reaches
|
|
88
|
+
into the shell's grid for every page at once). */
|
|
89
|
+
body.room #hall-main,
|
|
90
|
+
body.room .page-head { max-width: var(--room-max); }
|
|
91
|
+
|
|
92
|
+
.primer-layout {
|
|
93
|
+
display: grid;
|
|
94
|
+
grid-template-columns: var(--room-toc-w) minmax(0, 1fr);
|
|
95
|
+
gap: var(--room-gap);
|
|
96
|
+
align-items: start;
|
|
97
|
+
padding-bottom: var(--sp-md);
|
|
98
|
+
}
|
|
99
|
+
/* the article column, so the notes, the skeleton and the gate stack under the
|
|
100
|
+
card rather than beside the contents */
|
|
101
|
+
.primer-col { min-width: 0; }
|
|
102
|
+
|
|
103
|
+
/* ---- 3. the table of contents, as glass ---------------------------------- */
|
|
104
|
+
|
|
105
|
+
.primer-toc {
|
|
106
|
+
position: sticky;
|
|
107
|
+
top: calc(var(--topbar-h) + var(--sp-md));
|
|
108
|
+
align-self: start;
|
|
109
|
+
}
|
|
110
|
+
.primer-toc__toggle {
|
|
111
|
+
display: none;
|
|
112
|
+
width: 100%;
|
|
113
|
+
align-items: center;
|
|
114
|
+
justify-content: space-between;
|
|
115
|
+
gap: 8px;
|
|
116
|
+
min-height: 44px;
|
|
117
|
+
padding: 8px 16px;
|
|
118
|
+
background: var(--glass);
|
|
119
|
+
-webkit-backdrop-filter: blur(var(--glass-blur));
|
|
120
|
+
backdrop-filter: blur(var(--glass-blur));
|
|
121
|
+
border: var(--line) solid var(--glass-edge);
|
|
122
|
+
border-radius: var(--radius);
|
|
123
|
+
font-family: var(--font-body);
|
|
124
|
+
font-size: 14.5px;
|
|
125
|
+
color: var(--ink);
|
|
126
|
+
cursor: pointer;
|
|
127
|
+
}
|
|
128
|
+
.primer-toc__chevron { transition: transform 200ms cubic-bezier(.2, .7, .3, 1); }
|
|
129
|
+
.primer-toc__toggle[aria-expanded="true"] .primer-toc__chevron { transform: rotate(180deg); }
|
|
130
|
+
.primer-toc__inner {
|
|
131
|
+
background: var(--glass);
|
|
132
|
+
-webkit-backdrop-filter: blur(var(--glass-blur));
|
|
133
|
+
backdrop-filter: blur(var(--glass-blur));
|
|
134
|
+
border: var(--line) solid var(--glass-edge);
|
|
135
|
+
border-radius: var(--radius);
|
|
136
|
+
padding: var(--sp-md) var(--sp-sm) var(--sp-sm);
|
|
137
|
+
}
|
|
138
|
+
.primer-toc__heading {
|
|
139
|
+
margin: 0 0 var(--sp-sm);
|
|
140
|
+
padding: 0 var(--sp-xs);
|
|
141
|
+
font-family: var(--label-face);
|
|
142
|
+
font-size: var(--label-size);
|
|
143
|
+
font-weight: 400;
|
|
144
|
+
letter-spacing: var(--label-space);
|
|
145
|
+
text-transform: var(--label-case);
|
|
146
|
+
color: var(--ink-faint);
|
|
147
|
+
}
|
|
148
|
+
.primer-toc__list { list-style: none; margin: 0; padding: 0; counter-reset: toc; }
|
|
149
|
+
.primer-toc__list li { margin: 0; }
|
|
150
|
+
/* the numeral is a two-digit mono column, so a long list never re-spaces around
|
|
151
|
+
its tenth row the way an upper-roman VIII did */
|
|
152
|
+
.primer-toc__list a {
|
|
153
|
+
display: flex;
|
|
154
|
+
align-items: baseline;
|
|
155
|
+
gap: 11px;
|
|
156
|
+
min-height: 34px;
|
|
157
|
+
padding: 8px var(--sp-xs);
|
|
158
|
+
border-left: 2px solid transparent;
|
|
159
|
+
border-radius: var(--radius-sm);
|
|
160
|
+
font-size: 14px;
|
|
161
|
+
line-height: 1.4;
|
|
162
|
+
color: var(--ink-soft);
|
|
163
|
+
text-decoration: none;
|
|
164
|
+
transition: color 200ms cubic-bezier(.2, .7, .3, 1);
|
|
165
|
+
}
|
|
166
|
+
.primer-toc__list a::before {
|
|
167
|
+
counter-increment: toc;
|
|
168
|
+
content: counter(toc, decimal-leading-zero);
|
|
169
|
+
flex: none;
|
|
170
|
+
font: 400 11px/1.4 var(--font-mono);
|
|
171
|
+
font-variant-numeric: tabular-nums;
|
|
172
|
+
color: var(--ink-faint);
|
|
173
|
+
}
|
|
174
|
+
.primer-toc__list a:hover { color: var(--ink); text-decoration: none; }
|
|
175
|
+
.primer-toc__list a.is-active {
|
|
176
|
+
color: var(--ink);
|
|
177
|
+
background: var(--glass-strong);
|
|
178
|
+
border-left-color: var(--accent);
|
|
179
|
+
border-radius: 0 var(--radius-sm) var(--radius-sm) 0;
|
|
180
|
+
}
|
|
181
|
+
.primer-toc__list a.is-active::before { color: var(--ink-soft); }
|
|
182
|
+
.primer-toc__placeholder {
|
|
183
|
+
padding: 8px var(--sp-xs);
|
|
184
|
+
font-size: 14px;
|
|
185
|
+
color: var(--ink-faint);
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
/* ---- 4. the article ------------------------------------------------------
|
|
189
|
+
The card itself is `.scroll`; this is the reading pad and the rhythm. */
|
|
190
|
+
|
|
191
|
+
.primer-article {
|
|
192
|
+
padding: var(--room-pad);
|
|
193
|
+
margin: 0;
|
|
194
|
+
counter-reset: sec;
|
|
195
|
+
font-size: var(--room-size);
|
|
196
|
+
line-height: var(--room-lead);
|
|
197
|
+
color: var(--ink);
|
|
198
|
+
}
|
|
199
|
+
/* PROSE is measured; a table, a figure and a code block may take the whole card,
|
|
200
|
+
and that width is the only reason the card is wider than the measure. */
|
|
201
|
+
.primer-article > p,
|
|
202
|
+
.primer-article > ul,
|
|
203
|
+
.primer-article > ol,
|
|
204
|
+
.primer-article > blockquote,
|
|
205
|
+
.primer-article > h2,
|
|
206
|
+
.primer-article > h3 { max-width: var(--measure); }
|
|
207
|
+
|
|
208
|
+
/* the document's own h1 is suppressed — the page head already names the room,
|
|
209
|
+
and a second h1 in <main> fails the one-header-main-h1 floor outright */
|
|
210
|
+
.primer-article h1 { display: none; }
|
|
211
|
+
|
|
212
|
+
.primer-article h2 {
|
|
213
|
+
margin: calc(var(--sp-xl) * 1.4) 0 var(--sp-md);
|
|
214
|
+
font-family: var(--font-display);
|
|
215
|
+
font-weight: 300;
|
|
216
|
+
font-size: var(--room-h2);
|
|
217
|
+
line-height: 1.06;
|
|
218
|
+
letter-spacing: -0.035em;
|
|
219
|
+
color: var(--ink);
|
|
220
|
+
/* anchor jumps land below the sticky top bar AND its hairline */
|
|
221
|
+
scroll-margin-top: calc(var(--topbar-h) + 28px);
|
|
222
|
+
}
|
|
223
|
+
/* the section number sits above the headline rather than beside it, so a long
|
|
224
|
+
title stays one uninterrupted shape at every width */
|
|
225
|
+
.primer-article h2::before {
|
|
226
|
+
counter-increment: sec;
|
|
227
|
+
content: counter(sec, decimal-leading-zero);
|
|
228
|
+
display: block;
|
|
229
|
+
margin-bottom: 14px;
|
|
230
|
+
font-family: var(--label-face);
|
|
231
|
+
font-size: var(--label-size);
|
|
232
|
+
letter-spacing: var(--label-space);
|
|
233
|
+
font-variant-numeric: tabular-nums;
|
|
234
|
+
color: var(--ink-faint);
|
|
235
|
+
}
|
|
236
|
+
.primer-article > h2:first-child { margin-top: 0; }
|
|
237
|
+
.primer-article h3 {
|
|
238
|
+
margin: var(--sp-lg) 0 var(--sp-xs);
|
|
239
|
+
font-family: var(--font-display);
|
|
240
|
+
font-weight: 400;
|
|
241
|
+
font-size: var(--room-h3);
|
|
242
|
+
letter-spacing: -0.02em;
|
|
243
|
+
color: var(--ink);
|
|
244
|
+
scroll-margin-top: calc(var(--topbar-h) + 28px);
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
.primer-article p { margin: 0 0 var(--sp-md); }
|
|
248
|
+
.primer-article p:last-child { margin-bottom: 0; }
|
|
249
|
+
/* the subtitle line at the very top of the document */
|
|
250
|
+
.primer-article > p > em:only-child { color: var(--ink-soft); }
|
|
251
|
+
|
|
252
|
+
.primer-article ul, .primer-article ol { margin: 0 0 var(--sp-lg); padding-left: 1.4em; }
|
|
253
|
+
.primer-article li { margin: 0 0 12px; }
|
|
254
|
+
.primer-article li:last-child { margin-bottom: 0; }
|
|
255
|
+
.primer-article li::marker { color: var(--ink-faint); }
|
|
256
|
+
|
|
257
|
+
/* 1px of vertical padding takes an inline link past the 24px floor without
|
|
258
|
+
costing the line its own leading (the .scroll__lede precedent, task 1003304) */
|
|
259
|
+
.primer-article a {
|
|
260
|
+
display: inline-block;
|
|
261
|
+
min-height: 24px;
|
|
262
|
+
padding: 1px 0;
|
|
263
|
+
color: var(--accent-ink);
|
|
264
|
+
text-decoration: underline;
|
|
265
|
+
text-underline-offset: 4px;
|
|
266
|
+
text-decoration-thickness: 1px;
|
|
267
|
+
}
|
|
268
|
+
.primer-article a:hover { color: var(--ink); }
|
|
269
|
+
.primer-article strong { font-weight: 600; color: var(--ink); }
|
|
270
|
+
.primer-article em { font-style: italic; }
|
|
271
|
+
|
|
272
|
+
.primer-article code {
|
|
273
|
+
font: 400 .85em/1.4 var(--font-mono);
|
|
274
|
+
background: var(--glass);
|
|
275
|
+
padding: 2px 6px;
|
|
276
|
+
border-radius: 4px;
|
|
277
|
+
}
|
|
278
|
+
.primer-article pre {
|
|
279
|
+
margin: 0 0 var(--sp-lg);
|
|
280
|
+
padding: var(--sp-md) var(--sp-lg);
|
|
281
|
+
overflow-x: auto;
|
|
282
|
+
background: var(--glass);
|
|
283
|
+
border: var(--line) solid var(--glass-edge);
|
|
284
|
+
border-radius: var(--radius);
|
|
285
|
+
}
|
|
286
|
+
.primer-article pre code {
|
|
287
|
+
background: none;
|
|
288
|
+
padding: 0;
|
|
289
|
+
border-radius: 0;
|
|
290
|
+
font-size: 13.5px;
|
|
291
|
+
line-height: 1.8;
|
|
292
|
+
color: var(--ink-soft);
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
/* blockquotes only render since task 1003306 unified the two markdown parsers —
|
|
296
|
+
primer.js had no blockquote rule at all and md-reader.js has always emitted
|
|
297
|
+
them, so the primer silently dropped every aside into a paragraph. */
|
|
298
|
+
.primer-article blockquote {
|
|
299
|
+
margin: var(--sp-lg) 0;
|
|
300
|
+
padding: var(--sp-md) var(--sp-lg);
|
|
301
|
+
background: var(--glass);
|
|
302
|
+
border: var(--line) solid var(--glass-edge);
|
|
303
|
+
border-left: 2px solid var(--rule);
|
|
304
|
+
border-radius: 0 var(--radius) var(--radius) 0;
|
|
305
|
+
color: var(--ink-soft);
|
|
306
|
+
}
|
|
307
|
+
.primer-article blockquote p { margin: 0; max-width: var(--measure); }
|
|
308
|
+
|
|
309
|
+
.primer-article hr {
|
|
310
|
+
border: none;
|
|
311
|
+
border-top: var(--line) solid var(--rule-soft);
|
|
312
|
+
margin: var(--sp-xl) 0;
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
.primer-article table {
|
|
316
|
+
width: 100%;
|
|
317
|
+
border-collapse: collapse;
|
|
318
|
+
margin: 0 0 var(--sp-lg);
|
|
319
|
+
font-size: 14.5px;
|
|
320
|
+
font-variant-numeric: tabular-nums;
|
|
321
|
+
}
|
|
322
|
+
.primer-article th, .primer-article td {
|
|
323
|
+
text-align: left;
|
|
324
|
+
vertical-align: top;
|
|
325
|
+
padding: 13px 16px 13px 0;
|
|
326
|
+
border-bottom: var(--line) solid var(--rule-soft);
|
|
327
|
+
}
|
|
328
|
+
.primer-article th {
|
|
329
|
+
font-family: var(--label-face);
|
|
330
|
+
font-size: var(--label-size);
|
|
331
|
+
font-weight: 400;
|
|
332
|
+
letter-spacing: var(--label-space);
|
|
333
|
+
text-transform: var(--label-case);
|
|
334
|
+
color: var(--ink-faint);
|
|
335
|
+
}
|
|
336
|
+
.primer-article tr:last-child td { border-bottom: 0; }
|
|
337
|
+
|
|
338
|
+
/* ---- 5. the framed figure ------------------------------------------------
|
|
339
|
+
ONE rule, both rooms: diagram-viewer.js upgrades `figure.diagram img,
|
|
340
|
+
figure.primer-figure img` into a pannable canvas, and until (or unless) the
|
|
341
|
+
SVG fetch succeeds the PNG stays in this frame. Glass rather than a card, so
|
|
342
|
+
a figure inside the article reads as inset and a figure on the diagrams index
|
|
343
|
+
reads as the same object. */
|
|
344
|
+
.primer-figure, figure.diagram {
|
|
345
|
+
margin: var(--sp-xl) 0;
|
|
346
|
+
padding: var(--sp-lg) var(--sp-md);
|
|
347
|
+
background: var(--glass);
|
|
348
|
+
border: var(--line) solid var(--glass-edge);
|
|
349
|
+
border-radius: var(--radius);
|
|
350
|
+
}
|
|
351
|
+
.primer-figure:last-child, figure.diagram:last-child { margin-bottom: 0; }
|
|
352
|
+
.primer-figure img, figure.diagram img {
|
|
353
|
+
display: block;
|
|
354
|
+
width: 100%;
|
|
355
|
+
max-width: 100%;
|
|
356
|
+
height: auto;
|
|
357
|
+
}
|
|
358
|
+
/* diagram-viewer.js inserts its canvas INSIDE the figure and hides the <img>,
|
|
359
|
+
so the frame has to belong to exactly one of them or the diagram ends up in
|
|
360
|
+
two nested boxes. The figure keeps it; the canvas gives its own up. (Its
|
|
361
|
+
fullscreen state re-declares both, and diagram-viewer.css loads after this
|
|
362
|
+
sheet on both pages, so the overlay still paints.) */
|
|
363
|
+
.primer-figure .dgv, figure.diagram .dgv {
|
|
364
|
+
background: none;
|
|
365
|
+
border: 0;
|
|
366
|
+
border-radius: var(--radius-sm);
|
|
367
|
+
}
|
|
368
|
+
.primer-figure figcaption, figure.diagram figcaption {
|
|
369
|
+
margin-top: 14px;
|
|
370
|
+
max-width: var(--measure);
|
|
371
|
+
font-size: 13.5px;
|
|
372
|
+
line-height: 1.55;
|
|
373
|
+
color: var(--ink-faint);
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
/* ---- 6. the states before the document ----------------------------------
|
|
377
|
+
Each is the same card the article is, so the page never changes shape as it
|
|
378
|
+
resolves — the skeleton is the article's silhouette, not a spinner. */
|
|
379
|
+
|
|
380
|
+
.primer-note, .primer-skeleton { padding: var(--room-pad); }
|
|
381
|
+
.primer-note__label {
|
|
382
|
+
margin: 0 0 14px;
|
|
383
|
+
font-family: var(--label-face);
|
|
384
|
+
font-size: var(--label-size);
|
|
385
|
+
letter-spacing: var(--label-space);
|
|
386
|
+
text-transform: var(--label-case);
|
|
387
|
+
color: var(--ink-faint);
|
|
388
|
+
}
|
|
389
|
+
.primer-note--error .primer-note__label { color: var(--danger); }
|
|
390
|
+
.primer-note__body { margin: 0 0 var(--sp-lg); max-width: var(--measure); color: var(--ink-soft); }
|
|
391
|
+
.primer-note__body:last-child { margin-bottom: 0; }
|
|
392
|
+
.primer-note__acts { display: flex; flex-wrap: wrap; gap: var(--sp-xs); margin: 0; }
|
|
393
|
+
|
|
394
|
+
.primer-sk {
|
|
395
|
+
display: block;
|
|
396
|
+
height: 10px;
|
|
397
|
+
border-radius: 4px;
|
|
398
|
+
background: var(--skeleton);
|
|
399
|
+
}
|
|
400
|
+
.primer-skeleton__h { height: 28px; width: 58%; margin-bottom: var(--sp-lg); }
|
|
401
|
+
.primer-skeleton__p { margin-bottom: var(--sp-lg); max-width: var(--measure); }
|
|
402
|
+
.primer-skeleton__p .primer-sk { margin-bottom: 15px; }
|
|
403
|
+
.primer-skeleton__p .primer-sk:nth-child(2) { width: 96%; }
|
|
404
|
+
.primer-skeleton__p .primer-sk:nth-child(3) { width: 99%; }
|
|
405
|
+
.primer-skeleton__p .primer-sk:nth-child(4) { width: 84%; }
|
|
406
|
+
.primer-skeleton__p .primer-sk:last-child { width: 46%; margin-bottom: 0; }
|
|
407
|
+
.primer-skeleton__rule {
|
|
408
|
+
height: var(--line);
|
|
409
|
+
margin: var(--sp-xl) 0 var(--sp-lg);
|
|
410
|
+
background: var(--rule-soft);
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
/* ---- 7. the room's one breakpoint ---------------------------------------
|
|
414
|
+
760px, NOT the shell's 640: it is the width primer.js's matchMedia mirrors
|
|
415
|
+
and tests/hall_audit.mjs pins exactly. Narrowing it "for consistency" would
|
|
416
|
+
silently reopen the 641-760px band the table's scrollport exists to cover. */
|
|
417
|
+
@media (max-width: 760px) {
|
|
418
|
+
body.room {
|
|
419
|
+
--room-gap: 0px;
|
|
420
|
+
--room-pad: 20px;
|
|
421
|
+
--room-size: 16.5px;
|
|
422
|
+
--room-lead: 1.7;
|
|
423
|
+
--room-h2: 24px;
|
|
424
|
+
}
|
|
425
|
+
.primer-layout { grid-template-columns: minmax(0, 1fr); }
|
|
426
|
+
.primer-toc { position: static; margin-bottom: var(--sp-sm); }
|
|
427
|
+
.primer-toc__toggle { display: flex; }
|
|
428
|
+
.primer-toc__inner { display: none; margin-top: 8px; }
|
|
429
|
+
.primer-toc.is-open .primer-toc__inner { display: block; }
|
|
430
|
+
/* A markdown table's column count is fixed by its source, so its min-content
|
|
431
|
+
width outruns a phone (measured: 79px of page overflow on /drachmae). Give
|
|
432
|
+
the table its own horizontal scroller instead of letting it drag the page
|
|
433
|
+
sideways. `display: block` is what makes the table box a scrollport; the
|
|
434
|
+
rows still lay out through the anonymous table box inside it. */
|
|
435
|
+
.primer-article table {
|
|
436
|
+
display: block;
|
|
437
|
+
width: max-content;
|
|
438
|
+
max-width: 100%;
|
|
439
|
+
overflow-x: auto;
|
|
440
|
+
}
|
|
441
|
+
}
|