@ksp-gonogo/ui-kit 0.1.0 → 0.2.0-rc.10
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 -596
- package/README.md +151 -0
- package/dist/chunk-G3PMV62Z.js +36 -0
- package/dist/chunk-G3PMV62Z.js.map +1 -0
- package/dist/chunk-KPESGDJJ.js +8611 -0
- package/dist/chunk-KPESGDJJ.js.map +1 -0
- package/dist/chunk-SHAX2WJJ.js +18 -0
- package/dist/chunk-SHAX2WJJ.js.map +1 -0
- package/dist/dist-JSEJWZKX.js +546 -0
- package/dist/dist-JSEJWZKX.js.map +1 -0
- package/dist/gridUnits.d.ts +34 -0
- package/dist/gridUnits.js +14 -0
- package/dist/gridUnits.js.map +1 -0
- package/dist/guards.d.ts +110 -0
- package/dist/guards.js +171 -0
- package/dist/guards.js.map +1 -0
- package/dist/index.d.ts +9318 -25
- package/dist/index.js +8098 -28
- package/dist/index.js.map +1 -1
- package/dist/magic-string.es-J7BYFTTJ.js +1309 -0
- package/dist/magic-string.es-J7BYFTTJ.js.map +1 -0
- package/dist/testing.d.ts +470 -0
- package/dist/testing.js +16747 -0
- package/dist/testing.js.map +1 -0
- package/dist/tokens.css +1063 -29
- package/dist/units-Cl-8ZdJc.d.ts +270 -0
- package/package.json +57 -15
- package/dist/ActionButton.d.ts +0 -18
- package/dist/ActionButton.d.ts.map +0 -1
- package/dist/ActionButton.js +0 -56
- package/dist/ActionButton.js.map +0 -1
- package/dist/Badge.d.ts +0 -15
- package/dist/Badge.d.ts.map +0 -1
- package/dist/Badge.js +0 -60
- package/dist/Badge.js.map +0 -1
- package/dist/Box.d.ts +0 -19
- package/dist/Box.d.ts.map +0 -1
- package/dist/Box.js +0 -27
- package/dist/Box.js.map +0 -1
- package/dist/Card.d.ts +0 -11
- package/dist/Card.d.ts.map +0 -1
- package/dist/Card.js +0 -13
- package/dist/Card.js.map +0 -1
- package/dist/Cluster.d.ts +0 -18
- package/dist/Cluster.d.ts.map +0 -1
- package/dist/Cluster.js +0 -24
- package/dist/Cluster.js.map +0 -1
- package/dist/EmptyState.d.ts +0 -16
- package/dist/EmptyState.d.ts.map +0 -1
- package/dist/EmptyState.js +0 -37
- package/dist/EmptyState.js.map +0 -1
- package/dist/GonogoTokens.d.ts +0 -16
- package/dist/GonogoTokens.d.ts.map +0 -1
- package/dist/GonogoTokens.js +0 -108
- package/dist/GonogoTokens.js.map +0 -1
- package/dist/Grid.d.ts +0 -25
- package/dist/Grid.d.ts.map +0 -1
- package/dist/Grid.js +0 -23
- package/dist/Grid.js.map +0 -1
- package/dist/Inline.d.ts +0 -20
- package/dist/Inline.d.ts.map +0 -1
- package/dist/Inline.js +0 -17
- package/dist/Inline.js.map +0 -1
- package/dist/Panel.d.ts +0 -14
- package/dist/Panel.d.ts.map +0 -1
- package/dist/Panel.js +0 -145
- package/dist/Panel.js.map +0 -1
- package/dist/ProgressBar.d.ts +0 -15
- package/dist/ProgressBar.d.ts.map +0 -1
- package/dist/ProgressBar.js +0 -31
- package/dist/ProgressBar.js.map +0 -1
- package/dist/Readout.d.ts +0 -35
- package/dist/Readout.d.ts.map +0 -1
- package/dist/Readout.js +0 -114
- package/dist/Readout.js.map +0 -1
- package/dist/Row.d.ts +0 -22
- package/dist/Row.d.ts.map +0 -1
- package/dist/Row.js +0 -32
- package/dist/Row.js.map +0 -1
- package/dist/Section.d.ts +0 -15
- package/dist/Section.d.ts.map +0 -1
- package/dist/Section.js +0 -21
- package/dist/Section.js.map +0 -1
- package/dist/Spinner.d.ts +0 -18
- package/dist/Spinner.d.ts.map +0 -1
- package/dist/Spinner.js +0 -22
- package/dist/Spinner.js.map +0 -1
- package/dist/Stack.d.ts +0 -15
- package/dist/Stack.d.ts.map +0 -1
- package/dist/Stack.js +0 -17
- package/dist/Stack.js.map +0 -1
- package/dist/StatusIndicator.d.ts +0 -27
- package/dist/StatusIndicator.d.ts.map +0 -1
- package/dist/StatusIndicator.js +0 -78
- package/dist/StatusIndicator.js.map +0 -1
- package/dist/Truncate.d.ts +0 -7
- package/dist/Truncate.d.ts.map +0 -1
- package/dist/Truncate.js +0 -14
- package/dist/Truncate.js.map +0 -1
- package/dist/Value.d.ts +0 -24
- package/dist/Value.d.ts.map +0 -1
- package/dist/Value.js +0 -42
- package/dist/Value.js.map +0 -1
- package/dist/WidgetHeader.d.ts +0 -16
- package/dist/WidgetHeader.d.ts.map +0 -1
- package/dist/WidgetHeader.js +0 -40
- package/dist/WidgetHeader.js.map +0 -1
- package/dist/defaultDarkTheme.d.ts +0 -16
- package/dist/defaultDarkTheme.d.ts.map +0 -1
- package/dist/defaultDarkTheme.js +0 -96
- package/dist/defaultDarkTheme.js.map +0 -1
- package/dist/format.d.ts +0 -11
- package/dist/format.d.ts.map +0 -1
- package/dist/format.js +0 -12
- package/dist/format.js.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/science/ScienceExperimentRow.d.ts +0 -43
- package/dist/science/ScienceExperimentRow.d.ts.map +0 -1
- package/dist/science/ScienceExperimentRow.js +0 -61
- package/dist/science/ScienceExperimentRow.js.map +0 -1
- package/dist/test/axe.d.ts +0 -3
- package/dist/test/axe.d.ts.map +0 -1
- package/dist/test/axe.js +0 -5
- package/dist/test/axe.js.map +0 -1
- package/dist/test/setup.d.ts +0 -2
- package/dist/test/setup.d.ts.map +0 -1
- package/dist/test/setup.js +0 -12
- package/dist/test/setup.js.map +0 -1
- package/dist/theme.d.ts +0 -116
- package/dist/theme.d.ts.map +0 -1
- package/dist/theme.js +0 -15
- package/dist/theme.js.map +0 -1
package/dist/tokens.css
CHANGED
|
@@ -1,13 +1,231 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Every box measures its padding and border INSIDE the width it was given.
|
|
3
|
+
*
|
|
4
|
+
* Without this, a rule pairing `width: 100%` with horizontal padding resolves
|
|
5
|
+
* to 100% plus that padding and hangs over its parent's edge by exactly the
|
|
6
|
+
* inset. The panel toolbar measured 542px inside a 510px row, at every tile
|
|
7
|
+
* width and in every widget that drew one, and a fill empty state was 32px
|
|
8
|
+
* wider than the panel it was centred in, so its sentence was sliced by the
|
|
9
|
+
* border in four widgets at once. Neither is visible from the source: the rule
|
|
10
|
+
* that overflows reads as if it asks for exactly the space it has.
|
|
11
|
+
*
|
|
12
|
+
* It lives here because this file is what a page loads to be a gonogo page:
|
|
13
|
+
* the app imports it, and every render probe injects it verbatim. A page that
|
|
14
|
+
* draws kit primitives without it draws them at a size their authors never
|
|
15
|
+
* measured.
|
|
16
|
+
*/
|
|
17
|
+
*,
|
|
18
|
+
*::before,
|
|
19
|
+
*::after {
|
|
20
|
+
box-sizing: border-box;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/*
|
|
24
|
+
* Native form controls take their font, colour and background from the UA
|
|
25
|
+
* stylesheet rather than from the page, so a bare `<button>` draws in the
|
|
26
|
+
* browser's sans-serif with black words on a light grey box, and a bare input
|
|
27
|
+
* is a white box, on a dark panel. Every control takes the theme's type, text
|
|
28
|
+
* colour and raised surface instead, a pair that clears the text floor on
|
|
29
|
+
* its own, so a control no kit rule has styled is still readable. Kit
|
|
30
|
+
* controls set their own colours over it. The root carries the theme's text
|
|
31
|
+
* colour for the same reason: an inherited colour always ends at the theme
|
|
32
|
+
* and never at a browser default.
|
|
33
|
+
*
|
|
34
|
+
* It lives here for the same reason as the reset above: this file is what
|
|
35
|
+
* every page, render probe and Uplink docs page loads.
|
|
36
|
+
*/
|
|
37
|
+
html {
|
|
38
|
+
color: var(--color-text-primary);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
button,
|
|
42
|
+
input,
|
|
43
|
+
select,
|
|
44
|
+
textarea {
|
|
45
|
+
font: inherit;
|
|
46
|
+
color: var(--color-text-primary);
|
|
47
|
+
background-color: var(--color-surface-raised);
|
|
48
|
+
}
|
|
49
|
+
|
|
1
50
|
:root {
|
|
51
|
+
/*
|
|
52
|
+
* NAMING ACROSS FAMILIES. A convention, not a rule: a new token need not
|
|
53
|
+
* declare a category, and a name in one family needs no counterpart in
|
|
54
|
+
* another. The categories describe what the families already are.
|
|
55
|
+
*
|
|
56
|
+
* container externals --z-*, --color-* (boundary and ground), --radius-*
|
|
57
|
+
* container internals --color-* (content), --line-height-*, --gap-*,
|
|
58
|
+
* --inset-*
|
|
59
|
+
* animation --duration-*, --ease-*
|
|
60
|
+
*
|
|
61
|
+
* `--color-*` sits in both of the first two: a colour is either what a
|
|
62
|
+
* container is against what lies behind it (border, ground) or the
|
|
63
|
+
* treatment of what it holds (text, marks). It is one family because the
|
|
64
|
+
* names are not separable by prefix, not because the jobs are the same.
|
|
65
|
+
*
|
|
66
|
+
* A modifier such as `status` varies a token of an existing category and is
|
|
67
|
+
* never a category of its own. The set of three is closed: a fourth is a
|
|
68
|
+
* structural claim about the whole system and is made deliberately, not by
|
|
69
|
+
* adding a token.
|
|
70
|
+
*
|
|
71
|
+
* Reusing a term across families is the part with teeth. A shared word
|
|
72
|
+
* promises a pairing: `--radius-floating` names the corner of the boxes that
|
|
73
|
+
* sit on the `--z-*` rungs above the app (modal, fab), so a reader who reaches
|
|
74
|
+
* for one should reach for the other, and the two must actually belong
|
|
75
|
+
* together. Where that does not hold, use a different word
|
|
76
|
+
* rather than a familiar one borrowed by coincidence, because a coincidental
|
|
77
|
+
* match teaches a pairing nobody checked.
|
|
78
|
+
*
|
|
79
|
+
* This sits beside the bar for whether a name is earned at all (it must
|
|
80
|
+
* resolve differently by context or express a shape the rung ladder cannot),
|
|
81
|
+
* and governs only how names relate across families.
|
|
82
|
+
*/
|
|
2
83
|
--font-family-mono:
|
|
3
84
|
"JetBrains Mono", ui-monospace, "IBM Plex Mono", Menlo, Consolas, monospace;
|
|
85
|
+
/*
|
|
86
|
+
* Type scale. `2xs` is the one step the census added: 103 of the 394
|
|
87
|
+
* hardcoded px font-sizes sit BELOW the old 11px floor (69 at 10px, 34
|
|
88
|
+
* at 9px), so the scale had no rung for the micro-labels this dense
|
|
89
|
+
* mission-control UI is built out of. Everything else maps onto the
|
|
90
|
+
* four rungs that were already here.
|
|
91
|
+
*
|
|
92
|
+
* The scale deliberately stops at `lg`. Every hardcoded size above
|
|
93
|
+
* 16px in the codebase (18/19/20/22/23/24/28) is either a fluid
|
|
94
|
+
* `clamp()`, a JS-computed fit, or a value comment-locked to a
|
|
95
|
+
* specific box width. A fixed display rung would freeze behaviour
|
|
96
|
+
* those widgets depend on, so they stay literal.
|
|
97
|
+
*/
|
|
98
|
+
--font-size-2xs: 10px;
|
|
4
99
|
--font-size-xs: 11px;
|
|
5
100
|
--font-size-sm: 12px;
|
|
6
101
|
--font-size-base: 14px;
|
|
7
102
|
--font-size-lg: 16px;
|
|
8
103
|
|
|
9
104
|
/*
|
|
10
|
-
*
|
|
105
|
+
* SEMANTIC TYPE, over the rungs above. One name per JOB, where a job
|
|
106
|
+
* is what the text IS rather than how big it is.
|
|
107
|
+
*
|
|
108
|
+
* `caption` The annotation that names a value it does not contain.
|
|
109
|
+
* Small caps and tracked, set apart from the reading it
|
|
110
|
+
* points at. 165 sites, and the job has a ceiling the rung
|
|
111
|
+
* ladder never described: it reaches 2xs, xs and sm and
|
|
112
|
+
* never base or lg.
|
|
113
|
+
* `compact` The working text of a surface: rows, cells, control
|
|
114
|
+
* labels, and the commentary beside them. 297 sites, 53% of
|
|
115
|
+
* the whole population, so this is the app's real default
|
|
116
|
+
* and the document's own 14px never was.
|
|
117
|
+
* `value` What the caption points at. The name of a row or a card,
|
|
118
|
+
* the reading in a labelled line, the text a form control
|
|
119
|
+
* holds.
|
|
120
|
+
* `prose` Consecutive sentences, read start to finish.
|
|
121
|
+
* `figure` The number a widget exists to show.
|
|
122
|
+
*
|
|
123
|
+
* COMPACT AND PROSE ARE REGISTERS, NOT SIZES. The test is not length,
|
|
124
|
+
* it is whether a person reads the words in order or picks one out at
|
|
125
|
+
* a glance. The boundary is disjoint rather than a judgement at the
|
|
126
|
+
* margin: of the 297 compact sites, 2 set a max-width in em or ch and
|
|
127
|
+
* none sets `--line-height-prose`, so almost nothing outside `prose`
|
|
128
|
+
* holds a wrapped sentence at all.
|
|
129
|
+
*
|
|
130
|
+
* CAPTION AND VALUE ARE A PAIR, and colour says so independently of
|
|
131
|
+
* size: 85% of captions sit on a muted, faint or dim text colour and
|
|
132
|
+
* 69% of values on `--color-text-primary`. Reach for one and you are
|
|
133
|
+
* reaching for the other.
|
|
134
|
+
*
|
|
135
|
+
* THERE IS NO SIXTH NAME FOR SUPPORTING TEXT, and the reason is here
|
|
136
|
+
* because the question comes back. Split `compact` by what its
|
|
137
|
+
* declarations are called and the four strands (supporting text,
|
|
138
|
+
* control labels, small readings, the rest) come out at 11.22, 11.47,
|
|
139
|
+
* 10.71 and 11.24 mean px, which is one size. Supporting text IS a
|
|
140
|
+
* real job, and the design already marks it with COLOUR: 68% muted
|
|
141
|
+
* against 2% primary, where the rest of `compact` is 37% and 18%. A
|
|
142
|
+
* second size name would invent a distinction the design does not
|
|
143
|
+
* make and say a second time what `--color-text-muted` already says.
|
|
144
|
+
*
|
|
145
|
+
* NOT NAMED, and each absence is a decision:
|
|
146
|
+
* a glyph's box 14 sites size an icon glyph THROUGH `font-size`
|
|
147
|
+
* rather than sizing text: a dismiss cross, a
|
|
148
|
+
* caret, a chevron centred in a button. That is a
|
|
149
|
+
* box dimension wearing a type property, it belongs
|
|
150
|
+
* to an icon family, and a type name offered for it
|
|
151
|
+
* would be reached for as text.
|
|
152
|
+
* a display tier Every size above 16px is a fluid `clamp()`, a
|
|
153
|
+
* JS-computed fit or a value locked to a box width,
|
|
154
|
+
* as the scale's own note above records. `figure`
|
|
155
|
+
* is the top of the type scale, not the bottom of a
|
|
156
|
+
* display one.
|
|
157
|
+
*/
|
|
158
|
+
--font-size-caption: var(--font-size-2xs);
|
|
159
|
+
--font-size-compact: var(--font-size-xs);
|
|
160
|
+
--font-size-value: var(--font-size-sm);
|
|
161
|
+
--font-size-prose: var(--font-size-base);
|
|
162
|
+
--font-size-figure: var(--font-size-lg);
|
|
163
|
+
|
|
164
|
+
/*
|
|
165
|
+
* ICON SIZE. A separate family from the type scale on purpose: an icon's
|
|
166
|
+
* size is a BOX dimension, and a name offered on the type scale for it
|
|
167
|
+
* gets reached for as text.
|
|
168
|
+
*
|
|
169
|
+
* `control` The glyph inside a control the operator presses. 46 of the
|
|
170
|
+
* 63 icon sites, and the number is not arbitrary: both
|
|
171
|
+
* control tokens below already do their arithmetic against a
|
|
172
|
+
* 14px glyph, in writing. `--inset-control-compact` derives
|
|
173
|
+
* an 18px header from 2 inset + 2 border + a 14px glyph, and
|
|
174
|
+
* `--control-height` derives its 28 from 12 + 2 + 14. Sizing
|
|
175
|
+
* icons at anything else falsifies both.
|
|
176
|
+
* `standalone` The glyph that IS its control: no label, nothing beside it,
|
|
177
|
+
* on a target hit at a glance. Every `Fab`, and the
|
|
178
|
+
* processor picker.
|
|
179
|
+
*
|
|
180
|
+
* THESE STEP ON A COARSE POINTER and a raw `size={14}` cannot. The step
|
|
181
|
+
* is the reason the family is custom properties rather than constants: a
|
|
182
|
+
* prop is a JS number and a number cannot read a media query, so today
|
|
183
|
+
* the two halves of one population disagree on a touch screen. A `×`
|
|
184
|
+
* drawn with `font-size` grows and the `<CloseIcon>` beside it does not.
|
|
185
|
+
*
|
|
186
|
+
* REACHED THROUGH THE `size` PROP, not through a CSS rule, because a
|
|
187
|
+
* `var()` resolves inside an SVG presentation attribute. Measured in
|
|
188
|
+
* chromium, firefox and webkit, with the negative controls that make the
|
|
189
|
+
* measurement worth having: `width="banana"` is rejected in all three and
|
|
190
|
+
* `width="var(--absent, 33px)"` renders at 33, so the probe can tell a
|
|
191
|
+
* failure from a success. Anyone tempted to "fix" a `size="var(...)"`
|
|
192
|
+
* back to a number should reverse that reasoning, not the code.
|
|
193
|
+
*
|
|
194
|
+
* NOT NAMED:
|
|
195
|
+
* an overlay tier A dismiss on a surface that covers the screen is a
|
|
196
|
+
* real candidate and its own population disagrees:
|
|
197
|
+
* 16, 16, 14 and 18 across four instances of one job.
|
|
198
|
+
* Naming it would write one of the three down and call
|
|
199
|
+
* it a decision.
|
|
200
|
+
* a 12px tier The observed mode, and not a job. It appears on
|
|
201
|
+
* `--inset-control-compact` AND on the 28px control
|
|
202
|
+
* floor, and sits beside a 14 in the same row twice.
|
|
203
|
+
*/
|
|
204
|
+
--icon-size-control: 14px;
|
|
205
|
+
--icon-size-standalone: 20px;
|
|
206
|
+
|
|
207
|
+
/*
|
|
208
|
+
* Line height, unitless, named by ROLE rather than by number. The
|
|
209
|
+
* census showed the values split cleanly by job, not by size: all 25
|
|
210
|
+
* `line-height: 1` sites are single-line chrome and glyph buttons that
|
|
211
|
+
* collapse the glyph box, and all 16 `1.5` sites are prose blocks with
|
|
212
|
+
* no vertical padding. Four roles cover 55 of the 68 declarations
|
|
213
|
+
* exactly.
|
|
214
|
+
*
|
|
215
|
+
* `flush` glyph and single-line chrome. Collapses the line box so an
|
|
216
|
+
* icon or a one-character button centres in a fixed height.
|
|
217
|
+
* Never use on anything that can wrap.
|
|
218
|
+
* `tight` dense multi-line readouts, label-over-value stacks.
|
|
219
|
+
* `body` default for widget text.
|
|
220
|
+
* `prose` running paragraphs, help text, banners.
|
|
221
|
+
*/
|
|
222
|
+
--line-height-flush: 1;
|
|
223
|
+
--line-height-tight: 1.2;
|
|
224
|
+
--line-height-body: 1.4;
|
|
225
|
+
--line-height-prose: 1.5;
|
|
226
|
+
|
|
227
|
+
/*
|
|
228
|
+
* Colour tokens: names match `theme.colors.*` paths in
|
|
11
229
|
* `packages/ui-kit/src/defaultDarkTheme.ts`. The CSS-variable layer is
|
|
12
230
|
* the single source of truth; the JS theme object is a typed handle
|
|
13
231
|
* that reads from these vars (e.g. `var(--color-text-primary)`).
|
|
@@ -15,8 +233,8 @@
|
|
|
15
233
|
*/
|
|
16
234
|
--color-text-primary: #ccc;
|
|
17
235
|
--color-text-muted: #888;
|
|
18
|
-
--color-text-dim: #
|
|
19
|
-
--color-text-faint: #
|
|
236
|
+
--color-text-dim: #858585;
|
|
237
|
+
--color-text-faint: #838383;
|
|
20
238
|
--color-text-inverse: #050505;
|
|
21
239
|
|
|
22
240
|
--color-surface-app: #050505;
|
|
@@ -30,41 +248,103 @@
|
|
|
30
248
|
--color-accent-fg: #00ff88;
|
|
31
249
|
--color-accent-bg: #00ff88;
|
|
32
250
|
|
|
33
|
-
--color-status-go-fg: #cfe;
|
|
34
|
-
--color-status-go-bg: #2e5a2e;
|
|
35
|
-
--color-status-nogo-fg: #ffdede;
|
|
36
|
-
--color-status-nogo-bg: #ff4d4d;
|
|
37
|
-
--color-status-warning-fg: #1a1a1a;
|
|
38
|
-
--color-status-warning-bg: #ff8c00;
|
|
39
|
-
--color-status-info-fg: #7cf;
|
|
40
|
-
--color-status-info-bg: #0d0d0d;
|
|
41
|
-
|
|
42
251
|
/*
|
|
43
|
-
*
|
|
44
|
-
*
|
|
45
|
-
* inset). Distinct from the primary status colours, which are full-
|
|
46
|
-
* brightness. `alert-muted` covers nogo-tone darks; `warning-bg-muted`
|
|
47
|
-
* covers warning-tone darks (warm browns / olives).
|
|
252
|
+
* The tone hues. A palette rung is named nowhere but this file: everything
|
|
253
|
+
* else reaches a hue through the role token below that says what it is for.
|
|
48
254
|
*/
|
|
49
|
-
--
|
|
50
|
-
--
|
|
255
|
+
--palette-green-100: #cfe;
|
|
256
|
+
--palette-green-500: #3c8050;
|
|
257
|
+
--palette-green-700: #2e5a2e;
|
|
258
|
+
--palette-green-900: #0d180d;
|
|
259
|
+
--palette-red-100: #ffdede;
|
|
260
|
+
--palette-red-400: #ff4d4d;
|
|
261
|
+
--palette-red-900: #4a0e0e;
|
|
262
|
+
--palette-amber-200: #ffd68a;
|
|
263
|
+
--palette-amber-400: #ff8c00;
|
|
264
|
+
--palette-amber-600: #8a6a28;
|
|
265
|
+
--palette-amber-900: #3a2a0a;
|
|
266
|
+
--palette-blue-300: #7cf;
|
|
267
|
+
--palette-ink: #1a1a1a;
|
|
268
|
+
|
|
51
269
|
/*
|
|
52
|
-
*
|
|
53
|
-
*
|
|
54
|
-
*
|
|
270
|
+
* One tone scale, five roles per tone, so a colour is chosen by the job it
|
|
271
|
+
* does rather than by which token happened to look right:
|
|
272
|
+
*
|
|
273
|
+
* -text the tone's words on a surface or on its own muted ground
|
|
274
|
+
* -mark a dot, fill, edge or stroke standing alone, with no text of
|
|
275
|
+
* its own: held to 3:1 on the surfaces
|
|
276
|
+
* -status a fill that carries its own text, which is -on-status
|
|
277
|
+
* -on-status the text on that fill
|
|
278
|
+
* -muted a quiet ground under ordinary text
|
|
279
|
+
*
|
|
280
|
+
* Text takes the pale tint of a hue and marks the saturated one, since a
|
|
281
|
+
* saturated hue that clears 3:1 as a mark is too loud to read as prose, and
|
|
282
|
+
* the pale tint is too faint to carry meaning as a lone dot. go's mark is a
|
|
283
|
+
* mid green, distinct from both its muted fill and the accent, which means
|
|
284
|
+
* focus and interaction and never state.
|
|
55
285
|
*/
|
|
56
|
-
--color-
|
|
57
|
-
--color-
|
|
286
|
+
--color-neutral-text: var(--color-text-primary);
|
|
287
|
+
--color-neutral-mark: var(--color-text-dim);
|
|
288
|
+
--color-neutral-status: var(--color-surface-raised);
|
|
289
|
+
--color-neutral-on-status: var(--color-text-primary);
|
|
290
|
+
--color-neutral-muted: var(--color-surface-raised);
|
|
291
|
+
|
|
292
|
+
--color-info-text: var(--palette-blue-300);
|
|
293
|
+
--color-info-mark: var(--palette-blue-300);
|
|
294
|
+
--color-info-status: var(--palette-blue-300);
|
|
295
|
+
--color-info-on-status: var(--palette-ink);
|
|
296
|
+
--color-info-muted: var(--color-surface-panel);
|
|
297
|
+
|
|
298
|
+
--color-go-text: var(--palette-green-100);
|
|
299
|
+
--color-go-mark: var(--palette-green-500);
|
|
300
|
+
--color-go-status: var(--palette-green-700);
|
|
301
|
+
--color-go-on-status: var(--palette-green-100);
|
|
302
|
+
/* Kept this dark so --color-text-dim body text stays above 4.5:1 on it; a go card's green is carried by its edge. */
|
|
303
|
+
--color-go-muted: var(--palette-green-900);
|
|
304
|
+
|
|
305
|
+
--color-caution-text: var(--palette-amber-200);
|
|
306
|
+
--color-caution-mark: var(--palette-amber-200);
|
|
307
|
+
--color-caution-status: var(--palette-amber-200);
|
|
308
|
+
--color-caution-on-status: var(--palette-ink);
|
|
309
|
+
--color-caution-muted: var(--palette-amber-900);
|
|
310
|
+
|
|
311
|
+
--color-warn-text: var(--palette-amber-200);
|
|
312
|
+
--color-warn-mark: var(--palette-amber-400);
|
|
313
|
+
|
|
314
|
+
/* The mark of a figure a model carried: held keeps the warn square, a modelled figure draws this blue as a triangle, so the two differ by shape and by hue. */
|
|
315
|
+
--color-modelled-mark: var(--palette-blue-300);
|
|
316
|
+
/* The apsides, on an orbit drawing and beside their readouts. Neither is the held amber nor the modelled blue, so an apsis never reads as a mark about how current a figure is. */
|
|
317
|
+
--color-apoapsis-mark: var(--color-data-12);
|
|
318
|
+
--color-periapsis-mark: var(--color-data-15);
|
|
319
|
+
/* The mark of a figure measured now, but of something other than what its label names. Not the held amber, the modelled blue or a go green, so it says nothing about how current the figure is. */
|
|
320
|
+
--color-elsewhere-mark: var(--color-data-15);
|
|
321
|
+
--color-warn-status: var(--palette-amber-400);
|
|
322
|
+
--color-warn-on-status: var(--palette-ink);
|
|
323
|
+
--color-warn-muted: var(--palette-amber-900);
|
|
324
|
+
/* The edge of a warn box drawn on its muted ground: decorative, the box's text carries the tone. */
|
|
325
|
+
--color-warn-muted-edge: var(--palette-amber-600);
|
|
326
|
+
|
|
327
|
+
--color-nogo-text: var(--palette-red-100);
|
|
328
|
+
--color-nogo-mark: var(--palette-red-400);
|
|
329
|
+
--color-nogo-status: var(--palette-red-400);
|
|
330
|
+
--color-nogo-on-status: var(--palette-ink);
|
|
331
|
+
--color-nogo-muted: var(--palette-red-900);
|
|
332
|
+
|
|
333
|
+
--color-offline-text: var(--color-text-dim);
|
|
334
|
+
--color-offline-mark: var(--color-text-dim);
|
|
335
|
+
--color-offline-status: var(--color-surface-raised);
|
|
336
|
+
--color-offline-on-status: var(--color-text-dim);
|
|
337
|
+
--color-offline-muted: var(--color-surface-sunken);
|
|
58
338
|
|
|
59
339
|
/*
|
|
60
|
-
* Tag palette
|
|
340
|
+
* Tag palette: used for *labeled state* with a paired fg / bg /
|
|
61
341
|
* border surface. Examples: a purple "prediction" chip, a blue
|
|
62
342
|
* station-link badge. Each tag has a fg / bg / border triple.
|
|
63
343
|
*
|
|
64
344
|
* Not for categorical data (chart series, telemetry rows, body
|
|
65
|
-
* markers)
|
|
345
|
+
* markers): use the `--color-data-*` palette below for that.
|
|
66
346
|
*
|
|
67
|
-
* Not currently typed in the theme schema
|
|
347
|
+
* Not currently typed in the theme schema, promote when a widely-
|
|
68
348
|
* shared widget begins consuming them programmatically.
|
|
69
349
|
*/
|
|
70
350
|
--color-tag-blue-fg: #4488ff;
|
|
@@ -83,7 +363,28 @@
|
|
|
83
363
|
--color-tag-red-fg: #ff4466;
|
|
84
364
|
|
|
85
365
|
/*
|
|
86
|
-
*
|
|
366
|
+
* Attitude and manoeuvre marker palette: the hue KSP paints each navball
|
|
367
|
+
* marker, so an operator who knows a marker by its colour is not retrained.
|
|
368
|
+
* These are FACTS about the game, not a design choice, and are not to be
|
|
369
|
+
* tuned for the surface: the marker glyphs in `@ksp-gonogo/ui-kit`
|
|
370
|
+
* (`MarkerIcons.tsx`) carry a `currentColor` keyline that supplies the
|
|
371
|
+
* luminance contrast against either ground, so the hue is free to be the
|
|
372
|
+
* game's. Stock ships the glyph atlas as a white alpha mask
|
|
373
|
+
* (`Squad/Props/IVANavBallNoBase/navBall_vectors_IVA.png`) and tints it from
|
|
374
|
+
* the NavBall prefab; the values here are RasterPropMonitor's stock-matching
|
|
375
|
+
* tints (`JSIPrimaryFlightDisplay.cs`), converted from Unity `Color` floats.
|
|
376
|
+
* A pair (prograde/retrograde, normal/anti-normal, radial in/out,
|
|
377
|
+
* target/anti-target) shares one hue in game and shares one token here:
|
|
378
|
+
* within a pair, SHAPE carries the distinction.
|
|
379
|
+
*/
|
|
380
|
+
--color-marker-prograde: #d6fa00;
|
|
381
|
+
--color-marker-normal: #ed00ff;
|
|
382
|
+
--color-marker-radial: #00fff4;
|
|
383
|
+
--color-marker-maneuver: #001dff;
|
|
384
|
+
--color-marker-target: #ff00ff;
|
|
385
|
+
|
|
386
|
+
/*
|
|
387
|
+
* Categorical data palette: used for chart series, telemetry rows,
|
|
87
388
|
* body markers, and anything where the role is "make this category
|
|
88
389
|
* visually distinct from neighbours". Cycle by index (see
|
|
89
390
|
* packages/components/src/shared/dataPalette.ts).
|
|
@@ -92,7 +393,7 @@
|
|
|
92
393
|
* ~70%+ HSL lightness with high saturation so it reads on
|
|
93
394
|
* `--color-surface-app` through `--color-surface-raised`. Hues span
|
|
94
395
|
* ~360° with adjacent pairs visually distinct. None overlap the
|
|
95
|
-
* semantic palette (accent green, status orange/red/nogo)
|
|
396
|
+
* semantic palette (accent green, status orange/red/nogo): a chart
|
|
96
397
|
* series should never be mistaken for a state indicator.
|
|
97
398
|
*/
|
|
98
399
|
--color-data-1: #6cb4ff; /* steel blue */
|
|
@@ -121,13 +422,746 @@
|
|
|
121
422
|
--color-data-24: #f5e07c; /* canary */
|
|
122
423
|
|
|
123
424
|
--color-focus: #00ff88;
|
|
425
|
+
|
|
426
|
+
/*
|
|
427
|
+
* SPACING LADDER. One ladder for padding, margin AND gap, on a 2px grid
|
|
428
|
+
* with a 1px `hair` step below it.
|
|
429
|
+
*
|
|
430
|
+
* The rungs are raw material for the semantic names below and for nothing
|
|
431
|
+
* else. Only this file reads them, and only to define a name; every other
|
|
432
|
+
* file in the repo reads the name, which is enforced by the spacing gate in
|
|
433
|
+
* packages/core/src/styleguide-widget-spacing.test.ts. A rung says how many
|
|
434
|
+
* pixels. A name says which job, and the job is what a reader needs and
|
|
435
|
+
* what a container can change.
|
|
436
|
+
*/
|
|
437
|
+
--space-hair: 1px;
|
|
438
|
+
--space-2: 2px;
|
|
439
|
+
--space-4: 4px;
|
|
440
|
+
--space-6: 6px;
|
|
441
|
+
--space-8: 8px;
|
|
442
|
+
--space-10: 10px;
|
|
443
|
+
--space-12: 12px;
|
|
444
|
+
--space-16: 16px;
|
|
445
|
+
--space-24: 24px;
|
|
446
|
+
|
|
447
|
+
/*
|
|
448
|
+
* SEMANTIC SPACING. Every gap, inset, offset, indent and spacing-derived
|
|
449
|
+
* size in the app, named for its job.
|
|
450
|
+
*
|
|
451
|
+
* A site whose job has no name here gets one: add it to the right family,
|
|
452
|
+
* defined from the rungs or from another name, and read it. Two sites share
|
|
453
|
+
* a name only when they do the same job at the same size, so a name is safe
|
|
454
|
+
* to change for everything that reads it.
|
|
455
|
+
*
|
|
456
|
+
* Families, by the axis the space sits on:
|
|
457
|
+
* --gap-* between siblings, as a `gap` or as the margin that stands
|
|
458
|
+
* in for one in flow layout
|
|
459
|
+
* --inset-* inside an edge, as `padding`. Two- and three-value insets
|
|
460
|
+
* are ordered vertical/horizontal and belong in the
|
|
461
|
+
* `padding` shorthand, never `padding-inline`
|
|
462
|
+
* --outset-* outside an edge, as `margin`, where the box and not its
|
|
463
|
+
* siblings decides the distance
|
|
464
|
+
* --gutter-* one axis of an inset that several boxes share so their
|
|
465
|
+
* content lines up down a column
|
|
466
|
+
* --indent-* a leading inset nesting a child under its parent
|
|
467
|
+
* --offset-* the distance an absolutely positioned box keeps from the
|
|
468
|
+
* edge it is pinned to
|
|
469
|
+
* --size-* a box dimension that sits on the spacing grid
|
|
470
|
+
*
|
|
471
|
+
* The two context names, --gap-related and --gap-section, STEP: a
|
|
472
|
+
* container re-declares them from its tier (`Card` is compact, `Panel`
|
|
473
|
+
* and `Notice` comfortable) and everything inside inherits the new value.
|
|
474
|
+
* The related tiers run comfortable, compact, dense and packed.
|
|
475
|
+
* Every other name is a constant. A tier constant read directly
|
|
476
|
+
* (--gap-related-compact) is the related gap of that tier wherever it
|
|
477
|
+
* sits, which is how a widget spaces blocks in flow without inheriting a
|
|
478
|
+
* card's step.
|
|
479
|
+
*
|
|
480
|
+
* Every name is declared HERE, at `:root`, and a container only ever
|
|
481
|
+
* overrides. A name that resolves nowhere computes to nothing and the
|
|
482
|
+
* declaration is dropped, which for a gap is a silently collapsed layout.
|
|
483
|
+
*/
|
|
484
|
+
|
|
485
|
+
/* Context gaps, and the tiers a container steps them to. */
|
|
486
|
+
--gap-related-comfortable: var(--space-8);
|
|
487
|
+
--gap-related-compact: var(--space-6);
|
|
488
|
+
--gap-related-dense: var(--space-4);
|
|
489
|
+
--gap-related-packed: var(--space-2);
|
|
490
|
+
--gap-section-comfortable: var(--space-16);
|
|
491
|
+
--gap-section-compact: var(--space-12);
|
|
492
|
+
/* Items of the same kind. THE DEFAULT gap. */
|
|
493
|
+
--gap-related: var(--gap-related-comfortable);
|
|
494
|
+
/* Groups of different kinds. */
|
|
495
|
+
--gap-section: var(--gap-section-comfortable);
|
|
496
|
+
|
|
497
|
+
/* Lines and readouts. */
|
|
498
|
+
/* The seam that stops two stacked lines, rows or glyph boxes touching. */
|
|
499
|
+
--gap-line: var(--space-hair);
|
|
500
|
+
/* Stacked rows that each carry their own inset. */
|
|
501
|
+
--gap-rows: var(--space-2);
|
|
502
|
+
/* A caption, note, detail or wrapped second line directly under its owner. */
|
|
503
|
+
--gap-caption: var(--space-2);
|
|
504
|
+
/* A subordinate readout, chip or line under a figure, one step looser. */
|
|
505
|
+
--gap-sub-readout: var(--space-4);
|
|
506
|
+
/* Row seam in a label/value readout grid. */
|
|
507
|
+
--gap-readout-row: var(--space-2);
|
|
508
|
+
/* Column gap between a label and its value. */
|
|
509
|
+
--gap-label-value: var(--space-8);
|
|
510
|
+
/* The same, in a readout squeezed to fit a narrow tile. */
|
|
511
|
+
--gap-label-value-tight: var(--space-6);
|
|
512
|
+
/* A value and the tag, chip, unit or caption running beside it. */
|
|
513
|
+
--gap-value-tag: var(--space-6);
|
|
514
|
+
/* A label and the figure, separator or suffix it runs straight into. */
|
|
515
|
+
--gap-lead-figure: var(--space-2);
|
|
516
|
+
/* A unit symbol set off the figure it qualifies. */
|
|
517
|
+
--gap-unit-suffix: var(--space-2);
|
|
518
|
+
/* The parts of one figure: value and unit, or both ends of a range. */
|
|
519
|
+
--gap-figure-parts: var(--space-4);
|
|
520
|
+
/* Text and a trailing count, value or distance. */
|
|
521
|
+
--gap-trailing-figure: var(--space-4);
|
|
522
|
+
/* Text and a trailing unit, dot, bullet or pill. */
|
|
523
|
+
--gap-trailing-mark: var(--space-6);
|
|
524
|
+
/* The horizontal margin either side of a hairline rule between fields. */
|
|
525
|
+
--gap-rule: var(--space-4);
|
|
526
|
+
/* A title and the hairline rule drawn under it. */
|
|
527
|
+
--gap-title-rule: var(--space-4);
|
|
528
|
+
/* A title or caption and the block it heads. */
|
|
529
|
+
--gap-under-title: var(--space-4);
|
|
530
|
+
/* A row's name and its trailing content. */
|
|
531
|
+
--gap-row: var(--space-8);
|
|
532
|
+
/* The lines of a row allowed to wrap. */
|
|
533
|
+
--gap-row-wrap: var(--space-4);
|
|
534
|
+
/* A headline name and the figure or meta beside it. */
|
|
535
|
+
--gap-headline: var(--space-10);
|
|
536
|
+
/* Consecutive readout groups, each already carrying its own section seam. */
|
|
537
|
+
--gap-readout-groups: var(--space-10);
|
|
538
|
+
/* Lines of the centred content a tiny tile shows, and a hero value's caption. */
|
|
539
|
+
--gap-tiny-content: var(--space-4);
|
|
540
|
+
/* A row meter group stacked on one MeterStack's columns. */
|
|
541
|
+
--gap-meter-rows: var(--space-2);
|
|
542
|
+
/* A meter's label, bar and figure columns. */
|
|
543
|
+
--gap-meter-columns: var(--space-8);
|
|
544
|
+
/* The four bars of one signal-strength glyph. */
|
|
545
|
+
--gap-signal-bars: var(--space-2);
|
|
546
|
+
/* A data line: wrapped rows, then label to value. */
|
|
547
|
+
--gap-data-line: var(--space-4) var(--space-6);
|
|
548
|
+
/* A delay legend: wrapped rows, then entries. */
|
|
549
|
+
--gap-legend: var(--space-4) var(--space-12);
|
|
550
|
+
/* A contract's reward chips: wrapped rows, then chips. */
|
|
551
|
+
--gap-rewards: var(--space-2) var(--space-12);
|
|
552
|
+
/* The two columns of a tag suggestion. */
|
|
553
|
+
--gap-suggestion-columns: var(--space-12);
|
|
554
|
+
|
|
555
|
+
/* Glyphs and controls. */
|
|
556
|
+
/* A glyph and its label in a compact control, a legend or a tick. */
|
|
557
|
+
--gap-glyph: var(--space-4);
|
|
558
|
+
/* A glyph and its label in a full-size control. */
|
|
559
|
+
--gap-glyph-control: var(--space-6);
|
|
560
|
+
/* A glyph and its text inside a bordered status or message box. */
|
|
561
|
+
--gap-glyph-box: var(--space-8);
|
|
562
|
+
/* Adjacent glyph buttons in a tile header's tray. */
|
|
563
|
+
--gap-glyph-tray: var(--space-2);
|
|
564
|
+
/* A pill's glyph and label, and a FAB's label and button. */
|
|
565
|
+
--gap-pill: var(--space-10);
|
|
566
|
+
/* A file or screenshot and the name or caption beside it. */
|
|
567
|
+
--gap-attachment: var(--space-10);
|
|
568
|
+
/* Controls side by side in a row: form actions, a toolbar, a modal footer. */
|
|
569
|
+
--gap-control-row: var(--space-8);
|
|
570
|
+
/* Buttons packed into a grid. */
|
|
571
|
+
--gap-chips: var(--space-4);
|
|
572
|
+
/* A stepper's minus, value and plus. */
|
|
573
|
+
--gap-stepper: var(--space-4);
|
|
574
|
+
/* A cluster set apart from the cluster before it on one line. */
|
|
575
|
+
--gap-inline-cluster: var(--space-6);
|
|
576
|
+
/* A tab strip's tabs. */
|
|
577
|
+
--gap-tab: var(--space-2);
|
|
578
|
+
/* A tab strip and the panel it switches. */
|
|
579
|
+
--gap-tabs-panel: var(--space-12);
|
|
580
|
+
/* A disclosure trigger and the panel it opens. */
|
|
581
|
+
--gap-disclosure: var(--space-2);
|
|
582
|
+
/* A record's lead-in and its name. */
|
|
583
|
+
--gap-record-lead: var(--space-6);
|
|
584
|
+
/* The lines inside a free-standing card on a sheet. */
|
|
585
|
+
--gap-card-lines: var(--space-4);
|
|
586
|
+
|
|
587
|
+
/* Forms. */
|
|
588
|
+
/* A field's label and its input, stacked. */
|
|
589
|
+
--gap-field-label: var(--space-6);
|
|
590
|
+
/* The same in a compact field. */
|
|
591
|
+
--gap-field-label-compact: var(--space-4);
|
|
592
|
+
/* A label, input and suffix laid out in a row. */
|
|
593
|
+
--gap-field-label-inline: var(--space-8);
|
|
594
|
+
/* A read-only field's term and its value. */
|
|
595
|
+
--gap-field-term: var(--space-12);
|
|
596
|
+
/* The fields of a form section. */
|
|
597
|
+
--gap-form-field: var(--space-16);
|
|
598
|
+
/* The fields of a boxed form. */
|
|
599
|
+
--gap-form-field-boxed: var(--space-6);
|
|
600
|
+
/* An extra row hung under a field: a tag list, a screenshot, a listening state. */
|
|
601
|
+
--gap-under-field: var(--space-6);
|
|
602
|
+
/* A unit input's stepped parts. */
|
|
603
|
+
--gap-unit-parts: var(--space-6);
|
|
604
|
+
/* A heading and the hint line under it. */
|
|
605
|
+
--gap-heading-hint: var(--space-6);
|
|
606
|
+
|
|
607
|
+
/* Blocks in flow. */
|
|
608
|
+
/* A row of actions closing the block above it. */
|
|
609
|
+
--gap-actions: var(--space-4);
|
|
610
|
+
/* The actions at the foot of a card. */
|
|
611
|
+
--gap-card-actions: var(--space-6);
|
|
612
|
+
/* A control row closing a list or an editor. */
|
|
613
|
+
--gap-list-footer: var(--space-2);
|
|
614
|
+
/* A heading opening the next group in a list. */
|
|
615
|
+
--gap-list-heading: var(--space-4);
|
|
616
|
+
/* The next section of the maneuver planner. */
|
|
617
|
+
--gap-planner-section: var(--space-4);
|
|
618
|
+
/* A graph series' configuration group. */
|
|
619
|
+
--gap-config-group: var(--space-4);
|
|
620
|
+
/* A crew row's contributed meters and the next row. */
|
|
621
|
+
--gap-crew-meters: var(--space-4);
|
|
622
|
+
/* A toolbar's rule and the table under it. */
|
|
623
|
+
--gap-toolbar: var(--space-4);
|
|
624
|
+
/* A section opening below a rule inside a popover. */
|
|
625
|
+
--gap-popover-section: var(--space-12);
|
|
626
|
+
/* A footnote below the list it closes. */
|
|
627
|
+
--gap-footnote: var(--space-10);
|
|
628
|
+
/* The mission bar and the screen under it. */
|
|
629
|
+
--gap-mission-bar: var(--space-8);
|
|
630
|
+
/* Prose blocks. */
|
|
631
|
+
--gap-prose: var(--space-10);
|
|
632
|
+
/* Items of a prose list. */
|
|
633
|
+
--gap-prose-item: var(--space-4);
|
|
634
|
+
|
|
635
|
+
/* Panels. */
|
|
636
|
+
/* A panel's horizontal gutter, shared by its title, toolbar, body, sidebar
|
|
637
|
+
and footer so their content lines up down one column. */
|
|
638
|
+
--gutter-panel: var(--space-16);
|
|
639
|
+
/* How far a horizontal strip (a tab bar, a wide table) may reach past its
|
|
640
|
+
box to the panel's edge. A context name: a panel body steps it to its
|
|
641
|
+
gutter, and a bordered block inside resets it, so nothing bleeds out of a
|
|
642
|
+
card. */
|
|
643
|
+
--bleed-inline: 0px;
|
|
644
|
+
--inset-panel-top: var(--space-8);
|
|
645
|
+
--inset-panel-bottom: var(--space-12);
|
|
646
|
+
--inset-panel-body: var(--inset-panel-top) var(--gutter-panel)
|
|
647
|
+
var(--inset-panel-bottom);
|
|
648
|
+
/* The inset a panel steps down to when it has little room to give: a lone
|
|
649
|
+
framed drawing under a narrow container (a hairline of panel surface
|
|
650
|
+
either side of the frame's own border, so the panel's edge and the
|
|
651
|
+
frame's read as two lines rather than one thick one), and the tiny
|
|
652
|
+
hover-title panel's own edge (the same narrow-panel case; it is always
|
|
653
|
+
that narrow, so it takes the step unconditionally rather than under a
|
|
654
|
+
container query). */
|
|
655
|
+
--inset-tiny: var(--space-6);
|
|
656
|
+
/* A sidebar's top inset when it sits UNDER the body: the body's bottom
|
|
657
|
+
inset is already above it, so the full panel top would double the gap
|
|
658
|
+
between a drawing and the readouts that annotate it. */
|
|
659
|
+
--inset-panel-sidebar-under: var(--space-4);
|
|
660
|
+
/* No bottom inset: the body's own gap is the only space between the header and the content. */
|
|
661
|
+
--inset-panel-header: 0 var(--gutter-panel);
|
|
662
|
+
/* Above a hand-composed header row; inside a Panel the rail band is that inset. */
|
|
663
|
+
--inset-panel-header-top: var(--space-6);
|
|
664
|
+
--inset-panel-toolbar: var(--space-6) var(--gutter-panel) 0;
|
|
665
|
+
--inset-panel-footer: var(--space-6) var(--gutter-panel) var(--space-8);
|
|
666
|
+
/* A panel header's title and its aside. */
|
|
667
|
+
--gap-panel-header: var(--space-8);
|
|
668
|
+
/* Items in a panel header's aside. */
|
|
669
|
+
--gap-panel-aside: var(--space-4);
|
|
670
|
+
/* Sections side by side in a panel body. */
|
|
671
|
+
--gap-panel-columns: var(--space-16);
|
|
672
|
+
/* Sections stacked in a panel body's grid. */
|
|
673
|
+
--gap-panel-sections: var(--space-12);
|
|
674
|
+
/* The height of a panel's full-bleed trend strip along its bottom edge. */
|
|
675
|
+
--size-panel-trend: var(--space-24);
|
|
676
|
+
/* The least height a filling Section keeps when its siblings take the rest; the panel body scrolls past it. */
|
|
677
|
+
--size-section-fill-floor: calc(var(--space-24) * 4);
|
|
678
|
+
/* The band every panel reserves at its top edge for the delay rail. */
|
|
679
|
+
--panel-rail-band: var(--space-16);
|
|
680
|
+
|
|
681
|
+
/* Command delay. */
|
|
682
|
+
/* The strips around a panel's commands, on the panel gutter. */
|
|
683
|
+
--outset-command-strip: var(--space-4) var(--gutter-panel);
|
|
684
|
+
/* The delay stream's legend, on the panel gutter. */
|
|
685
|
+
--outset-delay-legend: 0 var(--gutter-panel) var(--space-4);
|
|
686
|
+
--gap-delay-stream: var(--space-4);
|
|
687
|
+
--gap-delay-rail: var(--space-8);
|
|
688
|
+
--gap-rail-summaries: var(--space-8);
|
|
689
|
+
--offset-rail-hint: var(--space-4);
|
|
690
|
+
/* How far the collapse hint's click target reaches past its glyph. */
|
|
691
|
+
--outset-rail-hint-target: var(--space-8);
|
|
692
|
+
--gap-message-stack: var(--space-4);
|
|
693
|
+
--inset-command-list: var(--space-4) var(--space-8);
|
|
694
|
+
--gap-command-list-column: var(--space-8);
|
|
695
|
+
--gap-command-list-row: var(--space-2);
|
|
696
|
+
--gap-command-row: var(--space-6);
|
|
697
|
+
|
|
698
|
+
/* Surfaces. */
|
|
699
|
+
/* A bordered or filled box that holds content: a card, a record, a popover body. */
|
|
700
|
+
--inset-surface: var(--space-6) var(--space-8);
|
|
701
|
+
/* A card that IS its screen, holding its own controls. */
|
|
702
|
+
--inset-surface-standalone: var(--space-10) var(--space-12);
|
|
703
|
+
/* A label sized by its text: a badge, a pill, an inline code span. */
|
|
704
|
+
--inset-chip: var(--space-hair) var(--space-6);
|
|
705
|
+
/* The same on a larger badge. */
|
|
706
|
+
--inset-chip-roomy: var(--space-hair) var(--space-8);
|
|
707
|
+
/* A chip that carries a live reading. */
|
|
708
|
+
--inset-chip-readout: var(--space-2) var(--space-8);
|
|
709
|
+
/* A single-token status pill, and a message pill that shares its shape. */
|
|
710
|
+
--inset-pill: var(--space-6) var(--space-12);
|
|
711
|
+
/* A floating or full-width banner on the 16px gutter. */
|
|
712
|
+
--inset-banner: var(--space-8) var(--space-16);
|
|
713
|
+
/* An alert band that spans the app or a menu. */
|
|
714
|
+
--inset-alert-band: var(--space-10) var(--space-16);
|
|
715
|
+
/* A bordered status box sized to --control-height. */
|
|
716
|
+
--inset-status-box: var(--space-4) var(--space-8);
|
|
717
|
+
/* A popover's content. */
|
|
718
|
+
--inset-popover: var(--space-8);
|
|
719
|
+
/* A tooltip's content. */
|
|
720
|
+
--inset-tooltip: var(--space-4) var(--space-8);
|
|
721
|
+
/* The drop between an anchor and the popover it opens. */
|
|
722
|
+
--offset-popover: var(--space-4);
|
|
723
|
+
/* A popover shadow's offset and blur. */
|
|
724
|
+
--shadow-popover-drop: 0 var(--space-4) var(--space-12);
|
|
725
|
+
/* Visual content held inside a FramedDisplay. */
|
|
726
|
+
--inset-framed-display: var(--space-4);
|
|
727
|
+
/* A panel sharing a FramedDisplay slot, whose frame draws the edge. */
|
|
728
|
+
--inset-frame-panel: var(--space-8) var(--space-10);
|
|
729
|
+
/* A box pinned into its container's corner. */
|
|
730
|
+
--offset-corner: var(--space-4);
|
|
731
|
+
/* A graph notice pinned over the plot's bottom-left corner, and its inset. */
|
|
732
|
+
--offset-graph-notice-bottom: var(--space-4);
|
|
733
|
+
--offset-graph-notice-left: var(--space-8);
|
|
734
|
+
--inset-notice-pill: var(--space-2) var(--space-4);
|
|
735
|
+
/* A caption inlaid on a FramedDisplay's own top-left corner. */
|
|
736
|
+
--offset-frame-caption-top: var(--space-6);
|
|
737
|
+
--offset-frame-caption-left: var(--space-8);
|
|
738
|
+
/* A footer line inlaid on a FramedDisplay's own bottom-left corner. */
|
|
739
|
+
--offset-frame-footer-bottom: var(--space-6);
|
|
740
|
+
--offset-frame-footer-left: var(--space-8);
|
|
741
|
+
|
|
742
|
+
/* Controls. */
|
|
743
|
+
/* A box you press or type into, on the --control-height floor. */
|
|
744
|
+
--inset-control: var(--space-6) var(--space-12);
|
|
745
|
+
/* The same class in a box that cannot reach the floor. */
|
|
746
|
+
--inset-control-compact: var(--space-hair) var(--space-4);
|
|
747
|
+
/* The same class standing on its own, one tier above the floor. */
|
|
748
|
+
--inset-control-prominent: var(--space-8) var(--space-12);
|
|
749
|
+
/* A small button, toggle or chip control. */
|
|
750
|
+
--inset-control-small: var(--space-2) var(--space-8);
|
|
751
|
+
/* The coarse-pointer widening of a control. */
|
|
752
|
+
--inset-control-touch: var(--space-8) var(--space-16);
|
|
753
|
+
/* The coarse-pointer widening of a small control. */
|
|
754
|
+
--inset-control-small-touch: var(--space-6) var(--space-10);
|
|
755
|
+
/* A chromeless glyph button. */
|
|
756
|
+
--inset-glyph-button: var(--space-2) var(--space-4);
|
|
757
|
+
/* A glyph button in a row, padded across only. */
|
|
758
|
+
--inset-glyph: 0 var(--space-4);
|
|
759
|
+
/* The same, packed tight against the row's text. */
|
|
760
|
+
--inset-glyph-tight: 0 var(--space-2);
|
|
761
|
+
/* A square icon-only button. */
|
|
762
|
+
--inset-icon-button: var(--space-6);
|
|
763
|
+
--inset-icon-button-compact: var(--space-4);
|
|
764
|
+
--inset-icon-button-tight: var(--space-2);
|
|
765
|
+
--inset-icon-button-touch: var(--space-8);
|
|
766
|
+
/* A command group's commit button. */
|
|
767
|
+
--inset-commit-button: var(--space-4) var(--space-12);
|
|
768
|
+
/* A compact button in a form's footer. */
|
|
769
|
+
--inset-form-footer-button: var(--space-4) var(--space-10);
|
|
770
|
+
/* A glyph button in a dense grid, taller than wide. */
|
|
771
|
+
--inset-warp-button: var(--space-6) var(--space-4);
|
|
772
|
+
/* A text button inside a FAB prompt. */
|
|
773
|
+
--inset-prompt-button: 0 var(--space-12);
|
|
774
|
+
/* A file picker's button on a coarse pointer. */
|
|
775
|
+
--inset-file-button-touch: var(--space-10) var(--space-16);
|
|
776
|
+
/* A momentary button on the virtual pad. */
|
|
777
|
+
--inset-pad-button: var(--space-10) 0;
|
|
778
|
+
/* A stepper's buttons and value. */
|
|
779
|
+
--inset-stepper: var(--space-4) var(--space-8);
|
|
780
|
+
--size-stepper-button: var(--space-24);
|
|
781
|
+
/* A switch label's touch target. */
|
|
782
|
+
--inset-switch-touch: 0 var(--space-6);
|
|
783
|
+
/* A segmented control's track. */
|
|
784
|
+
--inset-segment-track: var(--space-2);
|
|
785
|
+
/* A tab strip's track, and the selection blob inside it. */
|
|
786
|
+
--inset-tab-track: var(--space-4);
|
|
787
|
+
--inset-tab-compact: var(--space-4) var(--space-6);
|
|
788
|
+
--inset-tab-compact-touch: var(--space-4) var(--space-8);
|
|
789
|
+
/* A jog wheel's content, and its value label. */
|
|
790
|
+
--inset-jog-wheel: var(--space-4);
|
|
791
|
+
--inset-jog-wheel-compact: var(--space-2);
|
|
792
|
+
--inset-jog-wheel-label: 0 var(--space-2);
|
|
793
|
+
/* The room a Meter figure keeps for the held mark drawn outside it. */
|
|
794
|
+
--inset-meter-mark: var(--space-6);
|
|
795
|
+
|
|
796
|
+
/* Fields. */
|
|
797
|
+
--inset-field: var(--space-6) var(--space-8);
|
|
798
|
+
--inset-field-compact: var(--space-4) var(--space-6);
|
|
799
|
+
--inset-field-touch: var(--space-10) var(--space-12);
|
|
800
|
+
/* The trailing room a search field keeps for its clear control. */
|
|
801
|
+
--inset-field-clearable-end: calc(var(--icon-size-control) + var(--space-12));
|
|
802
|
+
/* The trailing room a select keeps for its drawn arrow. */
|
|
803
|
+
--inset-field-select-end: var(--space-24);
|
|
804
|
+
/* The two strokes of a select's arrow: each one's size, and how far each sits from the field's end. */
|
|
805
|
+
--size-select-arrow: var(--space-4);
|
|
806
|
+
--offset-select-arrow-near: var(--space-12);
|
|
807
|
+
--offset-select-arrow-far: var(--space-16);
|
|
808
|
+
/* A boxed form's surface. */
|
|
809
|
+
--inset-form-box: var(--space-8) var(--space-10);
|
|
810
|
+
/* A search input flush in its band. */
|
|
811
|
+
--inset-search-input: var(--space-4) 0;
|
|
812
|
+
|
|
813
|
+
/* Menus, lists and tables. */
|
|
814
|
+
--inset-menu-list: var(--space-4) 0;
|
|
815
|
+
--inset-menu-item: var(--space-6) var(--space-8);
|
|
816
|
+
/* A group label, hugging the items under it. */
|
|
817
|
+
--inset-menu-group-label: var(--space-8) var(--space-8) var(--space-4);
|
|
818
|
+
--inset-empty-menu: var(--space-12) var(--space-8);
|
|
819
|
+
--inset-row: var(--space-2) 0;
|
|
820
|
+
--inset-row-pressable: var(--space-4) var(--space-6);
|
|
821
|
+
/* A row picked from a select-one list. */
|
|
822
|
+
--inset-selectable-row: var(--space-2) var(--space-4);
|
|
823
|
+
/* A nested row under its parent. */
|
|
824
|
+
--indent-row: var(--space-12);
|
|
825
|
+
/* A line of text flush in its container, given a little vertical room. */
|
|
826
|
+
--inset-line: var(--space-2) 0;
|
|
827
|
+
/* A part row in a dense parts list. */
|
|
828
|
+
--inset-part-row: var(--space-hair) 0;
|
|
829
|
+
/* A label/value row in an expanded detail. */
|
|
830
|
+
--inset-detail-row: var(--space-4) 0;
|
|
831
|
+
/* A section header lined up with the toggles beside it. */
|
|
832
|
+
--inset-list-heading: var(--space-2) var(--space-4);
|
|
833
|
+
--gutter-table-cell: var(--space-8);
|
|
834
|
+
--inset-table-cell: var(--space-4) var(--gutter-table-cell);
|
|
835
|
+
--inset-table-section: var(--space-6) var(--gutter-table-cell);
|
|
836
|
+
--inset-table-detail: 0 var(--gutter-table-cell) var(--space-6);
|
|
837
|
+
--inset-table-empty: var(--space-8);
|
|
838
|
+
--inset-table-footer: var(--space-10) var(--gutter-table-cell) var(--space-4);
|
|
839
|
+
/* A narrow column header, taller than wide. */
|
|
840
|
+
--inset-table-narrow-header: var(--space-6) var(--space-4);
|
|
841
|
+
/* A reach table's cells. */
|
|
842
|
+
--inset-reach-cell: var(--space-2) var(--space-4);
|
|
843
|
+
/* A fleet roster cell, and the contributed lines hung under its row. */
|
|
844
|
+
--gutter-roster-cell: var(--space-6);
|
|
845
|
+
--inset-roster-cell: 0 var(--gutter-roster-cell);
|
|
846
|
+
/* A transfer window row and the expander under it, sharing one gutter. */
|
|
847
|
+
--gutter-window-row: var(--space-12);
|
|
848
|
+
--inset-window-row: var(--space-8) var(--gutter-window-row);
|
|
849
|
+
--inset-window-expander: var(--space-8) var(--gutter-window-row)
|
|
850
|
+
var(--space-4);
|
|
851
|
+
/* A tech node's expanded body, under the node row's own inset. */
|
|
852
|
+
--inset-node-body: var(--space-4) var(--space-10) var(--space-8);
|
|
853
|
+
/* A tech-graph card, sized against its fixed card height. */
|
|
854
|
+
--inset-graph-card: var(--space-4) var(--space-8);
|
|
855
|
+
/* The vessel switch panel. */
|
|
856
|
+
--inset-switch-panel: var(--space-2);
|
|
857
|
+
/* The spacing around a reveal toggle at a list header. */
|
|
858
|
+
--outset-reveal-toggle: var(--space-2) var(--space-2) var(--space-4);
|
|
859
|
+
|
|
860
|
+
/* Rules. */
|
|
861
|
+
/* Content opening below a divider rule. */
|
|
862
|
+
--inset-below-rule: var(--space-6);
|
|
863
|
+
/* A footnote below its rule. */
|
|
864
|
+
--inset-footnote-rule: var(--space-8);
|
|
865
|
+
/* A toolbar above its bottom rule. */
|
|
866
|
+
--inset-toolbar-bottom: var(--space-10);
|
|
867
|
+
|
|
868
|
+
/* Messages and empty states. */
|
|
869
|
+
/* A message that fills its container. */
|
|
870
|
+
--inset-empty-state: var(--space-16);
|
|
871
|
+
/* A message that fills a tile: an error, a placeholder, a no-data note. */
|
|
872
|
+
--inset-tile-message: var(--space-12);
|
|
873
|
+
/* A one-line "nothing here" note in a list. */
|
|
874
|
+
--inset-empty-note: var(--space-8) 0;
|
|
875
|
+
--inset-empty-roster: var(--space-6) 0;
|
|
876
|
+
--inset-empty-modal-list: var(--space-12) 0;
|
|
877
|
+
--inset-empty-popover: var(--space-16) 0;
|
|
878
|
+
--inset-chart-empty: var(--space-24) 0;
|
|
879
|
+
/* A widget's refusal to draw. */
|
|
880
|
+
--inset-refusal: var(--space-8);
|
|
881
|
+
/* A message standing in for a whole screen. */
|
|
882
|
+
--inset-screen-message: var(--space-24);
|
|
883
|
+
/* A stand-in box with no content of its own. */
|
|
884
|
+
--inset-placeholder: var(--space-8);
|
|
885
|
+
/* Contributed plots, framed by themselves. */
|
|
886
|
+
--inset-contributed-plots: var(--space-8) 0;
|
|
887
|
+
/* The maneuver planner's shortfall banner. */
|
|
888
|
+
--inset-feasibility-banner: var(--space-6) var(--space-10);
|
|
889
|
+
/* A bordered inline confirmation bar. */
|
|
890
|
+
--inset-confirm-bar: var(--space-10);
|
|
891
|
+
|
|
892
|
+
/* Screens, overlays and modals. */
|
|
893
|
+
/* A screen's outer gutter, before any safe-area inset. */
|
|
894
|
+
--gutter-screen: var(--space-24);
|
|
895
|
+
/* The gutter of a widget screen whose children draw no edge of their own; the panel pads the sides. */
|
|
896
|
+
--gutter-screen-body: var(--space-8) 0;
|
|
897
|
+
/* The dashboard grid's gutter between tiles. */
|
|
898
|
+
--gutter-dashboard: var(--space-8);
|
|
899
|
+
/* A tile's drag header. */
|
|
900
|
+
--inset-tile-header: 0 var(--space-4);
|
|
901
|
+
/* A dialog that stands alone over the app. */
|
|
902
|
+
--inset-dialog: var(--space-24);
|
|
903
|
+
--inset-modal-bar: var(--space-12) var(--space-16);
|
|
904
|
+
--inset-modal-body: var(--space-16);
|
|
905
|
+
/* The bands of a full-surface overlay, on one gutter. */
|
|
906
|
+
--gutter-overlay: var(--space-16);
|
|
907
|
+
--inset-overlay-band: var(--space-12) var(--gutter-overlay);
|
|
908
|
+
--inset-overlay-heading: var(--space-6) var(--gutter-overlay);
|
|
909
|
+
--inset-overlay-chips: var(--space-10) var(--gutter-overlay);
|
|
910
|
+
--inset-overlay-empty: var(--space-24) var(--gutter-overlay);
|
|
911
|
+
/* A reference sheet's header and body. */
|
|
912
|
+
--inset-reference-sheet: var(--space-10) var(--space-16);
|
|
913
|
+
/* The mission bar. */
|
|
914
|
+
--inset-mission-bar: 0 var(--space-2);
|
|
915
|
+
/* The Go/No-Go board. */
|
|
916
|
+
--inset-gonogo-board: var(--space-12);
|
|
917
|
+
/* A QR code's quiet zone. */
|
|
918
|
+
--inset-qr: var(--space-12);
|
|
919
|
+
/* A settings row, and a nested settings row. */
|
|
920
|
+
--inset-settings-row: var(--space-6) 0;
|
|
921
|
+
--indent-settings: var(--space-16);
|
|
922
|
+
/* The chapter editor's band. */
|
|
923
|
+
--inset-chapters-band: var(--space-10) var(--space-12) var(--space-12);
|
|
924
|
+
/* A device-picker row. */
|
|
925
|
+
--inset-picker-row: var(--space-6) 0;
|
|
926
|
+
/* A wizard, and the boxes inside it. */
|
|
927
|
+
--inset-wizard: var(--space-12);
|
|
928
|
+
--inset-wizard-box: var(--space-8);
|
|
929
|
+
/* A virtual device's frame buffer. */
|
|
930
|
+
--inset-device-display: var(--space-8);
|
|
931
|
+
/* The virtual pad's centre mark, off its track's ends. */
|
|
932
|
+
--offset-pad-mark: var(--space-4);
|
|
933
|
+
/* An inline code run in a banner. */
|
|
934
|
+
--inset-code-inline: 0 var(--space-2);
|
|
935
|
+
/* A free-standing sheet of cards, and a card on it. */
|
|
936
|
+
--inset-sheet: var(--space-12);
|
|
937
|
+
--inset-sheet-card: var(--space-8) var(--space-12);
|
|
938
|
+
|
|
939
|
+
/* Consoles and logs. */
|
|
940
|
+
/* A scrolling log's inner inset. */
|
|
941
|
+
--inset-log: var(--space-8);
|
|
942
|
+
/* A console's foot, and the chips pinned to its edges. */
|
|
943
|
+
--inset-console-foot: var(--space-8);
|
|
944
|
+
/* The foot's top when a reading straddles the composer's border. */
|
|
945
|
+
--inset-console-foot-straddled: var(--space-16);
|
|
946
|
+
--gap-console-foot: var(--space-6);
|
|
947
|
+
--gap-console-readings: var(--space-6);
|
|
948
|
+
--gap-composer: var(--space-6);
|
|
949
|
+
/* The prompt glyph and the line typed after it. */
|
|
950
|
+
--gap-prompt-glyph: var(--space-8);
|
|
951
|
+
|
|
952
|
+
/* Indents and marks. */
|
|
953
|
+
/* A contributed aside or detail under the row it belongs to. */
|
|
954
|
+
--indent-aside: var(--space-8);
|
|
955
|
+
/* The burn axis, off the row's leading edge. */
|
|
956
|
+
--indent-burn-axis: var(--space-8);
|
|
957
|
+
--size-burn-axis: var(--space-12);
|
|
958
|
+
--size-burn-mark: var(--space-6);
|
|
959
|
+
/* A short mark rather than a rule: a card's identity tab, a threshold tick. */
|
|
960
|
+
--size-mark: var(--space-24);
|
|
961
|
+
/* The height a comms hop keeps with no detail to show. */
|
|
962
|
+
--size-comms-hop: var(--space-16);
|
|
963
|
+
/* The gauge bar under a tiny tile's figure: the figure and the bar share a content box barely taller than the figure. */
|
|
964
|
+
--size-tiny-gauge: var(--space-2);
|
|
965
|
+
|
|
966
|
+
/*
|
|
967
|
+
* RADIUS. Three jobs plus two shape sentinels.
|
|
968
|
+
*
|
|
969
|
+
* The ladder was `xs`/`sm`/`md`/`lg` at 2/3/4/6px, which answered
|
|
970
|
+
* "which number" and nothing else, the same t-shirt complaint already
|
|
971
|
+
* ruled on for spacing. Measured over its 515 sites: `xs` (236) and
|
|
972
|
+
* `sm` (140) do not separate at all, buttons and inputs take both, and
|
|
973
|
+
* `md` (28) mostly joins them. One name covers all three, and every
|
|
974
|
+
* site moves by at most a pixel.
|
|
975
|
+
*
|
|
976
|
+
* regular Every ordinary corner in the app: chips, badges, buttons,
|
|
977
|
+
* inputs, rows, cells, swatches, cards, menus, dropdowns.
|
|
978
|
+
* 400+ sites, and there was never a rule distinguishing
|
|
979
|
+
* them.
|
|
980
|
+
* floating A box that sits ABOVE the app rather than in it. Eight of
|
|
981
|
+
* `lg`'s nine sites were already exactly that population
|
|
982
|
+
* (`Modal`, three consent/reference modals, `Fab`,
|
|
983
|
+
* `HostedLanding`, `GoNoGo`, the in-flight queue panel), so
|
|
984
|
+
* this names a job the ladder was already being used for by
|
|
985
|
+
* accident. It pairs deliberately with the `z` ladder's
|
|
986
|
+
* floating rungs: a thing that floats wants both, and a
|
|
987
|
+
* reader reaching for one should reach for the other.
|
|
988
|
+
* display-frame
|
|
989
|
+
* `FramedDisplay`'s corner, and only that. Bigger than
|
|
990
|
+
* everything else on purpose: it is what separates a box
|
|
991
|
+
* that is LOOKED AT from a box that is READ, which the kit
|
|
992
|
+
* asserted in a doc comment and nowhere in its pixels while
|
|
993
|
+
* a frame and a card were both drawn at 3px.
|
|
994
|
+
*
|
|
995
|
+
* Named for the frame rather than for "visual", so the next
|
|
996
|
+
* ambiguous box cannot reach for it and feel justified. It
|
|
997
|
+
* is a container external belonging to ONE container.
|
|
998
|
+
*
|
|
999
|
+
* It STEPS, which is what makes it a custom property rather
|
|
1000
|
+
* than a constant: `Block`'s side asides re-declare it, so
|
|
1001
|
+
* a frame holding a 40px avatar in a record's left aside
|
|
1002
|
+
* takes a corner proportioned to that box without the frame
|
|
1003
|
+
* knowing its own size. Content asks, context answers, the
|
|
1004
|
+
* same mechanism `--gap-related` uses.
|
|
1005
|
+
*
|
|
1006
|
+
* `pill` and `circle` are SHAPES, not sizes. 50% is a circle on a
|
|
1007
|
+
* square box; 999px clamps to exactly half the shorter side, so it
|
|
1008
|
+
* renders identically to a hand-computed half-height while surviving a
|
|
1009
|
+
* change to that height. Every stadium in the codebase (the 7px switch
|
|
1010
|
+
* track, the 10px chip, the 12px filter chip, the 20px and 24px FAB
|
|
1011
|
+
* prompts) should reach for `pill` rather than recomputing the half.
|
|
1012
|
+
* Neither sentinel belongs on the numeric ramp.
|
|
1013
|
+
*/
|
|
1014
|
+
--radius-regular: 3px;
|
|
1015
|
+
--radius-floating: 6px;
|
|
1016
|
+
--radius-display-frame: 8px;
|
|
1017
|
+
/* What `Block`'s side asides step --radius-display-frame to. */
|
|
1018
|
+
--radius-display-frame-aside: 4px;
|
|
1019
|
+
--radius-pill: 999px;
|
|
1020
|
+
--radius-circle: 50%;
|
|
1021
|
+
|
|
1022
|
+
/*
|
|
1023
|
+
* CONTROL HEIGHT. One rung, and one is the point of it.
|
|
1024
|
+
*
|
|
1025
|
+
* Every boxed control in the kit used to take its height from whatever was
|
|
1026
|
+
* inside it: a small toggle around a 14px glyph came out at 20px, the same
|
|
1027
|
+
* toggle around a word at 17, a bordered status readout at 27 and a default
|
|
1028
|
+
* button at 30. Put four of them in a row, which is what a widget bar IS, and
|
|
1029
|
+
* the row is visibly ragged with no one declaration to blame. Commcast's
|
|
1030
|
+
* radio bar is where the operator finally said so.
|
|
1031
|
+
*
|
|
1032
|
+
* So `size` on a control chooses its type scale and its inset, never its
|
|
1033
|
+
* height: a control is a control-shaped box. Read it as a `min-height` so
|
|
1034
|
+
* genuinely taller content (a wrapped label, a coarse-pointer target) still
|
|
1035
|
+
* grows the box rather than clipping inside it, and pair it with
|
|
1036
|
+
* `--line-height-flush` so a line box's unused descender headroom is not what
|
|
1037
|
+
* decides whether a control clears the floor.
|
|
1038
|
+
*
|
|
1039
|
+
* 28px is where the two commonest controls in the app already sat, so this
|
|
1040
|
+
* lifts the small ones to meet them rather than moving everything. The check
|
|
1041
|
+
* that it is high enough, worth writing down because a floor a control
|
|
1042
|
+
* OVERSHOOTS is a floor that does nothing for it: a default Button is
|
|
1043
|
+
* 12 inset + 2 border + a 14px glyph = 28, a small ToggleButton 4 + 2 + 14 =
|
|
1044
|
+
* 20, and a StatusIndicator 8 + 2 + 11px text at a 1.4 line height = 25.4.
|
|
1045
|
+
* Every one of them lands on the floor. The indicator is why its own inset
|
|
1046
|
+
* came down a rung; at the old one it cleared 28 and stayed the odd box out.
|
|
1047
|
+
* Coarse pointers ignore all of this and take the 44px touch target.
|
|
1048
|
+
*
|
|
1049
|
+
* A box that cannot reach this floor at all is a different case from one
|
|
1050
|
+
* that undershoots it. Ten pressable glyphs and chips would OVERFLOW what
|
|
1051
|
+
* holds them at 28: an 18px drag header, a note whose whole one-line body is
|
|
1052
|
+
* about that tall, a fixed overlay with a logged history of swallowing the
|
|
1053
|
+
* clicks underneath it. They take `--inset-control-compact` above, and each
|
|
1054
|
+
* names the box it is stuck inside.
|
|
1055
|
+
*/
|
|
1056
|
+
--control-height: 28px;
|
|
1057
|
+
|
|
1058
|
+
/*
|
|
1059
|
+
* Z-INDEX, as named layers rather than a numeric ramp.
|
|
1060
|
+
*
|
|
1061
|
+
* Only app-global chrome belongs here. Roughly half the z-index
|
|
1062
|
+
* declarations in the repo (the 0/1/2, 5/6 and 10/20 families) are
|
|
1063
|
+
* LOCAL sibling ordering inside one component's own stacking context,
|
|
1064
|
+
* where the absolute number is meaningless and only the relative order
|
|
1065
|
+
* matters. Those stay literal; pulling them onto this ladder would
|
|
1066
|
+
* collapse several independent contexts into one and can invert either
|
|
1067
|
+
* pair.
|
|
1068
|
+
*
|
|
1069
|
+
* The order below is derived from what the app does today, with two
|
|
1070
|
+
* deliberate corrections where today's numbers are already inverted:
|
|
1071
|
+
*
|
|
1072
|
+
* base 0 default flow.
|
|
1073
|
+
* sticky 100 in-flow chrome that pins while content scrolls
|
|
1074
|
+
* (the replay session bar, sticky table headers).
|
|
1075
|
+
* dropdown 200 popovers anchored to a control (combobox, tag
|
|
1076
|
+
* autocomplete, the science-augment menu). MUST
|
|
1077
|
+
* outrank sticky: a select opened next to a pinned
|
|
1078
|
+
* bar has to render over it. One of these menus
|
|
1079
|
+
* currently sits at 20 and renders BEHIND the
|
|
1080
|
+
* sticky bar; this rung is the fix.
|
|
1081
|
+
* overlay 800 full-surface overlays that replace the dashboard
|
|
1082
|
+
* (pushed dashboard, station overlay).
|
|
1083
|
+
* fab 900 the bottom-right floating control cluster.
|
|
1084
|
+
* Strictly BELOW backdrop: the FAB opens the
|
|
1085
|
+
* backdrop and must be covered by it.
|
|
1086
|
+
* backdrop 950 the scrim behind a modal. Covers the FAB, sits
|
|
1087
|
+
* under the dialog surface.
|
|
1088
|
+
* modal 1000 dialog surfaces.
|
|
1089
|
+
* toast 1100 transient notifications. ABOVE modal on purpose:
|
|
1090
|
+
* an alarm or offline banner has to reach the
|
|
1091
|
+
* operator even while a dialog is open. The banner
|
|
1092
|
+
* stack sits at 90 today, which renders it behind
|
|
1093
|
+
* the FAB it is positioned beside.
|
|
1094
|
+
* critical 10000 consent gates. Deliberately far off the ramp;
|
|
1095
|
+
* a consent surface may never be occluded.
|
|
1096
|
+
*/
|
|
1097
|
+
--z-base: 0;
|
|
1098
|
+
--z-sticky: 100;
|
|
1099
|
+
--z-dropdown: 200;
|
|
1100
|
+
--z-overlay: 800;
|
|
1101
|
+
--z-fab: 900;
|
|
1102
|
+
--z-backdrop: 950;
|
|
1103
|
+
--z-modal: 1000;
|
|
1104
|
+
--z-toast: 1100;
|
|
1105
|
+
--z-critical: 10000;
|
|
1106
|
+
|
|
1107
|
+
/*
|
|
1108
|
+
* MOTION. Durations and easings for UI transitions only.
|
|
1109
|
+
*
|
|
1110
|
+
* The census splits cleanly into two populations. 52 declarations are
|
|
1111
|
+
* UI transitions (hover, focus, open, close) in the 60ms to 400ms
|
|
1112
|
+
* band; 19 are PHYSICAL animation, where the duration encodes
|
|
1113
|
+
* something real: a resource bar tied to the telemetry sample cadence,
|
|
1114
|
+
* a reticle chasing a moving target, a 1Hz terminal caret, a spinner,
|
|
1115
|
+
* an indicator whose 1s-versus-2s period is how the operator reads
|
|
1116
|
+
* connection state. Those keep their literal values and their
|
|
1117
|
+
* `linear` / `step-end` timing; folding them onto a UI scale would
|
|
1118
|
+
* destroy information the widget is deliberately carrying.
|
|
1119
|
+
*
|
|
1120
|
+
* instant 80ms binary state flips, the visual echo of a press.
|
|
1121
|
+
* fast 120ms small property changes: colour, border, opacity.
|
|
1122
|
+
* base 150ms THE DEFAULT for a UI transition.
|
|
1123
|
+
* slow 200ms larger moves: a panel expanding, a row sliding.
|
|
1124
|
+
* entrance 320ms paired with `--ease-entrance`; the banner
|
|
1125
|
+
* entrance recipe, always used together.
|
|
1126
|
+
*
|
|
1127
|
+
* standard the default curve for a UI transition.
|
|
1128
|
+
* emphasis symmetric, for looping attention pulses.
|
|
1129
|
+
* linear continuous physical motion. Required, not stylistic: an
|
|
1130
|
+
* eased bar fill appears to stall between samples.
|
|
1131
|
+
* entrance an overshoot tuned to a 40px slide with
|
|
1132
|
+
* `transform-origin: right center`. Do not substitute a
|
|
1133
|
+
* generic ease-out; it changes the physical read.
|
|
1134
|
+
*
|
|
1135
|
+
* These tokens do NOT opt anything out of the reduced-motion damper in
|
|
1136
|
+
* `packages/app/src/styles/global.css`, which clamps every duration to
|
|
1137
|
+
* 0.01ms under `prefers-reduced-motion: reduce`. Indefinite animations
|
|
1138
|
+
* still need their own `@media (prefers-reduced-motion: no-preference)`
|
|
1139
|
+
* guard, and the `animation` shorthand must stay INSIDE that guard
|
|
1140
|
+
* with its keyframes.
|
|
1141
|
+
*/
|
|
1142
|
+
--duration-instant: 80ms;
|
|
1143
|
+
--duration-fast: 120ms;
|
|
1144
|
+
--duration-base: 150ms;
|
|
1145
|
+
--duration-slow: 200ms;
|
|
1146
|
+
--duration-entrance: 320ms;
|
|
1147
|
+
|
|
1148
|
+
--ease-standard: ease;
|
|
1149
|
+
--ease-emphasis: ease-in-out;
|
|
1150
|
+
--ease-linear: linear;
|
|
1151
|
+
--ease-entrance: cubic-bezier(0.22, 1, 0.36, 1);
|
|
124
1152
|
}
|
|
125
1153
|
|
|
126
1154
|
@media (pointer: coarse) {
|
|
127
1155
|
:root {
|
|
1156
|
+
--font-size-2xs: 11px;
|
|
128
1157
|
--font-size-xs: 12px;
|
|
129
1158
|
--font-size-sm: 13px;
|
|
130
1159
|
--font-size-base: 15px;
|
|
131
1160
|
--font-size-lg: 17px;
|
|
1161
|
+
|
|
1162
|
+
/* The step a raw size prop cannot have. A Fab already grows its own box
|
|
1163
|
+
40 -> 48 here; without this its glyph stayed behind. */
|
|
1164
|
+
--icon-size-control: 15px;
|
|
1165
|
+
--icon-size-standalone: 24px;
|
|
132
1166
|
}
|
|
133
1167
|
}
|