@wxxb789/anc 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +295 -0
- package/astro.config.mjs +255 -0
- package/bin/anc.mjs +798 -0
- package/package.json +93 -0
- package/public/_headers +45 -0
- package/public/favicon.ico +0 -0
- package/public/favicon.svg +9 -0
- package/public/fonts/Temml.woff2 +0 -0
- package/scripts/build-snapshot.js +69 -0
- package/scripts/build-wasm.js +67 -0
- package/scripts/build-workspace.js +50 -0
- package/scripts/copy-snapshot.js +48 -0
- package/scripts/copy-wasm.js +57 -0
- package/scripts/emit-redirects.js +64 -0
- package/scripts/generate-corpus.js +421 -0
- package/scripts/init-repository.js +249 -0
- package/scripts/load-config.js +975 -0
- package/scripts/markdown-to-artifact.js +1286 -0
- package/scripts/preview-site.js +364 -0
- package/scripts/publish-set-review.js +157 -0
- package/scripts/resolve-links.js +640 -0
- package/scripts/run-pagefind.js +125 -0
- package/scripts/scan-residue.js +1016 -0
- package/scripts/scan-secrets.js +268 -0
- package/scripts/seed-gitignore.js +410 -0
- package/scripts/snapshot-rows.js +205 -0
- package/scripts/validate-content.js +95 -0
- package/scripts/vendor-provenance.js +307 -0
- package/scripts/verify-output-inventory.js +307 -0
- package/scripts/write-report.js +351 -0
- package/scripts/write-snapshot.js +136 -0
- package/src/components/CollectionExplorer.astro +149 -0
- package/src/components/FacetIndex.astro +45 -0
- package/src/components/LinkedNotes.astro +94 -0
- package/src/components/NoteGraph.astro +434 -0
- package/src/components/NoteList.astro +54 -0
- package/src/components/SiteMetadata.astro +143 -0
- package/src/components/TableOfContents.astro +69 -0
- package/src/components/TagBrowser.astro +70 -0
- package/src/layouts/Layout.astro +305 -0
- package/src/lib/artifact-source.js +72 -0
- package/src/lib/build-bindings.js +11 -0
- package/src/lib/collection-navigation.js +145 -0
- package/src/lib/content.js +92 -0
- package/src/lib/diagram-mode.js +18 -0
- package/src/lib/graph-layout.js +219 -0
- package/src/lib/graph-selection.js +84 -0
- package/src/lib/graph.js +42 -0
- package/src/lib/link-resolution.js +389 -0
- package/src/lib/markdown.js +1469 -0
- package/src/lib/math-mode.js +31 -0
- package/src/lib/math-output.js +131 -0
- package/src/lib/math.js +165 -0
- package/src/lib/mermaid-environment.js +475 -0
- package/src/lib/mermaid-render.js +769 -0
- package/src/lib/preview-model.js +96 -0
- package/src/lib/relations.js +242 -0
- package/src/lib/rendered-marker.js +55 -0
- package/src/lib/route-path.js +192 -0
- package/src/lib/routes.js +342 -0
- package/src/lib/schema.js +578 -0
- package/src/lib/site.js +578 -0
- package/src/lib/snapshot-contract.js +216 -0
- package/src/lib/snapshot-operations.js +147 -0
- package/src/lib/snapshot-queries.js +216 -0
- package/src/lib/snapshot-reader.js +210 -0
- package/src/lib/snapshot.js +233 -0
- package/src/lib/sqlite-warning.js +22 -0
- package/src/lib/sqlite.js +14 -0
- package/src/lib/tag-browser-model.js +18 -0
- package/src/lib/translations.js +533 -0
- package/src/lib/wasm-asset.js +47 -0
- package/src/lib/worker-protocol.js +93 -0
- package/src/pages/404.astro +35 -0
- package/src/pages/about.astro +100 -0
- package/src/pages/collections/[slug].astro +36 -0
- package/src/pages/collections/index.astro +33 -0
- package/src/pages/graph.astro +64 -0
- package/src/pages/index.astro +33 -0
- package/src/pages/notes/[slug].astro +509 -0
- package/src/pages/privacy.astro +121 -0
- package/src/pages/private.astro +59 -0
- package/src/pages/recent.astro +33 -0
- package/src/pages/robots.txt.js +15 -0
- package/src/pages/rss.xml.js +21 -0
- package/src/pages/sitemap.xml.js +20 -0
- package/src/pages/tags/[tag].astro +56 -0
- package/src/pages/tags/index.astro +37 -0
- package/src/scripts/code-copy.js +45 -0
- package/src/scripts/diagram-disabled.js +16 -0
- package/src/scripts/diagram.js +322 -0
- package/src/scripts/graph-client.js +222 -0
- package/src/scripts/graph-draw.js +166 -0
- package/src/scripts/link-preview.js +334 -0
- package/src/scripts/math-disabled.js +18 -0
- package/src/scripts/math.js +133 -0
- package/src/scripts/preferences.js +123 -0
- package/src/scripts/search-dialog.js +651 -0
- package/src/scripts/snapshot-client.js +157 -0
- package/src/scripts/snapshot-worker.js +341 -0
- package/src/scripts/tag-browser.js +153 -0
- package/src/scripts/theme-init.js +35 -0
- package/src/scripts/toc-active.js +38 -0
- package/src/styles/code.css +152 -0
- package/src/styles/diagram.css +149 -0
- package/src/styles/global.css +1739 -0
- package/src/styles/graph.css +317 -0
- package/src/styles/math.css +376 -0
- package/src/styles/tokens.css +171 -0
- package/tsconfig.json +25 -0
|
@@ -0,0 +1,317 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* The graph.
|
|
3
|
+
*
|
|
4
|
+
* Loaded on every page that draws one, via a conditional `<link>` gated on the
|
|
5
|
+
* graph having edges — owner decision 7's pattern, the same way `code.css` and
|
|
6
|
+
* `diagram.css` reach only the pages that need them. A note with no
|
|
7
|
+
* neighbourhood requests nothing.
|
|
8
|
+
*
|
|
9
|
+
* **The region's own frame is in `global.css`, not here**, and that split is a
|
|
10
|
+
* fix rather than a preference: the region renders on every note page, with an
|
|
11
|
+
* empty state where there is no neighbourhood, so a frame in this conditional
|
|
12
|
+
* sheet left that empty state unstyled on every page of the published site.
|
|
13
|
+
* What lives here is only what a page that actually draws a figure needs.
|
|
14
|
+
*
|
|
15
|
+
* **Nothing here carries information by colour alone** (WCAG 1.4.1,
|
|
16
|
+
* requirements section 17). The three edge directions are three line *shapes*:
|
|
17
|
+
* an outgoing edge is solid with one arrowhead, an incoming one dashed, a
|
|
18
|
+
* mutual one solid with an arrowhead at each end. The subject node is larger
|
|
19
|
+
* and ringed. Every one of those distinctions survives a monochrome print and a
|
|
20
|
+
* reader who cannot see hue at all — and each node's accessible name states its
|
|
21
|
+
* relationship in words regardless.
|
|
22
|
+
*
|
|
23
|
+
* **No animation, so `prefers-reduced-motion` needs no rule.** The layout is
|
|
24
|
+
* computed at build time and never moves; there is no force simulation to
|
|
25
|
+
* settle and no transition to suppress. The global reduce block in `global.css`
|
|
26
|
+
* still covers the focus transitions this file inherits.
|
|
27
|
+
*
|
|
28
|
+
* Colour comes from the same tokens as everything else, so both themes follow
|
|
29
|
+
* `light-dark()` with no second palette and no script.
|
|
30
|
+
*/
|
|
31
|
+
|
|
32
|
+
.graph {
|
|
33
|
+
margin-block: var(--space-6);
|
|
34
|
+
/* `figure` carries a user-agent `margin-inline: 40px` that would indent the
|
|
35
|
+
graph relative to the prose around it. */
|
|
36
|
+
margin-inline: 0;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
.graph-canvas {
|
|
40
|
+
/* A graph wider than the measure scrolls rather than widening the page.
|
|
41
|
+
`tabindex="0"` is on the element in the markup: a scrollable region must be
|
|
42
|
+
reachable by keyboard, and the browser then scrolls it with the arrows.
|
|
43
|
+
The focus ring comes from `global.css`'s universal `:focus-visible`, which
|
|
44
|
+
already sets exactly this outline — restating it here was 87 bytes of a
|
|
45
|
+
conditional stylesheet that changed no computed value. */
|
|
46
|
+
overflow-x: auto;
|
|
47
|
+
text-align: center;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/*
|
|
51
|
+
* The figure scrolls rather than shrinking past legibility.
|
|
52
|
+
*
|
|
53
|
+
* `min-width` is what makes the scroll container real. With `max-width: 100%`
|
|
54
|
+
* alone the SVG always fits its parent, so `overflow-x: auto` could never
|
|
55
|
+
* trigger and the `tabindex="0"` beside it was a focus stop that did nothing —
|
|
56
|
+
* while a 60-node `/graph/` squeezed into 320 px rendered its labels at about
|
|
57
|
+
* five CSS pixels. Below this width the figure scrolls sideways instead, which
|
|
58
|
+
* is the same treatment a wide diagram and a wide code fence already get.
|
|
59
|
+
*
|
|
60
|
+
* `max-width: 100%` still caps it on a wide viewport, and without `height:
|
|
61
|
+
* auto` the browser keeps the attribute height and distorts the aspect ratio.
|
|
62
|
+
* The `width` and `height` attributes hold the intrinsic size, so the figure
|
|
63
|
+
* has a ratio before this stylesheet arrives and nothing shifts when it does.
|
|
64
|
+
*/
|
|
65
|
+
.graph-svg {
|
|
66
|
+
display: block;
|
|
67
|
+
margin-inline: auto;
|
|
68
|
+
min-width: 22rem;
|
|
69
|
+
max-width: 100%;
|
|
70
|
+
height: auto;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
.graph-edge {
|
|
74
|
+
stroke: var(--color-line-strong);
|
|
75
|
+
stroke-width: 1.5;
|
|
76
|
+
fill: none;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/*
|
|
80
|
+
* An edge the reader's note *receives* is dashed; one it *sends* is solid.
|
|
81
|
+
*
|
|
82
|
+
* Shape, not hue — this is the whole of requirements section 13.2's "incoming
|
|
83
|
+
* and outgoing edges visually distinguished" and section 17's "no information
|
|
84
|
+
* encoded by color alone". The dash pattern is coarse enough to read at the
|
|
85
|
+
* scale a 320 px viewport shrinks the figure to.
|
|
86
|
+
*
|
|
87
|
+
* Only the subject's own neighbourhood has a direction at all: `/graph/` has no
|
|
88
|
+
* subject, so its edges are all plain solid, which is honest — there is no
|
|
89
|
+
* "incoming" without a somewhere to come in to.
|
|
90
|
+
*/
|
|
91
|
+
.graph-edge-incoming {
|
|
92
|
+
stroke-dasharray: 6 4;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/* A mutual edge carries an arrowhead at both ends, which is its distinction.
|
|
96
|
+
It is drawn slightly heavier so the pair reads as one relationship rather
|
|
97
|
+
than as a line somebody drew twice. */
|
|
98
|
+
.graph-edge-mutual {
|
|
99
|
+
stroke-width: 2;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
.graph-arrow {
|
|
103
|
+
fill: var(--color-line-strong);
|
|
104
|
+
stroke: none;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
.graph-dot {
|
|
108
|
+
fill: var(--color-surface);
|
|
109
|
+
stroke: var(--color-link);
|
|
110
|
+
stroke-width: 2;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/*
|
|
114
|
+
* The note the reader is on: larger, filled, and ringed.
|
|
115
|
+
*
|
|
116
|
+
* Three distinctions rather than one, because a reader who cannot see the fill
|
|
117
|
+
* colour still meets a bigger circle with a heavier edge. Requirements section
|
|
118
|
+
* 13.2 asks for the current page emphasized; the node's accessible name also
|
|
119
|
+
* says "this note" in words.
|
|
120
|
+
*/
|
|
121
|
+
.graph-node-subject .graph-dot {
|
|
122
|
+
fill: var(--color-accent);
|
|
123
|
+
stroke: var(--color-accent);
|
|
124
|
+
stroke-width: 3;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
.graph-label {
|
|
128
|
+
fill: var(--color-text);
|
|
129
|
+
/* `px` rather than `rem`: the label is positioned in the SVG's own user units
|
|
130
|
+
and the `viewBox` scales the whole figure with the reader's text size
|
|
131
|
+
already, so a `rem` here would scale it twice and push labels over their
|
|
132
|
+
neighbours. */
|
|
133
|
+
font-size: 13px;
|
|
134
|
+
font-family: var(--font-sans);
|
|
135
|
+
text-anchor: middle;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
.graph-node-subject .graph-label {
|
|
139
|
+
font-weight: 650;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
/*
|
|
143
|
+
* The focus ring, on the node rather than on the anchor's bounding box.
|
|
144
|
+
*
|
|
145
|
+
* An `<a>` wrapping SVG shapes has a bounding box that spans the circle and its
|
|
146
|
+
* label, so the default ring is a wide rectangle that overlaps its neighbours'.
|
|
147
|
+
* Ringing the circle itself puts the indicator on the thing the reader is
|
|
148
|
+
* actually on. `outline` on an SVG child is honoured by every current engine;
|
|
149
|
+
* the stroke change is what carries it where it is not, so the indicator can
|
|
150
|
+
* never be absent (WCAG 2.4.7).
|
|
151
|
+
*/
|
|
152
|
+
.graph-node:focus-visible {
|
|
153
|
+
outline: none;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
.graph-node:focus-visible .graph-dot {
|
|
157
|
+
stroke: var(--color-focus);
|
|
158
|
+
stroke-width: 4;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
.graph-node:focus-visible .graph-label,
|
|
162
|
+
.graph-node:hover .graph-label {
|
|
163
|
+
fill: var(--color-link);
|
|
164
|
+
text-decoration: underline;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
.graph-node:hover .graph-dot {
|
|
168
|
+
fill: var(--color-wash);
|
|
169
|
+
stroke: var(--color-link);
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
/* The figcaption carries the derivation — how the layout was built, which a
|
|
173
|
+
reader cannot see by looking at it. */
|
|
174
|
+
.graph figcaption {
|
|
175
|
+
max-width: var(--measure);
|
|
176
|
+
margin-top: var(--space-2);
|
|
177
|
+
color: var(--color-muted);
|
|
178
|
+
font-size: var(--text-sm);
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
/*
|
|
182
|
+
* The equivalent table, in a native disclosure.
|
|
183
|
+
*
|
|
184
|
+
* `<details>` rather than an always-open table: the same data twice in a row is
|
|
185
|
+
* a long page, and the native element is keyboard-operable, announced as one
|
|
186
|
+
* control, and costs no script. No `interpolate-size` transition here — the
|
|
187
|
+
* explorer's collapse animates because it is navigation a reader opens
|
|
188
|
+
* repeatedly; this one is opened once, and an animation would be motion with no
|
|
189
|
+
* purpose to justify it.
|
|
190
|
+
*/
|
|
191
|
+
.graph-table {
|
|
192
|
+
margin-top: var(--space-6);
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
.graph-table summary {
|
|
196
|
+
padding: var(--space-2) 0;
|
|
197
|
+
color: var(--color-link);
|
|
198
|
+
cursor: pointer;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
/*
|
|
202
|
+
* The table's own scroll container.
|
|
203
|
+
*
|
|
204
|
+
* Four columns do not fit 320 px — the narrowest supported viewport — and the
|
|
205
|
+
* article's Markdown tables have the same problem with no fix, because a
|
|
206
|
+
* wrapper is the pipeline's to emit and `display: block` on the `<table>`
|
|
207
|
+
* itself would strip its semantics (TK-02's deferral, still recorded in
|
|
208
|
+
* `global.css`). This table is rendered by a component, so the wrapper is
|
|
209
|
+
* simply written.
|
|
210
|
+
*
|
|
211
|
+
* Its `tabindex="0"` is unconditional even though the container only scrolls at
|
|
212
|
+
* narrow widths — measured: 350 px of content in 288 px at 320 px, and no
|
|
213
|
+
* overflow at 768 or 1280. That is the same shape `<pre>` and `.diagram-canvas`
|
|
214
|
+
* already have, and for the same reason: whether a region scrolls depends on
|
|
215
|
+
* the viewport and on the content, so the alternative is a keyboard stop that
|
|
216
|
+
* appears and disappears as a reader resizes. This is not the dead stop the
|
|
217
|
+
* figure's own `min-width` fixed — that one could *never* scroll at any width,
|
|
218
|
+
* which is a different fault.
|
|
219
|
+
*/
|
|
220
|
+
.graph-table-scroll {
|
|
221
|
+
overflow-x: auto;
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
.graph-table table {
|
|
225
|
+
width: 100%;
|
|
226
|
+
margin-top: var(--space-2);
|
|
227
|
+
border-collapse: collapse;
|
|
228
|
+
font-size: var(--text-sm);
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
.graph-table th,
|
|
232
|
+
.graph-table td {
|
|
233
|
+
padding: var(--space-2);
|
|
234
|
+
border-bottom: 1px solid var(--color-line-strong);
|
|
235
|
+
text-align: left;
|
|
236
|
+
/* A title is the one cell that can be long, and a long one would otherwise
|
|
237
|
+
set the column's width from its longest unbroken word. Wrapping keeps the
|
|
238
|
+
table close to its container; the scroll wrapper above is what handles the
|
|
239
|
+
rest, since four columns do not fit 320 px however they wrap. */
|
|
240
|
+
overflow-wrap: break-word;
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
.graph-table thead th {
|
|
244
|
+
color: var(--color-muted);
|
|
245
|
+
font-weight: 650;
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
.graph-table tbody th {
|
|
249
|
+
font-weight: 400;
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
/* The degree column, which is the one cell holding a bare number. */
|
|
253
|
+
.graph-table td:nth-child(3) {
|
|
254
|
+
text-align: right;
|
|
255
|
+
font-variant-numeric: tabular-nums;
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
/* The notes at the other end of a row's lines: a list, not a sentence, so a
|
|
259
|
+
screen reader announces how many there are before reading them. */
|
|
260
|
+
.graph-joined {
|
|
261
|
+
margin: 0;
|
|
262
|
+
padding: 0;
|
|
263
|
+
list-style: none;
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
.graph-none {
|
|
267
|
+
color: var(--color-muted);
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
.graph-bound {
|
|
271
|
+
max-width: var(--measure);
|
|
272
|
+
margin-top: var(--space-4);
|
|
273
|
+
color: var(--color-muted);
|
|
274
|
+
font-size: var(--text-sm);
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
@media print {
|
|
278
|
+
/* A scroll container prints as its visible window, cutting the figure off at
|
|
279
|
+
the page edge. Letting it size itself prints the whole graph. */
|
|
280
|
+
.graph-canvas {
|
|
281
|
+
overflow-x: visible;
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
/*
|
|
285
|
+
* The table is the graph's equivalent representation (requirements section
|
|
286
|
+
* 17), so a printed page has to carry it — and a closed `<details>` prints
|
|
287
|
+
* closed, which drops it from paper entirely.
|
|
288
|
+
*
|
|
289
|
+
* `content-visibility: visible` on `::details-content` is what opens it:
|
|
290
|
+
* `details[open]` cannot be set from CSS, and Chromium hides a closed
|
|
291
|
+
* disclosure's content with `content-visibility: hidden` on that
|
|
292
|
+
* pseudo-element rather than with `display`. This repository already measured
|
|
293
|
+
* that once — `tests/rendered-page.test.ts` records it for the explorer rail's
|
|
294
|
+
* collapse — and two earlier versions of this rule ignored it: one set only
|
|
295
|
+
* `list-style: none`, the other overrode `display` on a `<div>` that was
|
|
296
|
+
* already block. Both left the table off the printed page while claiming in a
|
|
297
|
+
* comment to have fixed it. Verified by `checkVisibility()` on a body cell
|
|
298
|
+
* under `media: print`, not by reading a bounding box, which a hidden element
|
|
299
|
+
* still reports.
|
|
300
|
+
*
|
|
301
|
+
* The marker goes because a disclosure triangle on paper points at an
|
|
302
|
+
* interaction nobody can perform.
|
|
303
|
+
*/
|
|
304
|
+
.graph-table > summary {
|
|
305
|
+
list-style: none;
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
.graph-table::details-content {
|
|
309
|
+
content-visibility: visible;
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
.graph-table-scroll {
|
|
313
|
+
/* A scroll container prints as its visible window, cutting the right-hand
|
|
314
|
+
columns off at the page edge. */
|
|
315
|
+
overflow-x: visible;
|
|
316
|
+
}
|
|
317
|
+
}
|
|
@@ -0,0 +1,376 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Math.
|
|
3
|
+
*
|
|
4
|
+
* Loaded only on pages whose body contains an expression, via the conditional
|
|
5
|
+
* `<link>` in `src/pages/notes/[slug].astro` gated on `RenderedNote.hasMath` —
|
|
6
|
+
* owner decision 7. A page with no math pays nothing, which is asserted by
|
|
7
|
+
* `tests/math-and-diagrams.test.ts` in both directions.
|
|
8
|
+
*
|
|
9
|
+
* Temml's own stylesheet is vendored below rather than imported from
|
|
10
|
+
* `node_modules`, for two reasons that are properties of this project rather
|
|
11
|
+
* than preferences. It must be **same-origin** — requirements §19.3 sets
|
|
12
|
+
* `style-src 'self'` and `font-src 'self'`, so the upstream advice to load it
|
|
13
|
+
* from a CDN is not available. And it must be **edited**: upstream declares
|
|
14
|
+
* `src: url('Temml.woff2')`, a relative reference that resolves against
|
|
15
|
+
* whatever path the sheet is served from, which is not where Astro puts the
|
|
16
|
+
* font. The `@font-face` below points at `/fonts/Temml.woff2`, copied verbatim
|
|
17
|
+
* from the package by `public/fonts/`.
|
|
18
|
+
*
|
|
19
|
+
* Sections marked "Temml 0.13.4" are upstream, trimmed to the rules this
|
|
20
|
+
* projection can reach: the Firefox and WebKit correction blocks are kept
|
|
21
|
+
* whole, because they are what makes an accent sit in the right place in those
|
|
22
|
+
* browsers, and dropping them would ship subtly wrong typesetting to half the
|
|
23
|
+
* readers. What is dropped is the `\cancelto` mask image — a `data:image/svg+xml`
|
|
24
|
+
* URL that the privacy residue scan rejects as a non-image `data:` URL, and
|
|
25
|
+
* whose command (`\cancelto`) reaches nothing in this corpus.
|
|
26
|
+
*/
|
|
27
|
+
|
|
28
|
+
@font-face {
|
|
29
|
+
font-family: 'Temml';
|
|
30
|
+
src: url('/fonts/Temml.woff2') format('woff2');
|
|
31
|
+
font-weight: normal;
|
|
32
|
+
font-style: normal;
|
|
33
|
+
/* The font supplies exactly the script capitals in U+1D49C–U+1D4B5. Naming
|
|
34
|
+
the range means a browser fetches it only for an expression that uses
|
|
35
|
+
`\mathscr`, so most math pages never request the 9.4 KB at all. */
|
|
36
|
+
unicode-range: U+1D49C-1D4B5;
|
|
37
|
+
font-display: swap;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
math {
|
|
41
|
+
font-family: 'Cambria Math', 'STIXTwoMath-Regular', 'NotoSansMath-Regular', math;
|
|
42
|
+
font-style: normal;
|
|
43
|
+
font-weight: normal;
|
|
44
|
+
line-height: normal;
|
|
45
|
+
font-size-adjust: none;
|
|
46
|
+
text-indent: 0;
|
|
47
|
+
text-transform: none;
|
|
48
|
+
letter-spacing: normal;
|
|
49
|
+
word-wrap: normal;
|
|
50
|
+
direction: ltr;
|
|
51
|
+
/* Prevent Firefox from omitting the dot on i or j. */
|
|
52
|
+
font-feature-settings: 'dtls' off;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
math * {
|
|
56
|
+
border-color: currentColor;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/* `display: block` is needed in Firefox and Safari; Chromium honours the
|
|
60
|
+
`display: block math` that Temml writes inline — which the sanitizer strips,
|
|
61
|
+
so this rule is what makes display math a block in every browser. */
|
|
62
|
+
math.tml-display {
|
|
63
|
+
display: block;
|
|
64
|
+
width: 100%;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
*.mathcal {
|
|
68
|
+
font-feature-settings: 'ss01';
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
math .mathscr {
|
|
72
|
+
font-family: 'Temml';
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
mo.tml-prime {
|
|
76
|
+
font-family: 'Temml';
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/* Cramped superscripts in WebKit */
|
|
80
|
+
mfrac > :nth-child(2),
|
|
81
|
+
msqrt,
|
|
82
|
+
mover > :first-child {
|
|
83
|
+
math-shift: compact;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
.menclose {
|
|
87
|
+
display: inline-block;
|
|
88
|
+
position: relative;
|
|
89
|
+
padding: 0.5ex 0;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
@supports (-moz-appearance: none) {
|
|
93
|
+
/* \vec without italic correction for Firefox */
|
|
94
|
+
.tml-vec {
|
|
95
|
+
transform: scale(0.75);
|
|
96
|
+
}
|
|
97
|
+
.ff-narrow {
|
|
98
|
+
width: 0;
|
|
99
|
+
}
|
|
100
|
+
.ff-nudge-left {
|
|
101
|
+
margin-left: -0.2em;
|
|
102
|
+
}
|
|
103
|
+
/* Squash hidden mrows in \bordermatrix. */
|
|
104
|
+
.ff-squash mtd {
|
|
105
|
+
display: block;
|
|
106
|
+
height: 0;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
@supports (not (-moz-appearance: none)) {
|
|
111
|
+
/* Chromium and WebKit */
|
|
112
|
+
mo.tml-prime {
|
|
113
|
+
font-family: 'Temml';
|
|
114
|
+
}
|
|
115
|
+
.tml-sml-pad {
|
|
116
|
+
padding-left: 0.05em;
|
|
117
|
+
}
|
|
118
|
+
.tml-med-pad {
|
|
119
|
+
padding-left: 0.1em;
|
|
120
|
+
}
|
|
121
|
+
.tml-lrg-pad {
|
|
122
|
+
padding-left: 0.15em;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
@supports (-webkit-backdrop-filter: blur(1px)) {
|
|
127
|
+
/* WebKit vertical and italic correction on accents */
|
|
128
|
+
.wbk-acc { transform: translate(0, 0.431em); }
|
|
129
|
+
.wbk-sml { transform: translate(0.07em, 0); }
|
|
130
|
+
.wbk-sml-acc { transform: translate(0.07em, 0.431em); }
|
|
131
|
+
.wbk-sml-vec { transform: scale(0.75) translate(0.07em, 0); }
|
|
132
|
+
.wbk-med { transform: translate(0.14em, 0); }
|
|
133
|
+
.wbk-med-acc { transform: translate(0.14em, 0.431em); }
|
|
134
|
+
.wbk-med-vec { transform: scale(0.75) translate(0.14em, 0); }
|
|
135
|
+
.wbk-lrg { transform: translate(0.21em, 0); }
|
|
136
|
+
.wbk-lrg-acc { transform: translate(0.21em, 0.431em); }
|
|
137
|
+
.wbk-lrg-vec { transform: scale(0.75) translate(0.21em, 0); }
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
/* \cancel and \phase paint with a background; get them to print. */
|
|
141
|
+
menclose {
|
|
142
|
+
-webkit-print-color-adjust: exact;
|
|
143
|
+
print-color-adjust: exact;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
/* Array cell justification in Firefox and WebKit */
|
|
147
|
+
.tml-right { text-align: right; }
|
|
148
|
+
.tml-left { text-align: left; }
|
|
149
|
+
|
|
150
|
+
/* CD labels that grow leftward in Firefox and WebKit */
|
|
151
|
+
.tml-shift-left { margin-left: -200%; }
|
|
152
|
+
|
|
153
|
+
/* Chromium only */
|
|
154
|
+
@supports (not (-webkit-backdrop-filter: blur(1px))) and (not (-moz-appearance: none)) {
|
|
155
|
+
.chr-sml { transform: translate(0.07em, 0); }
|
|
156
|
+
.chr-sml-vec { transform: scale(0.75) translate(0.07em, 0); }
|
|
157
|
+
.chr-med { transform: translate(0.14em, 0); }
|
|
158
|
+
.chr-med-vec { transform: scale(0.75) translate(0.14em, 0); }
|
|
159
|
+
.chr-lrg { transform: translate(0.21em, 0); }
|
|
160
|
+
.chr-lrg-vec { transform: scale(0.75) translate(0.21em, 0); }
|
|
161
|
+
|
|
162
|
+
.tml-shift-left { margin-left: -100%; }
|
|
163
|
+
|
|
164
|
+
/* MathML Core and Chromium do not support the MathML 3 <menclose>
|
|
165
|
+
attributes, so these reproduce them. */
|
|
166
|
+
menclose {
|
|
167
|
+
position: relative;
|
|
168
|
+
padding: 0.5ex 0;
|
|
169
|
+
}
|
|
170
|
+
.tml-overline {
|
|
171
|
+
padding: 0.1em 0 0 0;
|
|
172
|
+
border-top: 0.065em solid;
|
|
173
|
+
}
|
|
174
|
+
.tml-underline {
|
|
175
|
+
padding: 0 0 0.1em 0;
|
|
176
|
+
border-bottom: 0.065em solid;
|
|
177
|
+
}
|
|
178
|
+
.tml-cancel {
|
|
179
|
+
display: inline-block;
|
|
180
|
+
position: absolute;
|
|
181
|
+
left: 0.5px;
|
|
182
|
+
bottom: 0;
|
|
183
|
+
width: 100%;
|
|
184
|
+
height: 100%;
|
|
185
|
+
background-color: currentColor;
|
|
186
|
+
}
|
|
187
|
+
.upstrike {
|
|
188
|
+
clip-path: polygon(0.05em 100%, 0 calc(100% - 0.05em), calc(100% - 0.05em) 0, 100% 0.05em);
|
|
189
|
+
}
|
|
190
|
+
.downstrike {
|
|
191
|
+
clip-path: polygon(0 0.05em, 0.05em 0, 100% calc(100% - 0.05em), calc(100% - 0.05em) 100%);
|
|
192
|
+
}
|
|
193
|
+
.sout {
|
|
194
|
+
clip-path: polygon(0 calc(55% + 0.0333em), 0 calc(55% - 0.0333em), 100% calc(55% - 0.0333em), 100% calc(55% + 0.0333em));
|
|
195
|
+
}
|
|
196
|
+
.tml-xcancel {
|
|
197
|
+
clip-path: polygon(0.05em 0, 0 0.05em, calc(50% - 0.05em) 50%, 0 calc(100% - 0.05em), 0.05em 100%, 50% calc(50% + 0.05em), calc(100% - 0.05em) 100%, 100% calc(100% - 0.05em), calc(50% + 0.05em) 50%, 100% 0.05em, calc(100% - 0.05em) 0, 50% calc(50% - 0.05em));
|
|
198
|
+
}
|
|
199
|
+
.longdiv-top {
|
|
200
|
+
border-top: 0.067em solid;
|
|
201
|
+
padding: 0.1em 0.2em 0.2em 0.433em;
|
|
202
|
+
}
|
|
203
|
+
.longdiv-arc {
|
|
204
|
+
position: absolute;
|
|
205
|
+
top: 0;
|
|
206
|
+
bottom: 0.1em;
|
|
207
|
+
left: -0.4em;
|
|
208
|
+
width: 0.7em;
|
|
209
|
+
border: 0.067em solid;
|
|
210
|
+
transform: translateY(-0.067em);
|
|
211
|
+
border-radius: 70%;
|
|
212
|
+
clip-path: inset(0 0 0 0.4em);
|
|
213
|
+
box-sizing: border-box;
|
|
214
|
+
}
|
|
215
|
+
.menclose {
|
|
216
|
+
display: inline-block;
|
|
217
|
+
text-align: left;
|
|
218
|
+
position: relative;
|
|
219
|
+
}
|
|
220
|
+
.phasor-bottom {
|
|
221
|
+
border-bottom: 0.067em solid;
|
|
222
|
+
padding: 0.2em 0.2em 0.1em 0.6em;
|
|
223
|
+
}
|
|
224
|
+
.phasor-angle {
|
|
225
|
+
display: inline-block;
|
|
226
|
+
position: absolute;
|
|
227
|
+
left: 0.5px;
|
|
228
|
+
bottom: -0.04em;
|
|
229
|
+
height: 100%;
|
|
230
|
+
aspect-ratio: 0.5;
|
|
231
|
+
background-color: currentColor;
|
|
232
|
+
clip-path: polygon(0.05em 100%, 0 calc(100% - 0.05em), calc(100% - 0.05em) 0, 100% 0.05em);
|
|
233
|
+
}
|
|
234
|
+
.tml-fbox {
|
|
235
|
+
padding: 3pt;
|
|
236
|
+
border: 1px solid;
|
|
237
|
+
}
|
|
238
|
+
.circle-pad { padding: 0.267em; }
|
|
239
|
+
.textcircle {
|
|
240
|
+
position: absolute;
|
|
241
|
+
inset: 0;
|
|
242
|
+
border: 0.067em solid;
|
|
243
|
+
border-radius: 50%;
|
|
244
|
+
}
|
|
245
|
+
.actuarial {
|
|
246
|
+
padding: 0.03889em 0.03889em 0 0.03889em;
|
|
247
|
+
border-width: 0.08em 0.08em 0 0;
|
|
248
|
+
border-style: solid;
|
|
249
|
+
margin-right: 0.03889em;
|
|
250
|
+
}
|
|
251
|
+
/* Stretch \widetilde */
|
|
252
|
+
.tml-tilde-2 { transform: scale(2, 1.1); }
|
|
253
|
+
.tml-tilde-3 { transform: scale(3, 1.1); }
|
|
254
|
+
.tml-tilde-4 { transform: scale(4, 1.1); }
|
|
255
|
+
/* Stretch \widehat */
|
|
256
|
+
.tml-hat-1 { transform: scale(1.9, 1); }
|
|
257
|
+
.tml-hat-2 { transform: scale(3.9, 1); }
|
|
258
|
+
.tml-hat-3 { transform: scale(5.8, 1); }
|
|
259
|
+
.tml-hat-4 { transform: scale(7.8, 1); }
|
|
260
|
+
|
|
261
|
+
.tml-right { text-align: -webkit-right; }
|
|
262
|
+
.tml-left { text-align: -webkit-left; }
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
.special-fraction {
|
|
266
|
+
font-family: 'STIX TWO', 'Times New Roman', Times, Tinos, serif;
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
/* Line-breaking in Chromium */
|
|
270
|
+
math {
|
|
271
|
+
display: inline-flex;
|
|
272
|
+
flex-wrap: wrap;
|
|
273
|
+
align-items: baseline;
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
math > mrow {
|
|
277
|
+
padding: 0.5ex 0;
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
/* Default mtd top padding is 0.5ex per MathML Core; adjust for jot and small. */
|
|
281
|
+
mtable.tml-jot mtd {
|
|
282
|
+
padding-top: 0.7ex;
|
|
283
|
+
padding-bottom: 0.7ex;
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
mtable.tml-small mtd {
|
|
287
|
+
padding-top: 0.35ex;
|
|
288
|
+
padding-bottom: 0.35ex;
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
@-moz-document url-prefix() {
|
|
292
|
+
/* Firefox: avoid flex-wrap and adjust array row spacing. */
|
|
293
|
+
math { display: inline; }
|
|
294
|
+
math > mrow { padding: 0; }
|
|
295
|
+
mtd,
|
|
296
|
+
mtable.tml-small mtd { padding-top: 0; padding-bottom: 0; }
|
|
297
|
+
mtable.tml-jot mtd { padding-top: 0.2ex; padding-bottom: 0; }
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
/* AMS environment auto-numbering. The counter is reset on the article rather
|
|
301
|
+
than on `body`, as upstream does: the article is the numbering scope a reader
|
|
302
|
+
expects, and resetting on `body` would number across the page chrome. */
|
|
303
|
+
.prose {
|
|
304
|
+
counter-reset: tmlEqnNo;
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
.tml-eqn::before {
|
|
308
|
+
counter-increment: tmlEqnNo;
|
|
309
|
+
content: '(' counter(tmlEqnNo) ')';
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
/*
|
|
313
|
+
* This projection's own rules.
|
|
314
|
+
*
|
|
315
|
+
* Six classes reproducing the inline declarations that measurably change
|
|
316
|
+
* layout. `src/lib/math.ts` documents which they are, how they were chosen —
|
|
317
|
+
* by dropping each property group in a real browser and re-measuring — and why
|
|
318
|
+
* the other 33 declarations Temml emits need no rule at all.
|
|
319
|
+
*/
|
|
320
|
+
|
|
321
|
+
.math-boxed {
|
|
322
|
+
border: 1px solid currentColor;
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
.math-boxed-pad {
|
|
326
|
+
padding: 3pt;
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
.math-cell-rule-right {
|
|
330
|
+
border-right: 0.06em solid currentColor;
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
.math-cell-rule-bottom {
|
|
334
|
+
border-bottom: 0.06em solid currentColor;
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
.math-cell-tight {
|
|
338
|
+
padding: 0;
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
.math-cell-tight-top {
|
|
342
|
+
padding-top: 0;
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
.math-cell-tight-bottom {
|
|
346
|
+
padding-bottom: 0;
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
/*
|
|
350
|
+
* Placement in the article.
|
|
351
|
+
*
|
|
352
|
+
* Display math is a block that can be wider than the measure — a long
|
|
353
|
+
* derivation does not wrap — so it scrolls horizontally rather than pushing the
|
|
354
|
+
* page wide, and the scroll container is focusable so a keyboard reader can
|
|
355
|
+
* reach it (axe `scrollable-region-focusable`, WCAG 2.1.1).
|
|
356
|
+
*/
|
|
357
|
+
.math-display {
|
|
358
|
+
display: block;
|
|
359
|
+
margin-block: var(--space-6);
|
|
360
|
+
overflow-x: auto;
|
|
361
|
+
overflow-y: hidden;
|
|
362
|
+
/* Room for the focus ring, which would otherwise be clipped by the scroll
|
|
363
|
+
container's own edge. */
|
|
364
|
+
padding: var(--space-1);
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
.math-display:focus-visible {
|
|
368
|
+
outline: 2px solid var(--color-focus);
|
|
369
|
+
outline-offset: 2px;
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
.math-inline {
|
|
373
|
+
/* Keeps an inline expression from setting the line height of its paragraph. */
|
|
374
|
+
display: inline-block;
|
|
375
|
+
vertical-align: baseline;
|
|
376
|
+
}
|