@atelic-action/artifact 2.0.0 → 4.0.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/README.md +6 -4
- package/package.json +3 -3
- package/src/documents/Gate.tsx +4 -4
- package/src/documents/Read.tsx +90 -105
- package/src/documents/Writeup.tsx +23 -53
- package/src/documents/documents.css +73 -253
package/README.md
CHANGED
|
@@ -7,7 +7,7 @@ The documents the practice hands or sends a business, as a published package and
|
|
|
7
7
|
|
|
8
8
|
Three layers, each a version the next depends on (ATE-671): `@atelic-action/ui` holds the pieces, this package holds the documents built from them, and each business's folder holds only its content, routes, and config. A document fix reaches a folder by bumping this package; a piece fix by bumping ui here, then this package in the folder.
|
|
9
9
|
|
|
10
|
-
Five artifacts live in the template site: the **writeup** at `/writeup`, the graded document an owner gets, a web page first with its printed copy derived from it; the **read** at `/the-read`, what a customer gets at the end of an engagement's first week, the baseline's grades explained by cause with the plan in order; the **proposal** at `/proposal`, sealed into the page and opened by the reader's own email address; the **monthly page** at `/report`, what an Operate client gets each month on one letter sheet; and the **note** at `/notes`, the first touch for a business whose site publishes no email address, set as a short page. The bare host sends a reader to the writeup. Every artifact prerenders to static HTML, stays out of every index, and carries the practice's brand by default.
|
|
10
|
+
Five artifacts live in the template site: the **writeup** at `/writeup`, the graded document an owner gets, a web page first with its printed copy derived from it; the **read** at `/the-read`, what a customer gets at the end of an engagement's first week, the baseline's grades explained by cause, with the plan in order between the gist and the cards; the **proposal** at `/proposal`, sealed into the page and opened by the reader's own email address; the **monthly page** at `/report`, what an Operate client gets each month on one letter sheet; and the **note** at `/notes`, the first touch for a business whose site publishes no email address, set as a short page. The bare host sends a reader to the writeup. Every artifact prerenders to static HTML, stays out of every index, and carries the practice's brand by default.
|
|
11
11
|
|
|
12
12
|
The method behind them (the seven sections, the four grades from A to D, the rented line, what moved, and when an artifact is private) is the practice repo's `FOOTPRINT.md`. This repo builds to it and never restates it.
|
|
13
13
|
|
|
@@ -26,8 +26,8 @@ Every export of the package, all from the one entry, `@atelic-action/artifact`.
|
|
|
26
26
|
| `ratingCell` | A star rating table cell for a writeup table, sorted by its figure | `/writeup` |
|
|
27
27
|
| `WriteupBlock`, `WriteupTopic`, `WriteupPart`, `WriteupSheet`, `WriteupSummary`, `WriteupSummaryRow`, `WriteupMarkets`, `WriteupRented`, `WriteupMark`, `WriteupCell`, `WriteupTone`, and the rest of the `Writeup*` types | The shapes a writeup's content is written in | none |
|
|
28
28
|
| `WriteupGrade`, `WriteupPerson`, `WriteupShot` | The grade letter, the sign off person, and the owner's screen, shared by every document, all three re exported from ui | none |
|
|
29
|
-
| `Read`, `ReadProps` | The baseline's grades explained by cause: the gist table, with an optional `note` callout
|
|
30
|
-
| `readLabels`, `ReadLabels` | The fixed words the read sets (Prepared for, the
|
|
29
|
+
| `Read`, `ReadProps` | The baseline's grades explained by cause: the gist table, each row a link to its card, with an optional `note` callout over it for what the read leaves out; each section on the writeup's card (`ReadSection` extends `WriteupTopic`: the trade name linked to its definition, the one liner, the grade, the why line as the summary, the writeup's blocks, and the sources at the foot) plus the read's own today and after (a two column table) and what we recommend (a checklist). The plan, numbered and in order, sits between the gist and the cards, so the whole program reads before any one card's detail. A beat with no data is left out | `/the-read` |
|
|
30
|
+
| `readLabels`, `ReadLabels` | The fixed words the read sets (Prepared for, the scorecard's screen reader words, Today, After, Recommendations, the plan's heading), each overridable through `labels` | `/the-read` |
|
|
31
31
|
| `ReadTier`, `ReadSection`, `ReadChange`, `ReadStep`, `ReadPlan`, `ReadClose`, `ReadLink`, `ReadParagraph` | The shapes a read's content is written in. `ReadSection` is a `WriteupTopic` plus `gist`, `changes`, and `recommend`; its `why` and a finding's `body` take a paragraph (a string, or runs of text and links) as well as a node, so a routine can still write a read as JSON | none |
|
|
32
32
|
| `Report`, `ReportProps` | The monthly page: the four questions, the seven grades now and before, the sign off, on one letter sheet | `/report` |
|
|
33
33
|
| `ReportLead`, `ReportLeads`, `ReportGradeRow` | The shapes a monthly page's content is written in | none |
|
|
@@ -45,7 +45,7 @@ What a document is built from stays in `@atelic-action/ui`, and this package imp
|
|
|
45
45
|
bun add @atelic-action/artifact @atelic-action/ui
|
|
46
46
|
```
|
|
47
47
|
|
|
48
|
-
Peer dependencies: `@atelic-action/ui` at `^
|
|
48
|
+
Peer dependencies: `@atelic-action/ui` at `^3.0.0`, `react` at `^19.0.0`, and `lucide-react` at `^1.23.0`. The package ships TSX and CSS as source, compiled inside the site's own Vite like ui's; a site whose `vite.config.ts` is one `artifactConfig` call from `@atelic-action/ui/vite` needs nothing more, for the build, the prerender, and the dev server alike. The default labels a document sets live in the document: the read's `readLabels` and the sealed document's gate copy are overridden through props, and the monthly page's four questions are fixed on purpose, since they are its contract with the Statement of Work.
|
|
49
49
|
|
|
50
50
|
```tsx
|
|
51
51
|
import { Writeup } from "@atelic-action/artifact";
|
|
@@ -136,6 +136,8 @@ Static files. `vercel.json` points Vercel at `dist/client` with no framework pre
|
|
|
136
136
|
|
|
137
137
|
A document is fixed or grown here, in `src/documents/`, with its test in `tst/documents/`, and released as a version of this package; a folder takes it with `bun update @atelic-action/artifact`. A piece a document is built from (the grade chip, the sign off, a page component, the chrome, the wall, a command) is fixed in `@atelic-action/ui` and released there first, then taken here by bumping the ui range. An improvement to the seed itself (a route, a stub file, the example content) is made here and copied into the folders by hand.
|
|
138
138
|
|
|
139
|
+
A folder taking 4.0.0 takes ui 3.0.0 with it (`bun update @atelic-action/artifact @atelic-action/ui --latest --cwd <short>`) and repoints its own routes, since ui 3.0.0 keeps acronyms capitalized with no alias for the old spelling: `canonicalUrl` from `@atelic-action/ui/artifact` becomes `canonicalURL` in `src/routes/index.tsx`, and the root route's `baseCss` import becomes `baseCSS`.
|
|
140
|
+
|
|
139
141
|
## Releasing
|
|
140
142
|
|
|
141
143
|
1. Bump `version` in `package.json` and merge it to `main`: patch for a fix, minor for a new document or prop, major for a breaking prop, type, or class rename.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@atelic-action/artifact",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "4.0.0",
|
|
4
4
|
"description": "The composed documents the Atelic practice hands or sends a business (the writeup, the read, the monthly page, the note, and the sealed document), built from the pieces in @atelic-action/ui",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -37,12 +37,12 @@
|
|
|
37
37
|
"format": "biome format . --write"
|
|
38
38
|
},
|
|
39
39
|
"peerDependencies": {
|
|
40
|
-
"@atelic-action/ui": "^
|
|
40
|
+
"@atelic-action/ui": "^3.0.0",
|
|
41
41
|
"lucide-react": "^1.23.0",
|
|
42
42
|
"react": "^19.0.0"
|
|
43
43
|
},
|
|
44
44
|
"devDependencies": {
|
|
45
|
-
"@atelic-action/ui": "^
|
|
45
|
+
"@atelic-action/ui": "^3.0.0",
|
|
46
46
|
"@biomejs/biome": "^2.0.0",
|
|
47
47
|
"@playwright/test": "^1.60.0",
|
|
48
48
|
"@sentry/react": "^10.0.0",
|
package/src/documents/Gate.tsx
CHANGED
|
@@ -227,7 +227,7 @@ export function Gate({
|
|
|
227
227
|
errorText = "That email does not open this document. Use the address it was sent to.",
|
|
228
228
|
onUnlock,
|
|
229
229
|
}: GateProps) {
|
|
230
|
-
const [html,
|
|
230
|
+
const [html, setHTML] = useState<string | null>(null);
|
|
231
231
|
const [failed, setFailed] = useState(false);
|
|
232
232
|
const [busy, setBusy] = useState(false);
|
|
233
233
|
const [value, setValue] = useState("");
|
|
@@ -253,7 +253,7 @@ export function Gate({
|
|
|
253
253
|
if (opened) {
|
|
254
254
|
writeStored(storageKey, fromQuery);
|
|
255
255
|
identifyReader(opened.email, identifyDomain);
|
|
256
|
-
|
|
256
|
+
setHTML(opened.html);
|
|
257
257
|
onUnlockRef.current?.(opened.person);
|
|
258
258
|
return;
|
|
259
259
|
}
|
|
@@ -267,7 +267,7 @@ export function Gate({
|
|
|
267
267
|
const opened = await openDocument(payload, stored);
|
|
268
268
|
if (cancelled || !opened) return;
|
|
269
269
|
identifyReader(opened.email, identifyDomain);
|
|
270
|
-
|
|
270
|
+
setHTML(opened.html);
|
|
271
271
|
onUnlockRef.current?.(opened.person);
|
|
272
272
|
}
|
|
273
273
|
|
|
@@ -290,7 +290,7 @@ export function Gate({
|
|
|
290
290
|
}
|
|
291
291
|
writeStored(storageKey, value);
|
|
292
292
|
identifyReader(opened.email, identifyDomain);
|
|
293
|
-
|
|
293
|
+
setHTML(opened.html);
|
|
294
294
|
onUnlockRef.current?.(opened.person);
|
|
295
295
|
}
|
|
296
296
|
|
package/src/documents/Read.tsx
CHANGED
|
@@ -1,17 +1,16 @@
|
|
|
1
1
|
import {
|
|
2
2
|
type ArtifactLink,
|
|
3
3
|
type ArtifactParagraph,
|
|
4
|
-
GradeChip,
|
|
5
|
-
gradeLabel,
|
|
6
4
|
isEmpty,
|
|
5
|
+
newTabProps,
|
|
7
6
|
Paragraph,
|
|
8
7
|
Runs,
|
|
9
8
|
SignOff,
|
|
10
9
|
type WriteupGrade,
|
|
11
10
|
type WriteupPerson,
|
|
12
11
|
} from "@atelic-action/ui/artifact";
|
|
13
|
-
import { IconList, type Tone } from "@atelic-action/ui/components";
|
|
14
|
-
import { Check } from "lucide-react";
|
|
12
|
+
import { IconList, ReportCard, type Tone } from "@atelic-action/ui/components";
|
|
13
|
+
import { ArrowUpRight, Check } from "lucide-react";
|
|
15
14
|
import type { ReactNode } from "react";
|
|
16
15
|
import { Topic, type WriteupTopic } from "./Writeup";
|
|
17
16
|
|
|
@@ -87,6 +86,8 @@ export interface ReadTier {
|
|
|
87
86
|
id?: string;
|
|
88
87
|
/** The tier's name, e.g. "Health". */
|
|
89
88
|
title: string;
|
|
89
|
+
/** Where the name is defined, e.g. the practice's glossary; the heading links there when set. */
|
|
90
|
+
href?: string;
|
|
90
91
|
/** The questions the tier answers, in the owner's words. */
|
|
91
92
|
lead?: string;
|
|
92
93
|
sections: ReadSection[];
|
|
@@ -98,9 +99,11 @@ export interface ReadStep {
|
|
|
98
99
|
body?: ReadParagraph;
|
|
99
100
|
/** Whose step it is when it is not the practice's, e.g. "Yours" or a name; set beside the title. */
|
|
100
101
|
who?: string;
|
|
102
|
+
/** The cards the step draws on, linked in a line beneath it, e.g. { text: "Local SEO", href: "#local-seo" }. */
|
|
103
|
+
cards?: ReadLink[];
|
|
101
104
|
}
|
|
102
105
|
|
|
103
|
-
/** The plan: the steps in order, numbered. */
|
|
106
|
+
/** The plan: the steps in order, numbered, between the gist and the cards, so the whole program reads before any one card's detail. */
|
|
104
107
|
export interface ReadPlan {
|
|
105
108
|
/** The anchor a header stop points at, e.g. "plan". */
|
|
106
109
|
id?: string;
|
|
@@ -123,12 +126,10 @@ export interface ReadClose {
|
|
|
123
126
|
export interface ReadLabels {
|
|
124
127
|
/** The dateline's words before the business, e.g. "Prepared for". */
|
|
125
128
|
preparedFor: string;
|
|
126
|
-
/**
|
|
127
|
-
section: string;
|
|
128
|
-
/** The gist table's second column. */
|
|
129
|
-
grade: string;
|
|
130
|
-
/** The gist table's third column. */
|
|
129
|
+
/** What a screen reader calls the gist card when it has no title. */
|
|
131
130
|
gist: string;
|
|
131
|
+
/** What a screen reader hears before a letter, on the gist card and each section's card. */
|
|
132
|
+
grade: string;
|
|
132
133
|
/** What a screen reader hears for a section with no grade. */
|
|
133
134
|
notGraded: string;
|
|
134
135
|
/** The today and after table's first column. */
|
|
@@ -147,9 +148,8 @@ export interface ReadLabels {
|
|
|
147
148
|
|
|
148
149
|
export const readLabels: ReadLabels = {
|
|
149
150
|
preparedFor: "Prepared for",
|
|
150
|
-
section: "Section",
|
|
151
|
-
grade: "Grade",
|
|
152
151
|
gist: "The Gist",
|
|
152
|
+
grade: "Grade",
|
|
153
153
|
notGraded: "Not graded yet",
|
|
154
154
|
now: "Today",
|
|
155
155
|
after: "After",
|
|
@@ -167,9 +167,13 @@ export interface ReadProps {
|
|
|
167
167
|
date: string;
|
|
168
168
|
/** Two or three sentences under the title. */
|
|
169
169
|
lede: ReadParagraph;
|
|
170
|
-
/** The heading over the
|
|
170
|
+
/** The heading over the scorecard, e.g. "The Scorecard". */
|
|
171
171
|
gistTitle?: string;
|
|
172
|
-
/**
|
|
172
|
+
/** The line under the scorecard's heading, e.g. what it is. */
|
|
173
|
+
gistLead?: string;
|
|
174
|
+
/** The anchor a header stop points at for the scorecard, e.g. "scorecard". */
|
|
175
|
+
gistId?: string;
|
|
176
|
+
/** A callout over the scorecard, under its heading, e.g. what the read leaves out and when it follows. */
|
|
173
177
|
note?: ReadParagraph;
|
|
174
178
|
/** The key: what each letter means, in a few words each. */
|
|
175
179
|
gradeKey?: Array<{ grade: WriteupGrade; label: string }>;
|
|
@@ -261,85 +265,51 @@ function Recommend({ items, label }: { items: ReadRecommendation[]; label: strin
|
|
|
261
265
|
|
|
262
266
|
function Gist({
|
|
263
267
|
tiers,
|
|
268
|
+
id,
|
|
264
269
|
title,
|
|
270
|
+
lead,
|
|
271
|
+
note,
|
|
265
272
|
gradeKey,
|
|
266
273
|
labels,
|
|
267
274
|
}: {
|
|
268
275
|
tiers: ReadTier[];
|
|
276
|
+
id?: string;
|
|
269
277
|
title?: string;
|
|
278
|
+
lead?: string;
|
|
279
|
+
note?: ReadProps["note"];
|
|
270
280
|
gradeKey?: ReadProps["gradeKey"];
|
|
271
281
|
labels: ReadLabels;
|
|
272
282
|
}) {
|
|
273
|
-
const key = gradeKey ?? [];
|
|
274
283
|
return (
|
|
275
|
-
|
|
276
|
-
{
|
|
277
|
-
<div className="op-
|
|
278
|
-
|
|
279
|
-
{
|
|
280
|
-
<ul className="op-legend">
|
|
281
|
-
{key.map((entry) => (
|
|
282
|
-
<li key={entry.grade}>
|
|
283
|
-
<GradeChip grade={entry.grade} />
|
|
284
|
-
<span>{entry.label}</span>
|
|
285
|
-
</li>
|
|
286
|
-
))}
|
|
287
|
-
</ul>
|
|
288
|
-
)}
|
|
284
|
+
<>
|
|
285
|
+
{title && (
|
|
286
|
+
<div className="op-part" id={id}>
|
|
287
|
+
<h2>{title}</h2>
|
|
288
|
+
{lead && <p>{lead}</p>}
|
|
289
289
|
</div>
|
|
290
290
|
)}
|
|
291
|
-
|
|
292
|
-
<
|
|
293
|
-
<
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
{tier.sections.map((section) => (
|
|
314
|
-
<tr key={section.id}>
|
|
315
|
-
<th scope="row" className="rd-gist-section">
|
|
316
|
-
<a href={`#${section.id}`}>{section.title}</a>
|
|
317
|
-
</th>
|
|
318
|
-
<td className="rd-gist-grade">
|
|
319
|
-
{section.grade ? (
|
|
320
|
-
<>
|
|
321
|
-
<span className="op-sr-only">{gradeLabel[section.grade]}</span>
|
|
322
|
-
<span aria-hidden="true">
|
|
323
|
-
<GradeChip grade={section.grade} />
|
|
324
|
-
</span>
|
|
325
|
-
</>
|
|
326
|
-
) : (
|
|
327
|
-
<>
|
|
328
|
-
<span className="op-sr-only">{labels.notGraded}</span>
|
|
329
|
-
<span className="op-dash" aria-hidden="true" />
|
|
330
|
-
</>
|
|
331
|
-
)}
|
|
332
|
-
</td>
|
|
333
|
-
<td className="rd-gist-read">
|
|
334
|
-
<Runs paragraph={section.gist} />
|
|
335
|
-
</td>
|
|
336
|
-
</tr>
|
|
337
|
-
))}
|
|
338
|
-
</tbody>
|
|
339
|
-
))}
|
|
340
|
-
</table>
|
|
341
|
-
</div>
|
|
342
|
-
</section>
|
|
291
|
+
{filled(note) && (
|
|
292
|
+
<div className="rd-note" role="note">
|
|
293
|
+
<Paragraph paragraph={note} />
|
|
294
|
+
</div>
|
|
295
|
+
)}
|
|
296
|
+
<ReportCard
|
|
297
|
+
className="rd-gist"
|
|
298
|
+
label={title ?? labels.gist}
|
|
299
|
+
legend={gradeKey}
|
|
300
|
+
legendAt="foot"
|
|
301
|
+
labels={{ grade: labels.grade, notGraded: labels.notGraded }}
|
|
302
|
+
groups={tiers.map((tier) => ({
|
|
303
|
+
title: tier.title,
|
|
304
|
+
rows: tier.sections.map((section) => ({
|
|
305
|
+
name: section.title,
|
|
306
|
+
href: `#${section.id}`,
|
|
307
|
+
grade: section.grade,
|
|
308
|
+
line: <Runs paragraph={section.gist} />,
|
|
309
|
+
})),
|
|
310
|
+
}))}
|
|
311
|
+
/>
|
|
312
|
+
</>
|
|
343
313
|
);
|
|
344
314
|
}
|
|
345
315
|
|
|
@@ -392,21 +362,24 @@ function Plan({ plan, labels }: { plan: ReadPlan; labels: ReadLabels }) {
|
|
|
392
362
|
<ol className="rd-steps">
|
|
393
363
|
{plan.steps.map((step) => (
|
|
394
364
|
<li className="rd-step" key={step.title}>
|
|
395
|
-
<
|
|
396
|
-
<
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
365
|
+
<div className="rd-step-body">
|
|
366
|
+
<p className="rd-step-head">
|
|
367
|
+
<b className="rd-step-title">{step.title}</b>
|
|
368
|
+
{step.who && <span className="rd-step-who">{step.who}</span>}
|
|
369
|
+
</p>
|
|
370
|
+
{filled(step.body) && <Paragraph paragraph={step.body} />}
|
|
371
|
+
{(step.cards ?? []).some((card) => card?.href) && (
|
|
372
|
+
<p className="rd-step-cards">
|
|
373
|
+
{(step.cards ?? [])
|
|
374
|
+
.filter((card) => card?.href)
|
|
375
|
+
.map((card, i) => (
|
|
376
|
+
<a href={card.href} key={`${i}-${card.href}`}>
|
|
377
|
+
{card.text}
|
|
378
|
+
</a>
|
|
379
|
+
))}
|
|
380
|
+
</p>
|
|
402
381
|
)}
|
|
403
|
-
|
|
404
|
-
<>
|
|
405
|
-
{" "}
|
|
406
|
-
<Runs paragraph={step.body} />
|
|
407
|
-
</>
|
|
408
|
-
)}
|
|
409
|
-
</p>
|
|
382
|
+
</div>
|
|
410
383
|
</li>
|
|
411
384
|
))}
|
|
412
385
|
</ol>
|
|
@@ -420,6 +393,8 @@ export function Read({
|
|
|
420
393
|
date,
|
|
421
394
|
lede,
|
|
422
395
|
gistTitle,
|
|
396
|
+
gistLead,
|
|
397
|
+
gistId,
|
|
423
398
|
note,
|
|
424
399
|
gradeKey,
|
|
425
400
|
tiers,
|
|
@@ -444,19 +419,30 @@ export function Read({
|
|
|
444
419
|
{filled(lede) && <Paragraph paragraph={lede} className="op-intro rd-lede" />}
|
|
445
420
|
</header>
|
|
446
421
|
{shownTiers.length > 0 && (
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
{
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
422
|
+
<Gist
|
|
423
|
+
tiers={shownTiers}
|
|
424
|
+
id={gistId}
|
|
425
|
+
title={gistTitle}
|
|
426
|
+
lead={gistLead}
|
|
427
|
+
note={note}
|
|
428
|
+
gradeKey={gradeKey}
|
|
429
|
+
labels={labels}
|
|
430
|
+
/>
|
|
455
431
|
)}
|
|
432
|
+
{plan.steps.length > 0 && <Plan plan={plan} labels={labels} />}
|
|
456
433
|
{shownTiers.map((tier) => (
|
|
457
434
|
<div className="rd-tier" key={tier.title}>
|
|
458
435
|
<div className="op-part" id={tier.id}>
|
|
459
|
-
<h2>
|
|
436
|
+
<h2>
|
|
437
|
+
{tier.href ? (
|
|
438
|
+
<a href={tier.href} {...newTabProps(tier.href, true)}>
|
|
439
|
+
{tier.title}
|
|
440
|
+
<ArrowUpRight size={14} aria-hidden="true" />
|
|
441
|
+
</a>
|
|
442
|
+
) : (
|
|
443
|
+
tier.title
|
|
444
|
+
)}
|
|
445
|
+
</h2>
|
|
460
446
|
{tier.lead && <p>{tier.lead}</p>}
|
|
461
447
|
</div>
|
|
462
448
|
{tier.sections.map((section) => (
|
|
@@ -464,7 +450,6 @@ export function Read({
|
|
|
464
450
|
))}
|
|
465
451
|
</div>
|
|
466
452
|
))}
|
|
467
|
-
{plan.steps.length > 0 && <Plan plan={plan} labels={labels} />}
|
|
468
453
|
{filled(close.line) && <Paragraph paragraph={close.line} className="rd-closing" />}
|
|
469
454
|
{close.signOff && close.person && (
|
|
470
455
|
<footer className="op-close rd-close">
|
|
@@ -18,6 +18,7 @@ import {
|
|
|
18
18
|
type ColumnChartGroup,
|
|
19
19
|
DataTable,
|
|
20
20
|
Disclosure,
|
|
21
|
+
ReportCard,
|
|
21
22
|
StackedBar,
|
|
22
23
|
type StackedBarSegment,
|
|
23
24
|
type StatItem,
|
|
@@ -27,7 +28,7 @@ import {
|
|
|
27
28
|
type ThresholdZone,
|
|
28
29
|
type Tone,
|
|
29
30
|
} from "@atelic-action/ui/components";
|
|
30
|
-
import { ArrowUpRight,
|
|
31
|
+
import { ArrowUpRight, CircleAlert, CircleCheck, CircleX, Star } from "lucide-react";
|
|
31
32
|
import type { ReactNode } from "react";
|
|
32
33
|
|
|
33
34
|
export type { WriteupGrade, WriteupPerson, WriteupShot } from "@atelic-action/ui/artifact";
|
|
@@ -609,61 +610,30 @@ export function Topic({ topic, extra }: { topic: WriteupTopic; extra?: ReactNode
|
|
|
609
610
|
}
|
|
610
611
|
|
|
611
612
|
function Summary({ summary }: { summary: WriteupSummary }) {
|
|
612
|
-
const
|
|
613
|
+
const groups: Array<{ title: string; rows: WriteupSummaryRow[] }> = [];
|
|
613
614
|
for (const row of summary.rows) {
|
|
614
|
-
const last =
|
|
615
|
-
if (last && last.
|
|
616
|
-
else
|
|
615
|
+
const last = groups[groups.length - 1];
|
|
616
|
+
if (last && last.title === row.tier) last.rows.push(row);
|
|
617
|
+
else groups.push({ title: row.tier, rows: [row] });
|
|
617
618
|
}
|
|
618
|
-
const beforeLabel = summary.beforeLabel ?? "Before";
|
|
619
619
|
return (
|
|
620
|
-
<
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
<div className="op-ov-tier-label">{tier}</div>
|
|
638
|
-
<ul>
|
|
639
|
-
{rows.map((row) => (
|
|
640
|
-
<li className="op-ov-row" key={row.section}>
|
|
641
|
-
<span className="op-ov-grade">
|
|
642
|
-
{row.before && (
|
|
643
|
-
<span className="op-ov-before">
|
|
644
|
-
<span className="op-sr-only">{`${beforeLabel}: ${gradeLabel[row.before]}. `}</span>
|
|
645
|
-
<span aria-hidden="true">
|
|
646
|
-
<GradeChip grade={row.before} />
|
|
647
|
-
</span>
|
|
648
|
-
</span>
|
|
649
|
-
)}
|
|
650
|
-
<span className="op-sr-only">{`Grade ${gradeLabel[row.grade]}: `}</span>
|
|
651
|
-
<span aria-hidden="true">
|
|
652
|
-
<GradeChip grade={row.grade} />
|
|
653
|
-
</span>
|
|
654
|
-
</span>
|
|
655
|
-
<b className="op-ov-name">
|
|
656
|
-
{row.href ? <a href={row.href}>{row.section}</a> : row.section}
|
|
657
|
-
</b>
|
|
658
|
-
<span className="op-ov-read">{row.read}</span>
|
|
659
|
-
{row.href && <ChevronRight className="op-ov-go" size={18} aria-hidden="true" />}
|
|
660
|
-
</li>
|
|
661
|
-
))}
|
|
662
|
-
</ul>
|
|
663
|
-
</div>
|
|
664
|
-
))}
|
|
665
|
-
</div>
|
|
666
|
-
</section>
|
|
620
|
+
<ReportCard
|
|
621
|
+
className="op-ov"
|
|
622
|
+
id={summary.id}
|
|
623
|
+
title={summary.title}
|
|
624
|
+
legend={summary.legend}
|
|
625
|
+
labels={{ before: summary.beforeLabel }}
|
|
626
|
+
groups={groups.map((group) => ({
|
|
627
|
+
title: group.title,
|
|
628
|
+
rows: group.rows.map((row) => ({
|
|
629
|
+
name: row.section,
|
|
630
|
+
href: row.href,
|
|
631
|
+
grade: row.grade,
|
|
632
|
+
before: row.before,
|
|
633
|
+
line: row.read,
|
|
634
|
+
})),
|
|
635
|
+
}))}
|
|
636
|
+
/>
|
|
667
637
|
);
|
|
668
638
|
}
|
|
669
639
|
|
|
@@ -921,134 +921,11 @@
|
|
|
921
921
|
|
|
922
922
|
/* ---- the overview: the key, then every section under its tier, each a
|
|
923
923
|
grade, a name that links to the section, and one plain read ---- */
|
|
924
|
+
/* the overview is the ReportCard (@atelic-action/ui); this is its place on the page */
|
|
924
925
|
.atelic-ui .op-ov {
|
|
925
926
|
margin-top: 22px;
|
|
926
927
|
scroll-margin-top: calc(var(--nav-height) + 16px);
|
|
927
928
|
}
|
|
928
|
-
.atelic-ui .op-ov-head {
|
|
929
|
-
display: flex;
|
|
930
|
-
flex-wrap: wrap;
|
|
931
|
-
align-items: center;
|
|
932
|
-
justify-content: space-between;
|
|
933
|
-
gap: 8px 20px;
|
|
934
|
-
margin-bottom: 10px;
|
|
935
|
-
}
|
|
936
|
-
.atelic-ui .op-ov-title {
|
|
937
|
-
font-size: 13px;
|
|
938
|
-
font-family: var(--font-mono);
|
|
939
|
-
font-weight: 500;
|
|
940
|
-
letter-spacing: 0.1em;
|
|
941
|
-
text-transform: uppercase;
|
|
942
|
-
color: var(--op-ink-faint);
|
|
943
|
-
margin: 0;
|
|
944
|
-
}
|
|
945
|
-
.atelic-ui .op-legend {
|
|
946
|
-
list-style: none;
|
|
947
|
-
margin: 0;
|
|
948
|
-
padding: 0;
|
|
949
|
-
display: flex;
|
|
950
|
-
flex-wrap: wrap;
|
|
951
|
-
gap: 6px 16px;
|
|
952
|
-
font-size: 13.5px;
|
|
953
|
-
color: var(--op-ink-soft);
|
|
954
|
-
}
|
|
955
|
-
.atelic-ui .op-legend li {
|
|
956
|
-
display: inline-flex;
|
|
957
|
-
align-items: center;
|
|
958
|
-
gap: 7px;
|
|
959
|
-
}
|
|
960
|
-
.atelic-ui .op-legend .op-grade {
|
|
961
|
-
width: 22px;
|
|
962
|
-
height: 22px;
|
|
963
|
-
border-radius: 6px;
|
|
964
|
-
font-size: 12px;
|
|
965
|
-
}
|
|
966
|
-
.atelic-ui .op-ov-card {
|
|
967
|
-
background: var(--op-card);
|
|
968
|
-
border: 1px solid var(--op-rule);
|
|
969
|
-
border-radius: var(--radius-md);
|
|
970
|
-
box-shadow: var(--shadow-sm);
|
|
971
|
-
overflow: hidden;
|
|
972
|
-
}
|
|
973
|
-
.atelic-ui .op-ov-tier-label {
|
|
974
|
-
padding: 7px 16px;
|
|
975
|
-
background: var(--surface-alt);
|
|
976
|
-
font-family: var(--font-mono);
|
|
977
|
-
font-size: 11.5px;
|
|
978
|
-
letter-spacing: 0.1em;
|
|
979
|
-
text-transform: uppercase;
|
|
980
|
-
color: var(--op-ink-soft);
|
|
981
|
-
}
|
|
982
|
-
.atelic-ui .op-ov-tier ul {
|
|
983
|
-
list-style: none;
|
|
984
|
-
margin: 0;
|
|
985
|
-
padding: 0;
|
|
986
|
-
}
|
|
987
|
-
.atelic-ui .op-ov-row {
|
|
988
|
-
position: relative;
|
|
989
|
-
display: grid;
|
|
990
|
-
grid-template-columns: auto minmax(0, 1fr) auto;
|
|
991
|
-
column-gap: 12px;
|
|
992
|
-
row-gap: 2px;
|
|
993
|
-
align-items: start;
|
|
994
|
-
padding: 12px 12px 12px 16px;
|
|
995
|
-
border-top: 1px solid var(--op-rule);
|
|
996
|
-
}
|
|
997
|
-
.atelic-ui .op-ov-row:hover {
|
|
998
|
-
background: var(--surface);
|
|
999
|
-
}
|
|
1000
|
-
.atelic-ui .op-ov-grade {
|
|
1001
|
-
grid-row: 1 / span 2;
|
|
1002
|
-
display: inline-flex;
|
|
1003
|
-
align-items: center;
|
|
1004
|
-
gap: 6px;
|
|
1005
|
-
}
|
|
1006
|
-
.atelic-ui .op-ov-grade .op-grade {
|
|
1007
|
-
width: 30px;
|
|
1008
|
-
height: 30px;
|
|
1009
|
-
border-radius: 9px;
|
|
1010
|
-
font-size: 15px;
|
|
1011
|
-
}
|
|
1012
|
-
.atelic-ui .op-ov-before .op-grade {
|
|
1013
|
-
opacity: 0.45;
|
|
1014
|
-
}
|
|
1015
|
-
.atelic-ui .op-ov-name {
|
|
1016
|
-
font-size: 16px;
|
|
1017
|
-
font-weight: 650;
|
|
1018
|
-
letter-spacing: -0.01em;
|
|
1019
|
-
line-height: 1.35;
|
|
1020
|
-
padding-top: 3px;
|
|
1021
|
-
}
|
|
1022
|
-
/* The name is the link, and it covers the row; a link inside the read
|
|
1023
|
-
sits above it. */
|
|
1024
|
-
.atelic-ui .op-ov-name a::after {
|
|
1025
|
-
content: "";
|
|
1026
|
-
position: absolute;
|
|
1027
|
-
inset: 0;
|
|
1028
|
-
}
|
|
1029
|
-
.atelic-ui .op-ov-row:hover .op-ov-name {
|
|
1030
|
-
color: var(--op-accent);
|
|
1031
|
-
}
|
|
1032
|
-
.atelic-ui .op-ov-read {
|
|
1033
|
-
grid-column: 2;
|
|
1034
|
-
font-size: 15px;
|
|
1035
|
-
line-height: 1.45;
|
|
1036
|
-
color: var(--op-ink-soft);
|
|
1037
|
-
text-wrap: pretty;
|
|
1038
|
-
}
|
|
1039
|
-
.atelic-ui .op-ov-read a {
|
|
1040
|
-
position: relative;
|
|
1041
|
-
z-index: 1;
|
|
1042
|
-
color: var(--op-accent);
|
|
1043
|
-
text-decoration: underline;
|
|
1044
|
-
text-underline-offset: 2px;
|
|
1045
|
-
}
|
|
1046
|
-
.atelic-ui .op-ov-go {
|
|
1047
|
-
grid-column: 3;
|
|
1048
|
-
grid-row: 1;
|
|
1049
|
-
margin-top: 5px;
|
|
1050
|
-
color: var(--neutral-300);
|
|
1051
|
-
}
|
|
1052
929
|
|
|
1053
930
|
/* ---- a part: the tier and the question it answers ---- */
|
|
1054
931
|
.atelic-ui .op-part {
|
|
@@ -1068,6 +945,23 @@
|
|
|
1068
945
|
font-size: 16.5px;
|
|
1069
946
|
color: var(--op-ink-soft);
|
|
1070
947
|
}
|
|
948
|
+
/* a part's name linked to its definition, the way a card's name is */
|
|
949
|
+
.atelic-ui .op-part h2 a {
|
|
950
|
+
display: inline-flex;
|
|
951
|
+
align-items: center;
|
|
952
|
+
gap: 6px;
|
|
953
|
+
color: inherit;
|
|
954
|
+
text-decoration: none;
|
|
955
|
+
border-bottom: 1px solid var(--neutral-200);
|
|
956
|
+
}
|
|
957
|
+
.atelic-ui .op-part h2 a svg {
|
|
958
|
+
color: var(--op-ink-faint);
|
|
959
|
+
}
|
|
960
|
+
.atelic-ui .op-part h2 a:hover,
|
|
961
|
+
.atelic-ui .op-part h2 a:hover svg {
|
|
962
|
+
color: var(--op-accent);
|
|
963
|
+
border-color: var(--op-accent);
|
|
964
|
+
}
|
|
1071
965
|
|
|
1072
966
|
/* ---- a topic: one section, a card of blocks ---- */
|
|
1073
967
|
.atelic-ui .op-topic {
|
|
@@ -1549,24 +1443,6 @@
|
|
|
1549
1443
|
.atelic-ui .op-intro {
|
|
1550
1444
|
font-size: 18px;
|
|
1551
1445
|
}
|
|
1552
|
-
.atelic-ui .op-ov-tier-label {
|
|
1553
|
-
padding: 7px 20px;
|
|
1554
|
-
}
|
|
1555
|
-
.atelic-ui .op-ov-row {
|
|
1556
|
-
grid-template-columns: auto 232px minmax(0, 1fr) auto;
|
|
1557
|
-
column-gap: 16px;
|
|
1558
|
-
padding: 11px 14px 11px 20px;
|
|
1559
|
-
}
|
|
1560
|
-
.atelic-ui .op-ov-grade {
|
|
1561
|
-
grid-row: 1;
|
|
1562
|
-
}
|
|
1563
|
-
.atelic-ui .op-ov-read {
|
|
1564
|
-
grid-column: 3;
|
|
1565
|
-
padding-top: 4px;
|
|
1566
|
-
}
|
|
1567
|
-
.atelic-ui .op-ov-go {
|
|
1568
|
-
grid-column: 4;
|
|
1569
|
-
}
|
|
1570
1446
|
.atelic-ui .op-part {
|
|
1571
1447
|
margin: 40px 0 12px;
|
|
1572
1448
|
}
|
|
@@ -1682,8 +1558,8 @@
|
|
|
1682
1558
|
html:has(.atelic-ui .op-doc) {
|
|
1683
1559
|
zoom: 0.74;
|
|
1684
1560
|
}
|
|
1685
|
-
.atelic-ui .op-
|
|
1686
|
-
.atelic-ui .op-
|
|
1561
|
+
.atelic-ui .op-topic h3 a svg,
|
|
1562
|
+
.atelic-ui .op-part h2 a svg {
|
|
1687
1563
|
display: none;
|
|
1688
1564
|
}
|
|
1689
1565
|
.atelic-ui,
|
|
@@ -1728,12 +1604,12 @@
|
|
|
1728
1604
|
width: auto;
|
|
1729
1605
|
display: block;
|
|
1730
1606
|
}
|
|
1731
|
-
.atelic-ui .op-ov-card,
|
|
1732
1607
|
.atelic-ui .op-topic {
|
|
1733
1608
|
box-shadow: none;
|
|
1734
1609
|
border-color: var(--neutral-200);
|
|
1735
1610
|
}
|
|
1736
|
-
.atelic-ui .op-topic h3 a
|
|
1611
|
+
.atelic-ui .op-topic h3 a,
|
|
1612
|
+
.atelic-ui .op-part h2 a {
|
|
1737
1613
|
border-bottom: 0;
|
|
1738
1614
|
}
|
|
1739
1615
|
/* A small block stays whole; a table or a disclosure may run over a
|
|
@@ -2177,7 +2053,6 @@
|
|
|
2177
2053
|
.atelic-ui .rd-note a,
|
|
2178
2054
|
.atelic-ui .rd-doc .op-why a,
|
|
2179
2055
|
.atelic-ui .rd-beat a,
|
|
2180
|
-
.atelic-ui .rd-gist-read a,
|
|
2181
2056
|
.atelic-ui .rd-plan a,
|
|
2182
2057
|
.atelic-ui .rd-closing a {
|
|
2183
2058
|
color: var(--op-accent);
|
|
@@ -2187,72 +2062,12 @@
|
|
|
2187
2062
|
overflow-wrap: anywhere;
|
|
2188
2063
|
}
|
|
2189
2064
|
|
|
2190
|
-
/* ---- the gist
|
|
2065
|
+
/* ---- the gist: the ReportCard (@atelic-action/ui), and this is its place on the page ---- */
|
|
2191
2066
|
.atelic-ui .rd-gist {
|
|
2192
2067
|
margin-top: 26px;
|
|
2193
2068
|
}
|
|
2194
|
-
.atelic-ui .rd-gist
|
|
2195
|
-
|
|
2196
|
-
background: var(--op-card);
|
|
2197
|
-
border: 1px solid var(--op-rule);
|
|
2198
|
-
border-radius: var(--radius-md);
|
|
2199
|
-
box-shadow: var(--shadow-sm);
|
|
2200
|
-
overflow: hidden;
|
|
2201
|
-
}
|
|
2202
|
-
.atelic-ui .rd-gist-table {
|
|
2203
|
-
width: 100%;
|
|
2204
|
-
border-collapse: collapse;
|
|
2205
|
-
font-size: 15px;
|
|
2206
|
-
line-height: 1.45;
|
|
2207
|
-
}
|
|
2208
|
-
.atelic-ui .rd-gist-table thead th {
|
|
2209
|
-
padding: 9px 12px;
|
|
2210
|
-
text-align: left;
|
|
2211
|
-
font-family: var(--font-mono);
|
|
2212
|
-
font-size: 11px;
|
|
2213
|
-
font-weight: 500;
|
|
2214
|
-
letter-spacing: 0.1em;
|
|
2215
|
-
text-transform: uppercase;
|
|
2216
|
-
color: var(--op-ink-faint);
|
|
2217
|
-
border-bottom: 1px solid var(--op-rule);
|
|
2218
|
-
}
|
|
2219
|
-
.atelic-ui .rd-gist-tier th {
|
|
2220
|
-
padding: 7px 12px;
|
|
2221
|
-
background: var(--surface-alt);
|
|
2222
|
-
text-align: left;
|
|
2223
|
-
font-family: var(--font-mono);
|
|
2224
|
-
font-size: 11.5px;
|
|
2225
|
-
font-weight: 500;
|
|
2226
|
-
letter-spacing: 0.1em;
|
|
2227
|
-
text-transform: uppercase;
|
|
2228
|
-
color: var(--op-ink-soft);
|
|
2229
|
-
}
|
|
2230
|
-
.atelic-ui .rd-gist-table tbody tr + tr > * {
|
|
2231
|
-
border-top: 1px solid var(--op-rule);
|
|
2232
|
-
}
|
|
2233
|
-
.atelic-ui .rd-gist-table tbody th[scope="row"],
|
|
2234
|
-
.atelic-ui .rd-gist-table td {
|
|
2235
|
-
padding: 11px 12px;
|
|
2236
|
-
vertical-align: top;
|
|
2237
|
-
text-align: left;
|
|
2238
|
-
}
|
|
2239
|
-
.atelic-ui .rd-gist-table .rd-gist-section {
|
|
2240
|
-
font-weight: 650;
|
|
2241
|
-
letter-spacing: -0.01em;
|
|
2242
|
-
width: 30%;
|
|
2243
|
-
}
|
|
2244
|
-
.atelic-ui .rd-gist-table tbody .rd-gist-section a:hover {
|
|
2245
|
-
color: var(--op-accent);
|
|
2246
|
-
}
|
|
2247
|
-
.atelic-ui .rd-gist-table .rd-gist-grade {
|
|
2248
|
-
width: 1%;
|
|
2249
|
-
white-space: nowrap;
|
|
2250
|
-
text-align: center;
|
|
2251
|
-
}
|
|
2252
|
-
.atelic-ui .rd-gist-table td.rd-gist-read {
|
|
2253
|
-
color: var(--op-ink-soft);
|
|
2254
|
-
text-wrap: pretty;
|
|
2255
|
-
min-width: 0;
|
|
2069
|
+
.atelic-ui .op-part + .rd-gist {
|
|
2070
|
+
margin-top: 0;
|
|
2256
2071
|
}
|
|
2257
2072
|
.atelic-ui .rd-beat {
|
|
2258
2073
|
margin-top: 20px;
|
|
@@ -2366,22 +2181,6 @@
|
|
|
2366
2181
|
.atelic-ui .rd-doc .op-shots-row[data-count="3"] {
|
|
2367
2182
|
max-width: none;
|
|
2368
2183
|
}
|
|
2369
|
-
/* Content patterns for a table inside a read, written by the content with ui's swatch: a rank with its badge in one cell, two equal halves, the swatch on the left and the figure on the right. These are the read's patterns, not a piece, until a consumer beyond the first wants them, when they move to ui. */
|
|
2370
|
-
.atelic-ui .rd-ranked {
|
|
2371
|
-
display: inline-grid;
|
|
2372
|
-
grid-template-columns: 1fr 1fr;
|
|
2373
|
-
column-gap: 8px;
|
|
2374
|
-
align-items: center;
|
|
2375
|
-
min-width: 3.4em;
|
|
2376
|
-
}
|
|
2377
|
-
.atelic-ui .rd-ranked .chart-swatch {
|
|
2378
|
-
justify-self: start;
|
|
2379
|
-
}
|
|
2380
|
-
.atelic-ui .rd-ranked > a,
|
|
2381
|
-
.atelic-ui .rd-ranked > span:last-child {
|
|
2382
|
-
justify-self: end;
|
|
2383
|
-
font-variant-numeric: tabular-nums;
|
|
2384
|
-
}
|
|
2385
2184
|
/* A swatch as a table cell: the chart key's box, keying the row in its tone, in a column marked fit. */
|
|
2386
2185
|
.atelic-ui .op-table .chart-swatch,
|
|
2387
2186
|
.atelic-ui .op-findings .callout-body .chart-swatch {
|
|
@@ -2407,10 +2206,12 @@
|
|
|
2407
2206
|
font-size: 16.5px;
|
|
2408
2207
|
color: var(--op-ink-soft);
|
|
2409
2208
|
}
|
|
2209
|
+
/* the steps: a large numeral in the accent, the title on its own line,
|
|
2210
|
+
the body under it, and the cards it draws on in a small line beneath */
|
|
2410
2211
|
.atelic-ui .rd-steps {
|
|
2411
2212
|
list-style: none;
|
|
2412
2213
|
counter-reset: rd-step;
|
|
2413
|
-
margin:
|
|
2214
|
+
margin: 14px 0 0;
|
|
2414
2215
|
padding: 0;
|
|
2415
2216
|
background: var(--op-card);
|
|
2416
2217
|
border: 1px solid var(--op-rule);
|
|
@@ -2420,38 +2221,66 @@
|
|
|
2420
2221
|
.atelic-ui .rd-step {
|
|
2421
2222
|
counter-increment: rd-step;
|
|
2422
2223
|
display: grid;
|
|
2423
|
-
grid-template-columns:
|
|
2224
|
+
grid-template-columns: 44px minmax(0, 1fr);
|
|
2424
2225
|
column-gap: 12px;
|
|
2425
|
-
padding:
|
|
2226
|
+
padding: 18px 20px 18px 18px;
|
|
2426
2227
|
}
|
|
2427
2228
|
.atelic-ui .rd-step + .rd-step {
|
|
2428
2229
|
border-top: 1px solid var(--op-rule);
|
|
2429
2230
|
}
|
|
2430
2231
|
.atelic-ui .rd-step::before {
|
|
2431
|
-
content: counter(rd-step);
|
|
2432
|
-
|
|
2433
|
-
|
|
2434
|
-
|
|
2435
|
-
|
|
2436
|
-
|
|
2437
|
-
|
|
2232
|
+
content: counter(rd-step, decimal-leading-zero);
|
|
2233
|
+
margin-top: 1px;
|
|
2234
|
+
font-family: var(--font-mono);
|
|
2235
|
+
font-size: 22px;
|
|
2236
|
+
font-weight: 500;
|
|
2237
|
+
line-height: 1.1;
|
|
2238
|
+
letter-spacing: -0.02em;
|
|
2438
2239
|
color: var(--op-accent);
|
|
2439
|
-
font-
|
|
2440
|
-
font-weight: 700;
|
|
2441
|
-
line-height: 1;
|
|
2240
|
+
font-variant-numeric: tabular-nums;
|
|
2442
2241
|
}
|
|
2443
|
-
.atelic-ui .rd-step
|
|
2444
|
-
|
|
2445
|
-
|
|
2446
|
-
|
|
2242
|
+
.atelic-ui .rd-step-body {
|
|
2243
|
+
min-width: 0;
|
|
2244
|
+
}
|
|
2245
|
+
.atelic-ui .rd-step-head {
|
|
2246
|
+
margin: 0;
|
|
2447
2247
|
}
|
|
2448
2248
|
.atelic-ui .rd-step-title {
|
|
2249
|
+
font-size: 17px;
|
|
2449
2250
|
font-weight: 650;
|
|
2251
|
+
letter-spacing: -0.015em;
|
|
2252
|
+
line-height: 1.3;
|
|
2450
2253
|
color: var(--op-ink);
|
|
2451
2254
|
}
|
|
2255
|
+
.atelic-ui .rd-step-body > p + p {
|
|
2256
|
+
margin: 5px 0 0;
|
|
2257
|
+
font-size: 15.5px;
|
|
2258
|
+
line-height: 1.5;
|
|
2259
|
+
color: var(--op-ink-soft);
|
|
2260
|
+
text-wrap: pretty;
|
|
2261
|
+
}
|
|
2262
|
+
.atelic-ui .rd-step-body > .rd-step-cards {
|
|
2263
|
+
display: flex;
|
|
2264
|
+
flex-wrap: wrap;
|
|
2265
|
+
gap: 4px 18px;
|
|
2266
|
+
margin-top: 9px;
|
|
2267
|
+
font-family: var(--font-mono);
|
|
2268
|
+
font-size: 11px;
|
|
2269
|
+
font-weight: 500;
|
|
2270
|
+
letter-spacing: 0.1em;
|
|
2271
|
+
text-transform: uppercase;
|
|
2272
|
+
}
|
|
2273
|
+
.atelic-ui .rd-step-cards a {
|
|
2274
|
+
color: var(--op-accent);
|
|
2275
|
+
text-decoration: none;
|
|
2276
|
+
}
|
|
2277
|
+
.atelic-ui .rd-step-cards a:hover {
|
|
2278
|
+
text-decoration: underline;
|
|
2279
|
+
text-underline-offset: 3px;
|
|
2280
|
+
}
|
|
2452
2281
|
.atelic-ui .rd-step-who {
|
|
2453
2282
|
display: inline-block;
|
|
2454
|
-
margin-left:
|
|
2283
|
+
margin-left: 8px;
|
|
2455
2284
|
padding: 1px 8px;
|
|
2456
2285
|
border: 1px solid var(--neutral-200);
|
|
2457
2286
|
border-radius: 999px;
|
|
@@ -2474,13 +2303,6 @@
|
|
|
2474
2303
|
|
|
2475
2304
|
/* ---- wide and on paper: the pictures beside each other ---- */
|
|
2476
2305
|
@media print, (min-width: 721px) {
|
|
2477
|
-
.atelic-ui .rd-gist-table tbody th[scope="row"],
|
|
2478
|
-
.atelic-ui .rd-gist-table td,
|
|
2479
|
-
.atelic-ui .rd-gist-table thead th,
|
|
2480
|
-
.atelic-ui .rd-gist-tier th {
|
|
2481
|
-
padding-left: 20px;
|
|
2482
|
-
padding-right: 16px;
|
|
2483
|
-
}
|
|
2484
2306
|
.atelic-ui .rd-changes-table {
|
|
2485
2307
|
display: table;
|
|
2486
2308
|
table-layout: fixed;
|
|
@@ -2546,12 +2368,10 @@
|
|
|
2546
2368
|
/* ---- print: the writeup's rules carry the page; these hold the read's
|
|
2547
2369
|
own blocks whole ---- */
|
|
2548
2370
|
@media print {
|
|
2549
|
-
.atelic-ui .rd-gist-card,
|
|
2550
2371
|
.atelic-ui .rd-steps {
|
|
2551
2372
|
box-shadow: none;
|
|
2552
2373
|
border-color: var(--neutral-200);
|
|
2553
2374
|
}
|
|
2554
|
-
.atelic-ui .rd-gist-table tr,
|
|
2555
2375
|
.atelic-ui .rd-changes-table tr,
|
|
2556
2376
|
.atelic-ui .rd-checks li,
|
|
2557
2377
|
.atelic-ui .rd-closing,
|