@motion-proto/live-tokens 0.80.0 → 0.82.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +35 -0
- package/package.json +17 -1
- package/src/demo/Demo.svelte +97 -0
- package/src/demo/Demo.svelte.d.ts +7 -0
- package/src/demo/DemoBar.svelte +75 -0
- package/src/demo/FloatingTokenTags.css +284 -0
- package/src/demo/FloatingTokenTags.svelte +570 -0
- package/src/demo/LabeledSelect.svelte +243 -0
- package/src/demo/Section.svelte +46 -0
- package/src/demo/SketchSelect.svelte +58 -0
- package/src/demo/SourceLinks.svelte +156 -0
- package/src/demo/TestingLoops.svelte +876 -0
- package/src/demo/TestingLoops.svelte.d.ts +4 -0
- package/src/demo/ThemeSelect.svelte +52 -0
- package/src/demo/sections/SectionClaude.svelte +192 -0
- package/src/demo/sections/SectionFooter.svelte +67 -0
- package/src/demo/sections/SectionGetStarted.svelte +100 -0
- package/src/demo/sections/SectionHero.svelte +201 -0
- package/src/demo/sections/SectionKit.svelte +410 -0
- package/src/demo/sections/SectionLayers.svelte +54 -0
- package/src/demo/sections/SectionOffering.svelte +135 -0
- package/src/demo/sketchCarry.ts +91 -0
- package/src/editor/skill-atlas/SkillAtlas.svelte +42 -19
- package/src/editor/skill-atlas/atlasLink.ts +43 -0
|
@@ -0,0 +1,876 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import CollapsibleSection from '../system/components/CollapsibleSection.svelte';
|
|
3
|
+
import Panel from '../system/components/Panel.svelte';
|
|
4
|
+
import Table from '../system/components/Table.svelte';
|
|
5
|
+
import Card from '../system/components/Card.svelte';
|
|
6
|
+
import { portal } from '../system/internal/portal';
|
|
7
|
+
import { navigate } from '../editor/core/routing/router';
|
|
8
|
+
|
|
9
|
+
let { homeHref = '/demo' }: { homeHref?: string } = $props();
|
|
10
|
+
|
|
11
|
+
const chapters = [
|
|
12
|
+
{ id: 'skills', title: 'LiveTokens skills' },
|
|
13
|
+
{ id: 'checkers', title: 'CLI Check' },
|
|
14
|
+
{ id: 'test-runs', title: 'Testing pages and components' },
|
|
15
|
+
{ id: 'walkthrough', title: 'Build and check a page' },
|
|
16
|
+
{ id: 'reference', title: 'Rule reference' },
|
|
17
|
+
];
|
|
18
|
+
|
|
19
|
+
// Closed by default: open, the fixed panel covers the full-width figures.
|
|
20
|
+
let contentsOpen = $state(false);
|
|
21
|
+
|
|
22
|
+
let openRules = $state<Record<string, boolean>>({});
|
|
23
|
+
|
|
24
|
+
function jump(event: MouseEvent, id: string) {
|
|
25
|
+
event.preventDefault();
|
|
26
|
+
contentsOpen = false;
|
|
27
|
+
document.getElementById(id)?.scrollIntoView({ behavior: window.matchMedia('(prefers-reduced-motion: reduce)').matches ? 'instant' : 'smooth', block: 'start' });
|
|
28
|
+
}
|
|
29
|
+
</script>
|
|
30
|
+
|
|
31
|
+
<!-- The markers live in one hidden SVG so every figure can reference them by a
|
|
32
|
+
single document-unique id. -->
|
|
33
|
+
<svg class="markers" aria-hidden="true">
|
|
34
|
+
<defs>
|
|
35
|
+
<marker id="loops-arw" viewBox="0 0 10 10" refX="5.9" refY="5" markerWidth="5.7" markerHeight="5.7" orient="auto-start-reverse">
|
|
36
|
+
<polygon class="head" points="0,1.5 10,5 0,8.5" />
|
|
37
|
+
</marker>
|
|
38
|
+
<marker id="loops-arw-back" viewBox="0 0 10 10" refX="5.9" refY="5" markerWidth="5.7" markerHeight="5.7" orient="auto-start-reverse">
|
|
39
|
+
<polygon class="head-back" points="0,1.5 10,5 0,8.5" />
|
|
40
|
+
</marker>
|
|
41
|
+
</defs>
|
|
42
|
+
</svg>
|
|
43
|
+
|
|
44
|
+
<div class="loops">
|
|
45
|
+
<header class="masthead">
|
|
46
|
+
<div class="chapter-body">
|
|
47
|
+
<a class="back-link" href={homeHref} onclick={(event) => { event.preventDefault(); navigate(homeHref); }}>
|
|
48
|
+
<span aria-hidden="true">←</span> Back to demo
|
|
49
|
+
</a>
|
|
50
|
+
<h1>Validating Skill Output</h1>
|
|
51
|
+
<div class="introduction">
|
|
52
|
+
<p>LiveTokens includes Claude skills that create pages and components. The results of these skills are checked with CLI commands to validate the output against the design system. This creates an inner feedback loop that mirrors the testing you would have in a build process: a deterministic layer with a pass/fail result rather than an interpretive LLM response.</p>
|
|
53
|
+
</div>
|
|
54
|
+
</div>
|
|
55
|
+
</header>
|
|
56
|
+
|
|
57
|
+
<section class="chapter" id="skills" aria-labelledby="skills-title">
|
|
58
|
+
<div class="chapter-body">
|
|
59
|
+
<h2 id="skills-title">LiveTokens skills</h2>
|
|
60
|
+
<div class="text-columns skills-overview">
|
|
61
|
+
<div>
|
|
62
|
+
<p>The CLI checks verify that skill output uses the design system and works correctly in the browser. They cover token use, component behavior, and page layout. Skills make design decisions and the CLI verifies the code.</p>
|
|
63
|
+
<p>The package includes eight skills, and one setup command copies them into your project.</p>
|
|
64
|
+
</div>
|
|
65
|
+
<ul class="skill-stack">
|
|
66
|
+
<li><Card variant="bare" prose={false}><h3>Build skills</h3><p>Build pages and create new components.</p></Card></li>
|
|
67
|
+
<li><Card variant="bare" prose={false}><h3>Check skills</h3><p>Check the code of every page and component.</p></Card></li>
|
|
68
|
+
<li><Card variant="bare" prose={false}><h3>Theme skills</h3><p>Create and customize themes for LiveTokens.</p></Card></li>
|
|
69
|
+
</ul>
|
|
70
|
+
</div>
|
|
71
|
+
</div>
|
|
72
|
+
</section>
|
|
73
|
+
|
|
74
|
+
<section class="chapter" id="checkers" aria-labelledby="checkers-title">
|
|
75
|
+
<div class="chapter-body">
|
|
76
|
+
<h2 id="checkers-title">CLI Check</h2>
|
|
77
|
+
<div class="text-columns checker-details">
|
|
78
|
+
<div>
|
|
79
|
+
<p>The page checker confirms that pages use catalogue components, valid props, and design tokens.</p>
|
|
80
|
+
<p>The component checker confirms that every property uses design tokens and that the component appears in the catalogue and the editor.</p>
|
|
81
|
+
<p>Both checkers flag unknown token and property names. Each finding names the rule broken and explains the fix. The table lists what each repair level means.</p>
|
|
82
|
+
<p>The skill makes its fixes and runs the checks again.</p>
|
|
83
|
+
</div>
|
|
84
|
+
<Table>
|
|
85
|
+
<table aria-label="Repair levels">
|
|
86
|
+
<thead><tr><th scope="col">Repair level</th><th scope="col">Description</th></tr></thead>
|
|
87
|
+
<tbody>
|
|
88
|
+
<tr><td>Automatic</td><td>The checker fixed the problem.</td></tr>
|
|
89
|
+
<tr><td>Choice</td><td>The skill picks a fix.</td></tr>
|
|
90
|
+
<tr><td>Authored</td><td>The skill writes the fix.</td></tr>
|
|
91
|
+
</tbody>
|
|
92
|
+
</table>
|
|
93
|
+
</Table>
|
|
94
|
+
</div>
|
|
95
|
+
</div>
|
|
96
|
+
</section>
|
|
97
|
+
|
|
98
|
+
<section class="chapter" id="test-runs" aria-labelledby="test-runs-title">
|
|
99
|
+
<div class="chapter-body">
|
|
100
|
+
<h2 id="test-runs-title">Testing pages and components</h2>
|
|
101
|
+
<p>When a skill creates a component or a page, the checker reviews the code against the design system, then tests the result. For a component, Vitest checks its registration and callbacks, and Playwright checks its rendering, input handling, and themes. For a page, Playwright checks layout, contrast, and typography.</p>
|
|
102
|
+
|
|
103
|
+
<figure>
|
|
104
|
+
<figcaption><b>Figure 1. The testing loop.</b></figcaption>
|
|
105
|
+
<div class="figure-stage">
|
|
106
|
+
<!-- svelte-ignore a11y_no_noninteractive_tabindex (Keyboard users need to scroll the diagram.) -->
|
|
107
|
+
<div class="figure-scroll" role="region" aria-label="Figure 1" tabindex="0">
|
|
108
|
+
<svg class="dg" viewBox="20 12 1160 866" role="img" aria-label="The skill builds a page or component and runs the checks. The CLI checker checks the code, makes the routine repairs, tests the result, and reports the findings. The skill repairs each finding and runs the checks again until every check passes.">
|
|
109
|
+
<rect class="lane-checker" x="20" y="12" width="1160" height="866" rx="8" />
|
|
110
|
+
<path class="lane-skill" d="M28,12 H600 V878 H28 A8,8 0 0 1 20,870 V20 A8,8 0 0 1 28,12 Z" />
|
|
111
|
+
<path class="lane-shade" d="M600,12 H1172 A8,8 0 0 1 1180,20 V870 A8,8 0 0 1 1172,878 H600 Z" />
|
|
112
|
+
<text class="lane-title" x="80" y="52">Claude Skill</text>
|
|
113
|
+
<text class="lane-title" x="660" y="52">CLI checker</text>
|
|
114
|
+
<path class="flow" d="M540,148 L876,148 Q890,148 890,162 L890,225" />
|
|
115
|
+
<path class="flow" d="M890,320 L890,353" />
|
|
116
|
+
<path class="flow" d="M890,448 L890,481" />
|
|
117
|
+
<path class="flow" d="M890,600 L890,633" />
|
|
118
|
+
<path class="flow" d="M660,684 L547,684" />
|
|
119
|
+
<path class="flow" d="M890,728 L890,781" />
|
|
120
|
+
<path class="back" d="M310,640 L310,290 Q310,276 324,276 L653,276" />
|
|
121
|
+
<rect class="box-lead" x="80" y="104" width="460" height="88" rx="4" />
|
|
122
|
+
<text class="t" x="101.3" y="138">Build a page or component</text>
|
|
123
|
+
<text class="s" x="101.3" y="166">from the catalogue and design tokens</text>
|
|
124
|
+
<rect class="box" x="660" y="232" width="460" height="88" rx="4" />
|
|
125
|
+
<text class="t" x="681.3" y="266">Check the code</text>
|
|
126
|
+
<text class="tag" x="1098.7" y="266" text-anchor="end">Static check</text>
|
|
127
|
+
<text class="s" x="681.3" y="294">design tokens, components, and props</text>
|
|
128
|
+
<rect class="box" x="660" y="360" width="460" height="88" rx="4" />
|
|
129
|
+
<text class="t" x="681.3" y="394">Make the routine repairs</text>
|
|
130
|
+
<text class="s" x="681.3" y="422">fixes with one right answer</text>
|
|
131
|
+
<rect class="box" x="660" y="488" width="460" height="112" rx="4" />
|
|
132
|
+
<text class="t" x="681.3" y="522">Test the result</text>
|
|
133
|
+
<text class="tag" x="1098.7" y="522" text-anchor="end">Vitest · Playwright</text>
|
|
134
|
+
<text class="s" x="681.3" y="550">Test component interactions, rendering, and themes.</text>
|
|
135
|
+
<text class="s" x="681.3" y="574">Check page layout, contrast, and typography.</text>
|
|
136
|
+
<rect class="box" x="660" y="640" width="460" height="88" rx="4" />
|
|
137
|
+
<text class="t" x="681.3" y="674">Report the findings</text>
|
|
138
|
+
<text class="s" x="681.3" y="702">each with guidance for its repair</text>
|
|
139
|
+
<rect class="box" x="80" y="640" width="460" height="88" rx="4" />
|
|
140
|
+
<text class="t" x="101.3" y="674">Repair each finding</text>
|
|
141
|
+
<text class="s" x="101.3" y="702">make the choice or write the code</text>
|
|
142
|
+
<rect class="box-lead" x="660" y="788" width="460" height="72" rx="4" />
|
|
143
|
+
<text class="t" x="890" y="830" text-anchor="middle">Every check passes</text>
|
|
144
|
+
<text class="lbl" x="715" y="136" text-anchor="middle">run the checks</text>
|
|
145
|
+
<text class="lbl" x="600" y="672" text-anchor="middle">findings</text>
|
|
146
|
+
<text class="lbl" x="906" y="759">none remain</text>
|
|
147
|
+
<text class="rule" x="479" y="262" text-anchor="middle">check again</text>
|
|
148
|
+
</svg>
|
|
149
|
+
</div>
|
|
150
|
+
</div>
|
|
151
|
+
</figure>
|
|
152
|
+
|
|
153
|
+
</div>
|
|
154
|
+
</section>
|
|
155
|
+
|
|
156
|
+
<section class="chapter" id="walkthrough" aria-labelledby="walkthrough-title">
|
|
157
|
+
<div class="chapter-body">
|
|
158
|
+
<h2 id="walkthrough-title">Build and check a page</h2>
|
|
159
|
+
<p><span class="name">create-page</span> builds each page from tested components. When the catalogue lacks a component, the skill creates one and checks it before the page uses it.</p>
|
|
160
|
+
|
|
161
|
+
<figure class="workflow-diagram">
|
|
162
|
+
<figcaption><b>Figure 2. The page workflow.</b></figcaption>
|
|
163
|
+
<div class="figure-stage">
|
|
164
|
+
<!-- svelte-ignore a11y_no_noninteractive_tabindex (Keyboard users need to scroll the diagram.) -->
|
|
165
|
+
<div class="figure-scroll" role="region" aria-label="Figure 2" tabindex="0">
|
|
166
|
+
<svg class="dg" viewBox="20 12 1160 916" role="img" aria-label="Read the project, plan the sections, and choose components. When no component fits, create one and check it until every check passes, and it joins the catalogue. Assemble the page and check it. Repair each finding until every check passes, then review the page.">
|
|
167
|
+
<rect class="lane-checker" x="20" y="12" width="1160" height="916" rx="8" />
|
|
168
|
+
<path class="lane-skill" d="M28,12 H600 V928 H28 A8,8 0 0 1 20,920 V20 A8,8 0 0 1 28,12 Z" />
|
|
169
|
+
<path class="lane-shade" d="M600,12 H1172 A8,8 0 0 1 1180,20 V920 A8,8 0 0 1 1172,928 H600 Z" />
|
|
170
|
+
<text class="lane-title" x="80" y="52">Page</text>
|
|
171
|
+
<text class="lane-title" x="660" y="52">New component</text>
|
|
172
|
+
<path class="flow" d="M310,192 L310,225" />
|
|
173
|
+
<path class="flow" d="M310,320 L310,353" />
|
|
174
|
+
<path class="flow" d="M310,448 L310,545" />
|
|
175
|
+
<path class="flow" d="M540,404 L653,404" />
|
|
176
|
+
<path class="flow" d="M890,472 L890,570 Q890,584 876,584 L547,584" />
|
|
177
|
+
<path class="flow" d="M310,640 L310,673" />
|
|
178
|
+
<path class="back" d="M540,724 L556,724 Q570,724 570,710 L570,629 Q570,620 561,620 L547,620" />
|
|
179
|
+
<path class="flow" d="M310,768 L310,813" />
|
|
180
|
+
<rect class="box-lead" x="80" y="104" width="460" height="88" rx="4" />
|
|
181
|
+
<text class="t" x="101.3" y="138">Read the project</text>
|
|
182
|
+
<text class="s" x="101.3" y="166">routes, grid, and the component catalogue</text>
|
|
183
|
+
<rect class="box" x="80" y="232" width="460" height="88" rx="4" />
|
|
184
|
+
<text class="t" x="101.3" y="266">Plan the sections</text>
|
|
185
|
+
<text class="s" x="101.3" y="294">one section per purpose</text>
|
|
186
|
+
<rect class="box" x="80" y="360" width="460" height="88" rx="4" />
|
|
187
|
+
<text class="t" x="101.3" y="394">Choose components</text>
|
|
188
|
+
<text class="s" x="101.3" y="422">from the catalogue first</text>
|
|
189
|
+
<rect class="box" x="660" y="360" width="460" height="112" rx="4" />
|
|
190
|
+
<text class="t" x="681.3" y="394">Create the component</text>
|
|
191
|
+
<text class="s" x="681.3" y="422">check it and repair it</text>
|
|
192
|
+
<text class="s" x="681.3" y="446">until every check passes</text>
|
|
193
|
+
<rect class="box" x="80" y="552" width="460" height="88" rx="4" />
|
|
194
|
+
<text class="t" x="101.3" y="586">Assemble the page</text>
|
|
195
|
+
<text class="s" x="101.3" y="614">components, tokens, and text styles</text>
|
|
196
|
+
<rect class="box" x="80" y="680" width="460" height="88" rx="4" />
|
|
197
|
+
<text class="t" x="101.3" y="714">Check the page</text>
|
|
198
|
+
<text class="s" x="101.3" y="742">review the code and test it in the browser</text>
|
|
199
|
+
<rect class="box-lead" x="80" y="820" width="460" height="88" rx="4" />
|
|
200
|
+
<text class="t" x="101.3" y="854">Review the page</text>
|
|
201
|
+
<text class="s" x="101.3" y="882">read it the way a visitor would</text>
|
|
202
|
+
<text class="lbl" x="326" y="499">a shipped component fits</text>
|
|
203
|
+
<text class="lbl" x="600" y="392" text-anchor="middle">none fits</text>
|
|
204
|
+
<text class="lbl" x="715" y="572" text-anchor="middle">joins the catalogue</text>
|
|
205
|
+
<text class="rule" x="584" y="677">repair</text>
|
|
206
|
+
<text class="lbl" x="326" y="793">every check passes</text>
|
|
207
|
+
</svg>
|
|
208
|
+
</div>
|
|
209
|
+
</div>
|
|
210
|
+
</figure>
|
|
211
|
+
|
|
212
|
+
<ol class="steps">
|
|
213
|
+
<li><strong>Read the project.</strong> Read the routes, the grid, and the component catalogue.</li>
|
|
214
|
+
<li><strong>Plan the sections.</strong> Give each purpose its own section.</li>
|
|
215
|
+
<li><strong>Choose components.</strong> Start with the catalogue. When no component fits, create one, then check and repair it until every check passes.</li>
|
|
216
|
+
<li><strong>Assemble the page.</strong> Build it from components, design tokens, and text styles.</li>
|
|
217
|
+
<li><strong>Check the page.</strong> The checker reviews the code and tests the page in the browser. Repair each finding and check again until every check passes.</li>
|
|
218
|
+
<li><strong>Review the page.</strong> Read it the way a visitor would, and confirm that it supports the reader’s task.</li>
|
|
219
|
+
</ol>
|
|
220
|
+
</div>
|
|
221
|
+
</section>
|
|
222
|
+
|
|
223
|
+
<section class="chapter" id="reference" aria-labelledby="reference-title">
|
|
224
|
+
<div class="chapter-body">
|
|
225
|
+
<h2 id="reference-title">Rule reference</h2>
|
|
226
|
+
<p>Expand a group to read its rules. The skills treat every rule as an error and repair each finding before they finish.</p>
|
|
227
|
+
<div class="reference-groups">
|
|
228
|
+
<div class="rule-group">
|
|
229
|
+
<CollapsibleSection label="Page code · 19 rules" variant="hairline" prose={false} open={openRules['0'] ?? false} ontoggle={() => openRules['0'] = !openRules['0']}>
|
|
230
|
+
<Table>
|
|
231
|
+
<table aria-label="Page code · 19 rules">
|
|
232
|
+
<thead><tr><th scope="col">Rule</th><th scope="col">Description</th></tr></thead>
|
|
233
|
+
<tbody>
|
|
234
|
+
<tr><td>tokens-migration</td><td>An additive migration would add design tokens <code>tokens.css</code> lacks. The checker applies it during a repair run.</td></tr>
|
|
235
|
+
<tr><td>tokens-breaking-migration</td><td>A breaking migration that renames, removes, or rewrites design tokens in <code>tokens.css</code> is pending.</td></tr>
|
|
236
|
+
<tr><td>unknown-component</td><td>An import names a component outside the catalogue.</td></tr>
|
|
237
|
+
<tr><td>unknown-prop</td><td>A component receives a prop it does not declare.</td></tr>
|
|
238
|
+
<tr><td>unknown-prop-value</td><td>A prop receives a value outside the set the component accepts.</td></tr>
|
|
239
|
+
<tr><td>deep-import</td><td>An import reaches into package internals. Import from a public entry point.</td></tr>
|
|
240
|
+
<tr><td>unknown-token</td><td>A <code>var()</code> reference uses an unknown token name.</td></tr>
|
|
241
|
+
<tr><td>color-literal</td><td>A color value uses a literal instead of a design token.</td></tr>
|
|
242
|
+
<tr><td>reserved-route</td><td>A route uses the reserved <code>/live-tokens/*</code> namespace.</td></tr>
|
|
243
|
+
<tr><td>site-css-in-main</td><td><code>main.ts</code> imports <code>site.css</code>, which leaks it into the editor routes.</td></tr>
|
|
244
|
+
<tr><td>raw-text-axis</td><td>A font size, family, line height, or letter spacing uses a literal or a single-axis token instead of a text style.</td></tr>
|
|
245
|
+
<tr><td>dimension-literal</td><td>A spacing, inset, stroke, radius, or shadow value uses a non-zero px or rem literal instead of a token.</td></tr>
|
|
246
|
+
<tr><td>hardcoded-columns</td><td>A grid uses <code>repeat(N, 1fr)</code> with four or more columns. Use <code>--columns-count</code>.</td></tr>
|
|
247
|
+
<tr><td>missing-source</td><td>A route has no <code>source</code>, so Page Source cannot open it.</td></tr>
|
|
248
|
+
<tr><td>control-size</td><td>The page sets <code>size</code> on a shipped component.</td></tr>
|
|
249
|
+
<tr><td>multiple-primary</td><td>The page uses more than one primary Button.</td></tr>
|
|
250
|
+
<tr><td>danger-without-dialog</td><td>The page has a danger Button or IconButton and no Dialog.</td></tr>
|
|
251
|
+
<tr><td>native-control</td><td>A bare <code><button></code>, <code><input></code>, <code><select></code>, or <code><textarea></code> replaces a shipped control.</td></tr>
|
|
252
|
+
<tr><td>property-override</td><td>The page redeclares a component's semantic property for one instance.</td></tr>
|
|
253
|
+
</tbody>
|
|
254
|
+
</table>
|
|
255
|
+
</Table>
|
|
256
|
+
</CollapsibleSection>
|
|
257
|
+
</div>
|
|
258
|
+
<div class="rule-group">
|
|
259
|
+
<CollapsibleSection label="Page browser tests · 5 rules" variant="hairline" prose={false} open={openRules['1'] ?? false} ontoggle={() => openRules['1'] = !openRules['1']}>
|
|
260
|
+
<Table>
|
|
261
|
+
<table aria-label="Page browser tests · 5 rules">
|
|
262
|
+
<thead><tr><th scope="col">Rule</th><th scope="col">Description</th></tr></thead>
|
|
263
|
+
<tbody>
|
|
264
|
+
<tr><td>page-component-paint</td><td>Each component part renders the value of its semantic property.</td></tr>
|
|
265
|
+
<tr><td>page-text-style</td><td>Text outside components matches a complete text style from the design system.</td></tr>
|
|
266
|
+
<tr><td>page-contrast</td><td>Text outside components meets WCAG AA against its surface.</td></tr>
|
|
267
|
+
<tr><td>page-grid</td><td>Section edges align to column lines at 768px and wider.</td></tr>
|
|
268
|
+
<tr><td>page-overflow</td><td>Content stays inside its container, and the page scrolls only vertically.</td></tr>
|
|
269
|
+
</tbody>
|
|
270
|
+
</table>
|
|
271
|
+
</Table>
|
|
272
|
+
</CollapsibleSection>
|
|
273
|
+
</div>
|
|
274
|
+
<div class="rule-group">
|
|
275
|
+
<CollapsibleSection label="Component code · 22 rules" variant="hairline" prose={false} open={openRules['2'] ?? false} ontoggle={() => openRules['2'] = !openRules['2']}>
|
|
276
|
+
<Table>
|
|
277
|
+
<table aria-label="Component code · 22 rules">
|
|
278
|
+
<thead><tr><th scope="col">Rule</th><th scope="col">Description</th></tr></thead>
|
|
279
|
+
<tbody>
|
|
280
|
+
<tr><td>tokens-migration</td><td>An additive migration would add design tokens <code>tokens.css</code> lacks. The checker applies it during a repair run.</td></tr>
|
|
281
|
+
<tr><td>tokens-breaking-migration</td><td>A breaking migration that renames, removes, or rewrites design tokens in <code>tokens.css</code> is pending.</td></tr>
|
|
282
|
+
<tr><td>invalid-id</td><td>The id contains characters other than lowercase letters and digits, or starts with a digit.</td></tr>
|
|
283
|
+
<tr><td>missing-file</td><td>The runtime or editor file is missing.</td></tr>
|
|
284
|
+
<tr><td>missing-root-block</td><td>The runtime has no <code>:global(:root)</code> block.</td></tr>
|
|
285
|
+
<tr><td>no-tokens</td><td>The <code>:global(:root)</code> block declares no <code>--<id>-*</code> property.</td></tr>
|
|
286
|
+
<tr><td>missing-description</td><td>The runtime's <code>catalogue</code> export is missing or lacks a required field.</td></tr>
|
|
287
|
+
<tr><td>unread-token</td><td>The runtime declares a property and never reads it.</td></tr>
|
|
288
|
+
<tr><td>state-after-property</td><td>A property name places the state after the property. Use <code>-hover-surface</code>.</td></tr>
|
|
289
|
+
<tr><td>disabled-is-terminal</td><td>A property name combines <code>disabled</code> with another state. The component cannot render that combination.</td></tr>
|
|
290
|
+
<tr><td>unknown-suffix</td><td>A property name uses a suffix the editor cannot edit.</td></tr>
|
|
291
|
+
<tr><td>phantom-editor-token</td><td>An editor row names a property the runtime never declares.</td></tr>
|
|
292
|
+
<tr><td>color-literal</td><td>A default is a literal color.</td></tr>
|
|
293
|
+
<tr><td>missing-component-const</td><td>The editor lacks <code>const component = '<id>'</code>.</td></tr>
|
|
294
|
+
<tr><td>missing-all-tokens</td><td>The editor does not export <code>allTokens</code>.</td></tr>
|
|
295
|
+
<tr><td>deep-import</td><td>A component file imports from package internals.</td></tr>
|
|
296
|
+
<tr><td>missing-registration</td><td>Nothing under <code>src/</code> registers the id.</td></tr>
|
|
297
|
+
<tr><td>unknown-token-ref</td><td>A default references an unknown token name.</td></tr>
|
|
298
|
+
<tr><td>default-not-token</td><td>A default lacks both a design token and a declared intrinsic.</td></tr>
|
|
299
|
+
<tr><td>phantom-link</td><td>A font helper spans several slots without a derivation, which links their fonts.</td></tr>
|
|
300
|
+
<tr><td>dimension-literal</td><td>A default uses a non-zero px or rem literal instead of a design token.</td></tr>
|
|
301
|
+
<tr><td>config-token</td><td>A default config references an unknown token name, or aliases a literal the editor does not declare as intrinsic.</td></tr>
|
|
302
|
+
</tbody>
|
|
303
|
+
</table>
|
|
304
|
+
</Table>
|
|
305
|
+
</CollapsibleSection>
|
|
306
|
+
</div>
|
|
307
|
+
<div class="rule-group">
|
|
308
|
+
<CollapsibleSection label="Component tests · 11 rules" variant="hairline" prose={false} open={openRules['3'] ?? false} ontoggle={() => openRules['3'] = !openRules['3']}>
|
|
309
|
+
<Table>
|
|
310
|
+
<table aria-label="Component tests · 11 rules">
|
|
311
|
+
<thead><tr><th scope="col">Rule</th><th scope="col">Description</th></tr></thead>
|
|
312
|
+
<tbody>
|
|
313
|
+
<tr><td>contract-registry</td><td>Vitest. The component has a valid registration, property declarations, and default values.</td></tr>
|
|
314
|
+
<tr><td>contract-behavior</td><td>Vitest. Callback props receive the arguments each case expects.</td></tr>
|
|
315
|
+
<tr><td>contract-listed</td><td>Playwright. The component appears in its registry group.</td></tr>
|
|
316
|
+
<tr><td>contract-alias</td><td>Playwright. The component declares every part and alias, each alias resolves, and each edit reaches the document root.</td></tr>
|
|
317
|
+
<tr><td>contract-states</td><td>Playwright. The preview renders the state the editor selects.</td></tr>
|
|
318
|
+
<tr><td>contract-interaction</td><td>Playwright. The component responds to pointer and keyboard input.</td></tr>
|
|
319
|
+
<tr><td>contract-persist</td><td>Playwright. An edit survives save and reload, and Reset restores the saved config.</td></tr>
|
|
320
|
+
<tr><td>contract-theme</td><td>Playwright. A theme preview updates the component, and Cancel restores the original values.</td></tr>
|
|
321
|
+
<tr><td>contract-sketch</td><td>Playwright. Sketch mode draws every visible part.</td></tr>
|
|
322
|
+
<tr><td>contract-render</td><td>Playwright. The runtime preview applies each property to the correct part.</td></tr>
|
|
323
|
+
<tr><td>contract-missing</td><td>Playwright. The named component has no contract.</td></tr>
|
|
324
|
+
</tbody>
|
|
325
|
+
</table>
|
|
326
|
+
</Table>
|
|
327
|
+
</CollapsibleSection>
|
|
328
|
+
</div>
|
|
329
|
+
<div class="rule-group">
|
|
330
|
+
<CollapsibleSection label="Test runner · 3 rules" variant="hairline" prose={false} open={openRules['4'] ?? false} ontoggle={() => openRules['4'] = !openRules['4']}>
|
|
331
|
+
<Table>
|
|
332
|
+
<table aria-label="Test runner · 3 rules">
|
|
333
|
+
<thead><tr><th scope="col">Rule</th><th scope="col">Description</th></tr></thead>
|
|
334
|
+
<tbody>
|
|
335
|
+
<tr><td>tests-not-installed</td><td><code>@playwright/test</code>, <code>vitest</code>, or <code>happy-dom</code> is missing, or Playwright’s Chromium is not installed.</td></tr>
|
|
336
|
+
<tr><td>tests-setup</td><td>The run could not start, found nothing to check, found no route for the page, or a tool crashed before it wrote a report.</td></tr>
|
|
337
|
+
<tr><td>tests-incomplete</td><td>A run timed out, collected no tests, or left a component and rule pair without a result.</td></tr>
|
|
338
|
+
</tbody>
|
|
339
|
+
</table>
|
|
340
|
+
</Table>
|
|
341
|
+
</CollapsibleSection>
|
|
342
|
+
</div>
|
|
343
|
+
</div>
|
|
344
|
+
</div>
|
|
345
|
+
</section>
|
|
346
|
+
|
|
347
|
+
<!-- NOTES, open questions for this page:
|
|
348
|
+
- "Review by eye" (walkthrough step 7) and Figure 2's "Read the page yourself".
|
|
349
|
+
Leaning toward removing both. The create-page skill says "Open the page at
|
|
350
|
+
the width it is built for" but gives it no browser or screenshot, so the
|
|
351
|
+
model mostly reads the source and imagines the layout. Options discussed:
|
|
352
|
+
measure line length, bottom alignment, focus order, and heading order in
|
|
353
|
+
the page tests; save a screenshot per viewport from check-page --tests for
|
|
354
|
+
the visual items; keep only the judgment items in the skill. Revisit after
|
|
355
|
+
the intro paragraph is settled.
|
|
356
|
+
-->
|
|
357
|
+
<footer>Source: .claude/skills, bin/, src/testing, and scripts/ at v0.79.0.</footer>
|
|
358
|
+
<div class="contents" class:contents-collapsed={!contentsOpen} use:portal>
|
|
359
|
+
<Panel>
|
|
360
|
+
<div class="contents-body">
|
|
361
|
+
<CollapsibleSection
|
|
362
|
+
label="Contents"
|
|
363
|
+
variant="chromeless"
|
|
364
|
+
prose={false}
|
|
365
|
+
open={contentsOpen}
|
|
366
|
+
ontoggle={() => contentsOpen = !contentsOpen}
|
|
367
|
+
>
|
|
368
|
+
<nav aria-label="On this page">
|
|
369
|
+
<ol>
|
|
370
|
+
{#each chapters as chapter (chapter.id)}
|
|
371
|
+
<li><a href="#{chapter.id}" onclick={(event) => jump(event, chapter.id)}>{chapter.title}</a></li>
|
|
372
|
+
{/each}
|
|
373
|
+
</ol>
|
|
374
|
+
</nav>
|
|
375
|
+
</CollapsibleSection>
|
|
376
|
+
</div>
|
|
377
|
+
</Panel>
|
|
378
|
+
</div>
|
|
379
|
+
</div>
|
|
380
|
+
|
|
381
|
+
<style>
|
|
382
|
+
.markers {
|
|
383
|
+
position: absolute;
|
|
384
|
+
width: var(--space-0);
|
|
385
|
+
height: var(--space-0);
|
|
386
|
+
overflow: hidden;
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
.loops {
|
|
390
|
+
display: grid;
|
|
391
|
+
grid-template-columns: repeat(var(--columns-count), minmax(var(--space-0), 1fr));
|
|
392
|
+
column-gap: var(--columns-gutter);
|
|
393
|
+
max-width: var(--columns-max-width);
|
|
394
|
+
margin-inline: auto;
|
|
395
|
+
padding: var(--space-48) var(--space-32) var(--space-64);
|
|
396
|
+
color: var(--text-primary);
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
.masthead,
|
|
400
|
+
.chapter {
|
|
401
|
+
grid-column: 1 / -1;
|
|
402
|
+
display: grid;
|
|
403
|
+
grid-template-columns: subgrid;
|
|
404
|
+
align-items: start;
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
.masthead {
|
|
408
|
+
padding-bottom: var(--space-48);
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
.chapter {
|
|
412
|
+
padding-block: var(--space-40);
|
|
413
|
+
scroll-margin-top: var(--space-32);
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
/* Prose follows the demo inset. Paired topics and diagrams share the
|
|
417
|
+
wider ten-column span; standalone paragraphs match the left column of
|
|
418
|
+
that span. */
|
|
419
|
+
.chapter-body {
|
|
420
|
+
display: contents;
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
.chapter-body > * {
|
|
424
|
+
grid-column: 2 / 7;
|
|
425
|
+
min-width: var(--space-0);
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
.chapter-body > h2 {
|
|
429
|
+
grid-column: 2 / -2;
|
|
430
|
+
padding-top: var(--space-24);
|
|
431
|
+
border-top: var(--border-width-1) solid var(--border-neutral-subtle);
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
.chapter-body > h1,
|
|
435
|
+
.chapter-body > .text-columns,
|
|
436
|
+
.chapter-body > .steps,
|
|
437
|
+
.chapter-body > figure {
|
|
438
|
+
grid-column: 2 / -2;
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
.chapter-body > .reference-groups {
|
|
442
|
+
grid-column: 2 / 11;
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
.text-columns {
|
|
446
|
+
display: grid;
|
|
447
|
+
grid-template-columns: repeat(2, minmax(var(--space-0), 1fr));
|
|
448
|
+
column-gap: var(--columns-gutter);
|
|
449
|
+
row-gap: var(--space-32);
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
.text-columns > * {
|
|
453
|
+
min-width: var(--space-0);
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
.text-columns p:last-child {
|
|
457
|
+
margin-bottom: var(--space-0);
|
|
458
|
+
}
|
|
459
|
+
|
|
460
|
+
h1 {
|
|
461
|
+
font-family: var(--heading-xl-font-family);
|
|
462
|
+
font-size: var(--heading-xl-font-size);
|
|
463
|
+
font-weight: var(--heading-xl-font-weight);
|
|
464
|
+
line-height: var(--heading-xl-line-height);
|
|
465
|
+
letter-spacing: var(--heading-xl-letter-spacing);
|
|
466
|
+
margin: var(--space-0) var(--space-0) var(--space-40);
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
h2 {
|
|
470
|
+
font-family: var(--heading-lg-font-family);
|
|
471
|
+
font-size: var(--heading-lg-font-size);
|
|
472
|
+
font-weight: var(--heading-lg-font-weight);
|
|
473
|
+
line-height: var(--heading-lg-line-height);
|
|
474
|
+
letter-spacing: var(--heading-lg-letter-spacing);
|
|
475
|
+
margin: var(--space-0) var(--space-0) var(--space-24);
|
|
476
|
+
}
|
|
477
|
+
|
|
478
|
+
p,
|
|
479
|
+
li,
|
|
480
|
+
figcaption {
|
|
481
|
+
font-family: var(--editorial-md-font-family);
|
|
482
|
+
font-size: var(--editorial-md-font-size);
|
|
483
|
+
font-weight: var(--editorial-md-font-weight);
|
|
484
|
+
line-height: var(--editorial-md-line-height);
|
|
485
|
+
letter-spacing: var(--editorial-md-letter-spacing);
|
|
486
|
+
}
|
|
487
|
+
|
|
488
|
+
.back-link,
|
|
489
|
+
.contents a {
|
|
490
|
+
font-family: var(--body-md-font-family);
|
|
491
|
+
font-size: var(--body-md-font-size);
|
|
492
|
+
font-weight: var(--body-md-font-weight);
|
|
493
|
+
line-height: var(--body-md-line-height);
|
|
494
|
+
letter-spacing: var(--body-md-letter-spacing);
|
|
495
|
+
}
|
|
496
|
+
|
|
497
|
+
p {
|
|
498
|
+
margin: var(--space-0) var(--space-0) var(--space-20);
|
|
499
|
+
color: var(--text-secondary);
|
|
500
|
+
}
|
|
501
|
+
|
|
502
|
+
strong {
|
|
503
|
+
color: var(--text-primary);
|
|
504
|
+
font-weight: var(--font-weight-semibold);
|
|
505
|
+
}
|
|
506
|
+
|
|
507
|
+
|
|
508
|
+
code {
|
|
509
|
+
font-family: var(--code-font-family);
|
|
510
|
+
font-size: var(--code-font-size);
|
|
511
|
+
font-weight: var(--code-font-weight);
|
|
512
|
+
line-height: var(--code-line-height);
|
|
513
|
+
letter-spacing: var(--code-letter-spacing);
|
|
514
|
+
background: var(--tint-low);
|
|
515
|
+
padding-inline: var(--space-4);
|
|
516
|
+
border-radius: var(--radius-sm);
|
|
517
|
+
overflow-wrap: anywhere;
|
|
518
|
+
}
|
|
519
|
+
|
|
520
|
+
.name {
|
|
521
|
+
color: var(--text-primary);
|
|
522
|
+
overflow-wrap: anywhere;
|
|
523
|
+
}
|
|
524
|
+
|
|
525
|
+
.back-link {
|
|
526
|
+
justify-self: start;
|
|
527
|
+
scroll-margin-top: var(--space-64);
|
|
528
|
+
display: inline-flex;
|
|
529
|
+
align-items: center;
|
|
530
|
+
gap: var(--space-8);
|
|
531
|
+
padding-block: var(--space-8);
|
|
532
|
+
margin-bottom: var(--space-48);
|
|
533
|
+
color: var(--text-secondary);
|
|
534
|
+
text-decoration: none;
|
|
535
|
+
}
|
|
536
|
+
|
|
537
|
+
.introduction p {
|
|
538
|
+
font-family: var(--editorial-lg-font-family);
|
|
539
|
+
font-size: var(--editorial-lg-font-size);
|
|
540
|
+
font-weight: var(--editorial-lg-font-weight);
|
|
541
|
+
line-height: var(--editorial-lg-line-height);
|
|
542
|
+
letter-spacing: var(--editorial-lg-letter-spacing);
|
|
543
|
+
}
|
|
544
|
+
|
|
545
|
+
.introduction p:last-child {
|
|
546
|
+
margin-bottom: var(--space-0);
|
|
547
|
+
}
|
|
548
|
+
|
|
549
|
+
/* Panel owns the frame and surface; the page positions the overlay. */
|
|
550
|
+
.contents {
|
|
551
|
+
position: fixed;
|
|
552
|
+
top: var(--space-96);
|
|
553
|
+
right: var(--space-24);
|
|
554
|
+
z-index: 10;
|
|
555
|
+
width: calc(var(--space-96) * 3 + var(--space-24));
|
|
556
|
+
max-width: calc(100vw - var(--space-32));
|
|
557
|
+
max-height: calc(100dvh - var(--space-96) - var(--space-24));
|
|
558
|
+
overflow-y: auto;
|
|
559
|
+
border-radius: var(--panel-frame-radius);
|
|
560
|
+
backdrop-filter: blur(var(--blur-lg));
|
|
561
|
+
}
|
|
562
|
+
|
|
563
|
+
.contents.contents-collapsed {
|
|
564
|
+
width: auto;
|
|
565
|
+
}
|
|
566
|
+
|
|
567
|
+
.contents-body {
|
|
568
|
+
width: 100%;
|
|
569
|
+
min-width: var(--space-0);
|
|
570
|
+
}
|
|
571
|
+
|
|
572
|
+
.contents ol {
|
|
573
|
+
list-style: none;
|
|
574
|
+
margin: var(--space-0);
|
|
575
|
+
padding: var(--space-0);
|
|
576
|
+
}
|
|
577
|
+
|
|
578
|
+
.contents li {
|
|
579
|
+
margin: var(--space-0);
|
|
580
|
+
}
|
|
581
|
+
|
|
582
|
+
.contents a {
|
|
583
|
+
display: block;
|
|
584
|
+
padding-block: var(--space-12);
|
|
585
|
+
color: var(--text-primary);
|
|
586
|
+
text-decoration: none;
|
|
587
|
+
}
|
|
588
|
+
|
|
589
|
+
.contents a:hover,
|
|
590
|
+
.back-link:hover {
|
|
591
|
+
color: var(--text-accent);
|
|
592
|
+
text-decoration: underline;
|
|
593
|
+
text-underline-offset: var(--space-4);
|
|
594
|
+
}
|
|
595
|
+
|
|
596
|
+
a:focus-visible,
|
|
597
|
+
.figure-scroll:focus-visible {
|
|
598
|
+
outline: var(--border-width-2) solid var(--border-accent);
|
|
599
|
+
outline-offset: var(--space-4);
|
|
600
|
+
}
|
|
601
|
+
|
|
602
|
+
.skill-stack {
|
|
603
|
+
list-style: none;
|
|
604
|
+
margin: var(--space-0);
|
|
605
|
+
padding: var(--space-0);
|
|
606
|
+
display: grid;
|
|
607
|
+
gap: var(--space-16);
|
|
608
|
+
}
|
|
609
|
+
|
|
610
|
+
.skill-stack li {
|
|
611
|
+
display: grid;
|
|
612
|
+
min-width: var(--space-0);
|
|
613
|
+
margin: var(--space-0);
|
|
614
|
+
}
|
|
615
|
+
|
|
616
|
+
.skill-stack h3 {
|
|
617
|
+
font-family: var(--heading-sm-font-family);
|
|
618
|
+
font-size: var(--heading-sm-font-size);
|
|
619
|
+
font-weight: var(--heading-sm-font-weight);
|
|
620
|
+
line-height: var(--heading-sm-line-height);
|
|
621
|
+
letter-spacing: var(--heading-sm-letter-spacing);
|
|
622
|
+
margin: var(--space-0) var(--space-0) var(--space-8);
|
|
623
|
+
color: var(--text-primary);
|
|
624
|
+
}
|
|
625
|
+
|
|
626
|
+
.steps {
|
|
627
|
+
display: none;
|
|
628
|
+
list-style: none;
|
|
629
|
+
counter-reset: step;
|
|
630
|
+
margin: var(--space-24) var(--space-0) var(--space-0);
|
|
631
|
+
padding: var(--space-0);
|
|
632
|
+
}
|
|
633
|
+
|
|
634
|
+
/* Positioned rather than a grid: the step's strong, text, and code runs
|
|
635
|
+
would each become a grid cell. */
|
|
636
|
+
.steps li {
|
|
637
|
+
counter-increment: step;
|
|
638
|
+
position: relative;
|
|
639
|
+
margin: var(--space-0);
|
|
640
|
+
padding: var(--space-12) var(--space-0) var(--space-12) var(--space-40);
|
|
641
|
+
border-top: var(--border-width-1) solid var(--border-neutral-subtle);
|
|
642
|
+
}
|
|
643
|
+
|
|
644
|
+
.steps li::before {
|
|
645
|
+
content: counter(step) ".";
|
|
646
|
+
position: absolute;
|
|
647
|
+
left: var(--space-0);
|
|
648
|
+
color: var(--text-secondary);
|
|
649
|
+
}
|
|
650
|
+
|
|
651
|
+
.reference-groups {
|
|
652
|
+
display: grid;
|
|
653
|
+
grid-template-columns: minmax(var(--space-0), 1fr);
|
|
654
|
+
gap: var(--space-16);
|
|
655
|
+
}
|
|
656
|
+
|
|
657
|
+
.rule-group {
|
|
658
|
+
width: 100%;
|
|
659
|
+
min-width: var(--space-0);
|
|
660
|
+
}
|
|
661
|
+
|
|
662
|
+
|
|
663
|
+
figure {
|
|
664
|
+
display: grid;
|
|
665
|
+
grid-template-columns: subgrid;
|
|
666
|
+
margin: var(--space-24) var(--space-0) var(--space-32);
|
|
667
|
+
}
|
|
668
|
+
|
|
669
|
+
.figure-stage {
|
|
670
|
+
grid-column: 1 / -1;
|
|
671
|
+
min-width: var(--space-0);
|
|
672
|
+
}
|
|
673
|
+
|
|
674
|
+
.figure-scroll {
|
|
675
|
+
overflow-x: auto;
|
|
676
|
+
}
|
|
677
|
+
|
|
678
|
+
/* Inside the figure's subgrid, so 1 / 7 lines up with the text column. */
|
|
679
|
+
figcaption {
|
|
680
|
+
grid-column: 1 / 7;
|
|
681
|
+
margin-bottom: var(--space-16);
|
|
682
|
+
color: var(--text-secondary);
|
|
683
|
+
}
|
|
684
|
+
|
|
685
|
+
figcaption b {
|
|
686
|
+
color: var(--text-primary);
|
|
687
|
+
font-weight: var(--font-weight-semibold);
|
|
688
|
+
}
|
|
689
|
+
|
|
690
|
+
/* The diagram scales to the document width. Below the floor its labels would
|
|
691
|
+
shrink past legibility, so a narrow frame scrolls instead. */
|
|
692
|
+
.dg {
|
|
693
|
+
display: block;
|
|
694
|
+
width: 100%;
|
|
695
|
+
height: auto;
|
|
696
|
+
min-width: calc(var(--space-96) * 7);
|
|
697
|
+
color: var(--text-primary);
|
|
698
|
+
}
|
|
699
|
+
|
|
700
|
+
.dg :global(.lane-checker) {
|
|
701
|
+
fill: none;
|
|
702
|
+
stroke: var(--border-neutral-subtle);
|
|
703
|
+
stroke-width: var(--border-width-1);
|
|
704
|
+
}
|
|
705
|
+
|
|
706
|
+
.dg :global(.lane-skill) {
|
|
707
|
+
fill: var(--tint-low);
|
|
708
|
+
}
|
|
709
|
+
|
|
710
|
+
/* No faint scrim token exists, so thin the lowest one to a light wash. */
|
|
711
|
+
.dg :global(.lane-shade) {
|
|
712
|
+
fill: color-mix(in srgb, var(--scrim-low) 40%, transparent);
|
|
713
|
+
}
|
|
714
|
+
|
|
715
|
+
.dg :global(.lane-title) {
|
|
716
|
+
font-family: var(--heading-md-font-family);
|
|
717
|
+
font-weight: var(--heading-md-font-weight);
|
|
718
|
+
font-size: var(--heading-md-font-size);
|
|
719
|
+
line-height: var(--heading-md-line-height);
|
|
720
|
+
letter-spacing: var(--heading-md-letter-spacing);
|
|
721
|
+
fill: var(--text-primary);
|
|
722
|
+
}
|
|
723
|
+
|
|
724
|
+
.dg :global(.tag) {
|
|
725
|
+
font-family: var(--body-sm-font-family);
|
|
726
|
+
font-size: var(--body-sm-font-size);
|
|
727
|
+
font-weight: var(--body-sm-font-weight);
|
|
728
|
+
line-height: var(--body-sm-line-height);
|
|
729
|
+
letter-spacing: var(--body-sm-letter-spacing);
|
|
730
|
+
fill: var(--text-tertiary);
|
|
731
|
+
}
|
|
732
|
+
|
|
733
|
+
.dg :global(.box) {
|
|
734
|
+
fill: var(--tint-low);
|
|
735
|
+
stroke: var(--border-neutral-medium);
|
|
736
|
+
stroke-width: var(--border-width-1);
|
|
737
|
+
}
|
|
738
|
+
|
|
739
|
+
.dg :global(.box-lead) {
|
|
740
|
+
fill: var(--tint-low);
|
|
741
|
+
stroke: var(--border-accent-medium);
|
|
742
|
+
stroke-width: var(--border-width-2);
|
|
743
|
+
}
|
|
744
|
+
|
|
745
|
+
.dg :global(.t) {
|
|
746
|
+
font-family: var(--heading-sm-font-family);
|
|
747
|
+
font-weight: var(--heading-sm-font-weight);
|
|
748
|
+
font-size: var(--heading-sm-font-size);
|
|
749
|
+
line-height: var(--heading-sm-line-height);
|
|
750
|
+
letter-spacing: var(--heading-sm-letter-spacing);
|
|
751
|
+
fill: var(--text-primary);
|
|
752
|
+
}
|
|
753
|
+
|
|
754
|
+
.dg :global(.s),
|
|
755
|
+
.dg :global(.lbl) {
|
|
756
|
+
font-family: var(--body-md-font-family);
|
|
757
|
+
font-size: var(--body-md-font-size);
|
|
758
|
+
font-weight: var(--body-md-font-weight);
|
|
759
|
+
line-height: var(--body-md-line-height);
|
|
760
|
+
letter-spacing: var(--body-md-letter-spacing);
|
|
761
|
+
fill: var(--text-secondary);
|
|
762
|
+
}
|
|
763
|
+
|
|
764
|
+
.dg :global(.rule) {
|
|
765
|
+
font-family: var(--code-font-family);
|
|
766
|
+
font-size: var(--code-font-size);
|
|
767
|
+
font-weight: var(--code-font-weight);
|
|
768
|
+
line-height: var(--code-line-height);
|
|
769
|
+
letter-spacing: var(--code-letter-spacing);
|
|
770
|
+
fill: var(--text-accent);
|
|
771
|
+
}
|
|
772
|
+
|
|
773
|
+
.dg :global(.flow),
|
|
774
|
+
.dg :global(.back) {
|
|
775
|
+
fill: none;
|
|
776
|
+
stroke-width: var(--border-width-3);
|
|
777
|
+
stroke-linecap: round;
|
|
778
|
+
stroke-linejoin: round;
|
|
779
|
+
}
|
|
780
|
+
|
|
781
|
+
.dg :global(.flow) {
|
|
782
|
+
stroke: var(--text-secondary);
|
|
783
|
+
marker-end: url(#loops-arw);
|
|
784
|
+
}
|
|
785
|
+
|
|
786
|
+
.dg :global(.back) {
|
|
787
|
+
stroke: var(--text-accent);
|
|
788
|
+
marker-end: url(#loops-arw-back);
|
|
789
|
+
}
|
|
790
|
+
|
|
791
|
+
.markers :global(.head) {
|
|
792
|
+
fill: var(--text-secondary);
|
|
793
|
+
}
|
|
794
|
+
|
|
795
|
+
.markers :global(.head-back) {
|
|
796
|
+
fill: var(--text-accent);
|
|
797
|
+
}
|
|
798
|
+
|
|
799
|
+
footer {
|
|
800
|
+
grid-column: 2 / -2;
|
|
801
|
+
padding-top: var(--space-24);
|
|
802
|
+
border-top: var(--border-width-1) solid var(--border-neutral-subtle);
|
|
803
|
+
font-family: var(--code-font-family);
|
|
804
|
+
font-size: var(--code-font-size);
|
|
805
|
+
font-weight: var(--code-font-weight);
|
|
806
|
+
line-height: var(--code-line-height);
|
|
807
|
+
letter-spacing: var(--code-letter-spacing);
|
|
808
|
+
color: var(--text-secondary);
|
|
809
|
+
}
|
|
810
|
+
|
|
811
|
+
@media (max-width: 1279px) {
|
|
812
|
+
.chapter-body > * {
|
|
813
|
+
grid-column: 2 / -2;
|
|
814
|
+
}
|
|
815
|
+
|
|
816
|
+
figcaption {
|
|
817
|
+
grid-column: 1 / -1;
|
|
818
|
+
}
|
|
819
|
+
}
|
|
820
|
+
|
|
821
|
+
@media (max-width: 1023px) {
|
|
822
|
+
.chapter-body > *,
|
|
823
|
+
.chapter-body > h2,
|
|
824
|
+
.chapter-body > .text-columns,
|
|
825
|
+
.chapter-body > .steps,
|
|
826
|
+
.chapter-body > figure,
|
|
827
|
+
footer,
|
|
828
|
+
.chapter-body > .reference-groups,
|
|
829
|
+
figcaption {
|
|
830
|
+
grid-column: 1 / -1;
|
|
831
|
+
}
|
|
832
|
+
|
|
833
|
+
.text-columns {
|
|
834
|
+
grid-template-columns: minmax(var(--space-0), 1fr);
|
|
835
|
+
}
|
|
836
|
+
|
|
837
|
+
.contents {
|
|
838
|
+
top: var(--space-64);
|
|
839
|
+
right: var(--space-16);
|
|
840
|
+
}
|
|
841
|
+
}
|
|
842
|
+
|
|
843
|
+
/* Media queries cannot read the grid tokens. */
|
|
844
|
+
@media (width < 768px) {
|
|
845
|
+
.workflow-diagram {
|
|
846
|
+
display: none;
|
|
847
|
+
}
|
|
848
|
+
|
|
849
|
+
.steps {
|
|
850
|
+
display: block;
|
|
851
|
+
}
|
|
852
|
+
|
|
853
|
+
.loops {
|
|
854
|
+
grid-template-columns: minmax(var(--space-0), 1fr);
|
|
855
|
+
/* Leave room for the fixed editor toolbar above the back link. */
|
|
856
|
+
padding: var(--space-64) var(--space-20) var(--space-48);
|
|
857
|
+
}
|
|
858
|
+
|
|
859
|
+
h1 {
|
|
860
|
+
margin-bottom: var(--space-32);
|
|
861
|
+
}
|
|
862
|
+
|
|
863
|
+
.back-link {
|
|
864
|
+
margin-bottom: var(--space-24);
|
|
865
|
+
}
|
|
866
|
+
|
|
867
|
+
.masthead {
|
|
868
|
+
padding-bottom: var(--space-32);
|
|
869
|
+
}
|
|
870
|
+
|
|
871
|
+
.chapter {
|
|
872
|
+
padding-block: var(--space-32);
|
|
873
|
+
}
|
|
874
|
+
|
|
875
|
+
}
|
|
876
|
+
</style>
|