@axiapps/axi-design 1.21.0 → 1.23.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -0
- package/dist/axi.css +109 -8
- package/docs/RULES.md +24 -0
- package/package.json +1 -1
- package/src/data.css +9 -4
- package/src/primitives.css +37 -1
- package/src/shells.css +7 -3
- package/src/utilities.css +54 -0
package/README.md
CHANGED
|
@@ -139,6 +139,7 @@ not "what does the system look like". Everything else is
|
|
|
139
139
|
| `--axi-check-fill` | the fill a checked `.axi-check` takes, and the colour of a checked `.axi-radio`'s diamond | `var(--axi-accent)` | `<input type="checkbox" class="axi-check" style="--axi-check-fill: var(--axi-danger)">` |
|
|
140
140
|
| `--axi-textarea-h` | the minimum height of a `<textarea class="axi-input">` | `90px` | `<textarea class="axi-input" style="--axi-textarea-h: 200px">` |
|
|
141
141
|
| `--axi-well-pad` | the padding inside an `.axi-well` | `10px` | `<div class="axi-well" style="--axi-well-pad: 18px">` |
|
|
142
|
+
| `--axi-well-radius` | an `.axi-well`'s corner radius, for a well used at reading scale rather than page scale | `var(--axi-radius)` | `<div class="axi-well" style="--axi-well-radius: var(--axi-radius-sm)">` |
|
|
142
143
|
| `--axi-rail-w` | an `.axi-rail`'s width, for labels longer than the default holds | `208px` | `<aside class="axi-rail" style="--axi-rail-w: 260px">` |
|
|
143
144
|
| `--axi-rail-pad` | the padding inside an `.axi-rail` | `10px` | `<aside class="axi-rail" style="--axi-rail-pad: 6px">` |
|
|
144
145
|
| `--axi-avatar-size` | the size of an `.axi-avatar` square | `40px` | `<span class="axi-avatar" style="--axi-avatar-size: 28px">MS</span>` |
|
package/dist/axi.css
CHANGED
|
@@ -304,6 +304,36 @@ a { color: inherit; }
|
|
|
304
304
|
on the other surface that needs it. */
|
|
305
305
|
.axi-panel--float { background: var(--axi-surface-float); }
|
|
306
306
|
|
|
307
|
+
/* A panel that stands in a grid of its own kind rather than alone on the page.
|
|
308
|
+
Same surface, one form step down: the control border and the control block,
|
|
309
|
+
so a row of six tiles does not read as six page regions arguing with the
|
|
310
|
+
page that holds them.
|
|
311
|
+
|
|
312
|
+
This is the form ramp doing work a hue would otherwise be asked to do. A
|
|
313
|
+
tile beside a tile is level; a tile beside a plain .axi-panel is outranked -
|
|
314
|
+
which is how a grid of readings says "this one is first" without spending
|
|
315
|
+
the accent on it, and the accent is not available for that anyway (it means
|
|
316
|
+
the thing you picked, and nobody picks a winner, the data does).
|
|
317
|
+
|
|
318
|
+
Padding reads the panel's own knob so a consumer overriding --axi-panel-pad
|
|
319
|
+
does not have to know which of the two it is looking at, at the tighter
|
|
320
|
+
figure a tile wants. */
|
|
321
|
+
.axi-panel--tile {
|
|
322
|
+
border-width: var(--axi-border-control);
|
|
323
|
+
box-shadow: var(--axi-shadow-control);
|
|
324
|
+
padding: var(--axi-panel-pad, 12px);
|
|
325
|
+
}
|
|
326
|
+
/* A tile you can press moves under the press, the way every other control in
|
|
327
|
+
the language does. Keyed off what the tile already is rather than a second
|
|
328
|
+
class: a tile that is a button, a link, or a div wearing the button role has
|
|
329
|
+
said so once, and should not have to say it again for the shadow. The role
|
|
330
|
+
selector is there because it is what a pressable div in real markup actually
|
|
331
|
+
carries - the alternative is a consumer with a keyboard handler and no
|
|
332
|
+
hover, which is the worse half of the bargain. */
|
|
333
|
+
a.axi-panel--tile:hover,
|
|
334
|
+
button.axi-panel--tile:hover,
|
|
335
|
+
.axi-panel--tile[role='button']:hover { box-shadow: var(--axi-shadow-control-hover); }
|
|
336
|
+
|
|
307
337
|
/* ---------- well ---------- */
|
|
308
338
|
/* The panel's inverse: a field sunk into the surface around it rather than
|
|
309
339
|
raised off it. No block, because a recess casts nothing, and the rule rather
|
|
@@ -314,7 +344,13 @@ a { color: inherit; }
|
|
|
314
344
|
.axi-well {
|
|
315
345
|
background: var(--axi-well-fill);
|
|
316
346
|
border: var(--axi-border-control) solid var(--axi-well-line);
|
|
317
|
-
|
|
347
|
+
/* A knob rather than a fixed radius, unlike the panel's, because a well is
|
|
348
|
+
the one form in the language that is used at two scales: a field the size
|
|
349
|
+
of a page column, and a recess the size of a single reading. At reading
|
|
350
|
+
scale the large radius is the wrong one - it is the radius everything else
|
|
351
|
+
that small already declines - so those instances say --axi-radius-sm here
|
|
352
|
+
rather than reaching for a modifier or a second class. */
|
|
353
|
+
border-radius: var(--axi-well-radius, var(--axi-radius));
|
|
318
354
|
/* Tighter than a panel's 26px: a well is a container for objects that carry
|
|
319
355
|
their own padding, not a page margin. */
|
|
320
356
|
padding: var(--axi-well-pad, 10px);
|
|
@@ -1183,7 +1219,11 @@ textarea.axi-input {
|
|
|
1183
1219
|
font-size: 14px; font-weight: 900;
|
|
1184
1220
|
border: var(--axi-border-control) solid var(--axi-ink-line);
|
|
1185
1221
|
}
|
|
1186
|
-
|
|
1222
|
+
/* :where() around the element, here and on the card's and the quote's copy,
|
|
1223
|
+
for the reason spelled out over `.axi-table :where(thead th)` in data.css: a
|
|
1224
|
+
slot that holds a consumer's words must not out-rank the ink the consumer
|
|
1225
|
+
puts on them. */
|
|
1226
|
+
.axi-notice :where(p) { margin: 0; font: var(--axi-t-small); color: var(--axi-text-dim); }
|
|
1187
1227
|
.axi-notice b { color: var(--axi-accent); font-weight: 800; }
|
|
1188
1228
|
|
|
1189
1229
|
/* ---------- toolbar ---------- */
|
|
@@ -1452,7 +1492,7 @@ textarea.axi-input {
|
|
|
1452
1492
|
color: var(--axi-text-faint);
|
|
1453
1493
|
letter-spacing: .08em; text-transform: uppercase;
|
|
1454
1494
|
}
|
|
1455
|
-
.axi-card p { margin: 0; font: var(--axi-t-small); color: var(--axi-text-dim); }
|
|
1495
|
+
.axi-card :where(p) { margin: 0; font: var(--axi-t-small); color: var(--axi-text-dim); }
|
|
1456
1496
|
/* Pushed to the bottom so that in an equalised grid row every card's meta
|
|
1457
1497
|
strip lands on the same line and the rules read as continuous across the
|
|
1458
1498
|
grid. The cost is empty space on cards with less content. */
|
|
@@ -1515,7 +1555,7 @@ textarea.axi-input {
|
|
|
1515
1555
|
background: var(--axi-ground);
|
|
1516
1556
|
border-radius: 0 var(--axi-radius-sm) var(--axi-radius-sm) 0;
|
|
1517
1557
|
}
|
|
1518
|
-
.axi-quote p { margin: 0; font-size: 13px; font-style: italic; color: var(--axi-text-dim); line-height: 1.5; }
|
|
1558
|
+
.axi-quote :where(p) { margin: 0; font-size: 13px; font-style: italic; color: var(--axi-text-dim); line-height: 1.5; }
|
|
1519
1559
|
.axi-quote cite {
|
|
1520
1560
|
display: block; margin-top: 7px;
|
|
1521
1561
|
font-style: normal; font-size: 11.5px; font-weight: 700;
|
|
@@ -1845,8 +1885,14 @@ textarea.axi-input {
|
|
|
1845
1885
|
/* `thead th`, not `th`. A row's name is a `<th scope="row">` - that is what
|
|
1846
1886
|
tells a screen reader which cell labels the row - and it is a name, not a
|
|
1847
1887
|
column heading: uppercase micro type down the first column would shout every
|
|
1848
|
-
row's label at the reader. A row header takes the cell treatment below.
|
|
1849
|
-
|
|
1888
|
+
row's label at the reader. A row header takes the cell treatment below.
|
|
1889
|
+
|
|
1890
|
+
The element part is wrapped in :where() so this rule weighs one class, not a
|
|
1891
|
+
class and a type. A base rule that out-ranks the component's own modifiers is
|
|
1892
|
+
a base rule nothing can correct: at (0,1,1) this beat `.axi-table__num` and
|
|
1893
|
+
every ink class a consumer could put on a cell, so the column that carries
|
|
1894
|
+
the measured value was silently still the dim one. */
|
|
1895
|
+
.axi-table :where(thead th) {
|
|
1850
1896
|
padding: 0 10px 10px;
|
|
1851
1897
|
font: var(--axi-t-micro);
|
|
1852
1898
|
letter-spacing: var(--axi-ls-micro);
|
|
@@ -1854,8 +1900,7 @@ textarea.axi-input {
|
|
|
1854
1900
|
color: var(--axi-text-faint);
|
|
1855
1901
|
border-bottom: var(--axi-border-control) solid var(--axi-rule);
|
|
1856
1902
|
}
|
|
1857
|
-
.axi-table td,
|
|
1858
|
-
.axi-table tbody th {
|
|
1903
|
+
.axi-table :where(td, tbody th) {
|
|
1859
1904
|
padding: 9px 10px;
|
|
1860
1905
|
font: var(--axi-t-small);
|
|
1861
1906
|
font-weight: 700;
|
|
@@ -2311,3 +2356,59 @@ textarea.axi-input {
|
|
|
2311
2356
|
}
|
|
2312
2357
|
|
|
2313
2358
|
.axi-prose img { max-width: 100%; height: auto; border-radius: var(--axi-radius-sm); }
|
|
2359
|
+
|
|
2360
|
+
/* --- utilities.css --- */
|
|
2361
|
+
/* axi design language - utilities.
|
|
2362
|
+
Two families of single-purpose class, and the file is last in the cascade
|
|
2363
|
+
because that is the whole point of it: a utility has to be able to overrule
|
|
2364
|
+
the component it sits inside, and it is not allowed to buy that with
|
|
2365
|
+
!important or with a padded selector.
|
|
2366
|
+
|
|
2367
|
+
Why the language needs them at all. Rules 5 and 6 draw a distinction the
|
|
2368
|
+
reader is expected to make at a glance - a filled status against a cool ink
|
|
2369
|
+
that is commentary - and until now the only way to say either was to be a
|
|
2370
|
+
component that said it for you. Real markup is full of places that are not
|
|
2371
|
+
components: a number in a sentence, a word in a legend, a value beside a
|
|
2372
|
+
label. An app with no way to say "this reading is bad" in those places will
|
|
2373
|
+
reach for a colour literal, and at that moment the theme stops reaching it.
|
|
2374
|
+
So the language names the meanings, and the app spends them by name.
|
|
2375
|
+
|
|
2376
|
+
What they deliberately are not. An ink sets colour and nothing else - no
|
|
2377
|
+
size, no weight, no spacing, no surface - and an edge sets border-colour
|
|
2378
|
+
without asserting that there is a border. Neither is a shorthand for a
|
|
2379
|
+
component: a status that belongs to a whole object still wants the chip or
|
|
2380
|
+
the cap that rule 5 describes, because an object's verdict should be a shape
|
|
2381
|
+
the eye finds, not a recoloured word inside it. These are for the marks
|
|
2382
|
+
inside those shapes.
|
|
2383
|
+
|
|
2384
|
+
And there is no fill family. Under rule 2 colour at partial opacity over the
|
|
2385
|
+
ground is not available, and an opaque status fill behind arbitrary text is a
|
|
2386
|
+
chip - which the language already ships. A surface stays a surface token. */
|
|
2387
|
+
|
|
2388
|
+
/* The five meanings. Ordered as rule 5 orders them: the three statuses, then
|
|
2389
|
+
the cool ink that is not a status, then the accent - which means "the thing
|
|
2390
|
+
you picked" and never "good". */
|
|
2391
|
+
.axi-ink-ok { color: var(--axi-ok); }
|
|
2392
|
+
.axi-ink-warn { color: var(--axi-warn); }
|
|
2393
|
+
.axi-ink-danger { color: var(--axi-danger); }
|
|
2394
|
+
.axi-ink-meta { color: var(--axi-meta); }
|
|
2395
|
+
.axi-ink-accent { color: var(--axi-accent); }
|
|
2396
|
+
|
|
2397
|
+
/* The three neutral steps. `plain` rather than `text` so that reading the class
|
|
2398
|
+
list does not suggest it does something to the text other than ink it, and so
|
|
2399
|
+
the three read as one scale. */
|
|
2400
|
+
.axi-ink-plain { color: var(--axi-text); }
|
|
2401
|
+
.axi-ink-dim { color: var(--axi-text-dim); }
|
|
2402
|
+
.axi-ink-faint { color: var(--axi-text-faint); }
|
|
2403
|
+
|
|
2404
|
+
/* Edges. `rule` and `line` are the two neutral weights of meaning, not of
|
|
2405
|
+
width: --axi-rule is the quiet separator inside a surface, --axi-ink-line the
|
|
2406
|
+
full ink a raised thing is outlined in. Width stays with whoever drew the
|
|
2407
|
+
border. */
|
|
2408
|
+
.axi-edge-ok { border-color: var(--axi-ok); }
|
|
2409
|
+
.axi-edge-warn { border-color: var(--axi-warn); }
|
|
2410
|
+
.axi-edge-danger { border-color: var(--axi-danger); }
|
|
2411
|
+
.axi-edge-meta { border-color: var(--axi-meta); }
|
|
2412
|
+
.axi-edge-accent { border-color: var(--axi-accent); }
|
|
2413
|
+
.axi-edge-rule { border-color: var(--axi-rule); }
|
|
2414
|
+
.axi-edge-line { border-color: var(--axi-ink-line); }
|
package/docs/RULES.md
CHANGED
|
@@ -243,6 +243,30 @@ see is a slug floating in the card.
|
|
|
243
243
|
meaning. It is the only ink guaranteed not to mean "how bad is this" — which is
|
|
244
244
|
what makes it readable as commentary at a glance.
|
|
245
245
|
|
|
246
|
+
### Saying a meaning outside a component
|
|
247
|
+
|
|
248
|
+
Rules 5 and 6 are about marks, not only about components. A number inside a
|
|
249
|
+
sentence, a word in a legend, a value beside its label — each of these can be a
|
|
250
|
+
status or can be commentary, and a reader is entitled to see which. So the five
|
|
251
|
+
meanings are available as inks: `.axi-ink-ok`, `.axi-ink-warn`,
|
|
252
|
+
`.axi-ink-danger`, `.axi-ink-meta`, `.axi-ink-accent`, with the three neutral
|
|
253
|
+
steps as `.axi-ink-plain`, `.axi-ink-dim` and `.axi-ink-faint`, and the same
|
|
254
|
+
list again as `.axi-edge-*` for a border's colour.
|
|
255
|
+
|
|
256
|
+
An ink colours a mark. It is not a way to skip the chip or the status cap, which
|
|
257
|
+
are what rule 5 asks for when the verdict belongs to a whole object: a shape the
|
|
258
|
+
eye finds beats a recoloured word inside a paragraph. Reach for an ink when
|
|
259
|
+
there is no object, only a mark.
|
|
260
|
+
|
|
261
|
+
They live in `src/utilities.css`, last in the cascade, which is how a single
|
|
262
|
+
class overrules the component it sits inside without `!important`. That places
|
|
263
|
+
an obligation on components in the other direction: **a component's base rules
|
|
264
|
+
may not out-rank its own modifiers.** A rule written `.axi-table td` weighs a
|
|
265
|
+
class and a type, so it silently defeats both `.axi-table__num` and any ink a
|
|
266
|
+
consumer puts on the cell — the fix is `:where()` around the element, which
|
|
267
|
+
spends no specificity. Where a component holds a consumer's content, wrap the
|
|
268
|
+
element part.
|
|
269
|
+
|
|
246
270
|
## 7. The diamond is the family motif
|
|
247
271
|
|
|
248
272
|
A 45°-rotated outlined square. Bullet, status dot, language marker, and scaled
|
package/package.json
CHANGED
package/src/data.css
CHANGED
|
@@ -67,8 +67,14 @@
|
|
|
67
67
|
/* `thead th`, not `th`. A row's name is a `<th scope="row">` - that is what
|
|
68
68
|
tells a screen reader which cell labels the row - and it is a name, not a
|
|
69
69
|
column heading: uppercase micro type down the first column would shout every
|
|
70
|
-
row's label at the reader. A row header takes the cell treatment below.
|
|
71
|
-
|
|
70
|
+
row's label at the reader. A row header takes the cell treatment below.
|
|
71
|
+
|
|
72
|
+
The element part is wrapped in :where() so this rule weighs one class, not a
|
|
73
|
+
class and a type. A base rule that out-ranks the component's own modifiers is
|
|
74
|
+
a base rule nothing can correct: at (0,1,1) this beat `.axi-table__num` and
|
|
75
|
+
every ink class a consumer could put on a cell, so the column that carries
|
|
76
|
+
the measured value was silently still the dim one. */
|
|
77
|
+
.axi-table :where(thead th) {
|
|
72
78
|
padding: 0 10px 10px;
|
|
73
79
|
font: var(--axi-t-micro);
|
|
74
80
|
letter-spacing: var(--axi-ls-micro);
|
|
@@ -76,8 +82,7 @@
|
|
|
76
82
|
color: var(--axi-text-faint);
|
|
77
83
|
border-bottom: var(--axi-border-control) solid var(--axi-rule);
|
|
78
84
|
}
|
|
79
|
-
.axi-table td,
|
|
80
|
-
.axi-table tbody th {
|
|
85
|
+
.axi-table :where(td, tbody th) {
|
|
81
86
|
padding: 9px 10px;
|
|
82
87
|
font: var(--axi-t-small);
|
|
83
88
|
font-weight: 700;
|
package/src/primitives.css
CHANGED
|
@@ -38,6 +38,36 @@
|
|
|
38
38
|
on the other surface that needs it. */
|
|
39
39
|
.axi-panel--float { background: var(--axi-surface-float); }
|
|
40
40
|
|
|
41
|
+
/* A panel that stands in a grid of its own kind rather than alone on the page.
|
|
42
|
+
Same surface, one form step down: the control border and the control block,
|
|
43
|
+
so a row of six tiles does not read as six page regions arguing with the
|
|
44
|
+
page that holds them.
|
|
45
|
+
|
|
46
|
+
This is the form ramp doing work a hue would otherwise be asked to do. A
|
|
47
|
+
tile beside a tile is level; a tile beside a plain .axi-panel is outranked -
|
|
48
|
+
which is how a grid of readings says "this one is first" without spending
|
|
49
|
+
the accent on it, and the accent is not available for that anyway (it means
|
|
50
|
+
the thing you picked, and nobody picks a winner, the data does).
|
|
51
|
+
|
|
52
|
+
Padding reads the panel's own knob so a consumer overriding --axi-panel-pad
|
|
53
|
+
does not have to know which of the two it is looking at, at the tighter
|
|
54
|
+
figure a tile wants. */
|
|
55
|
+
.axi-panel--tile {
|
|
56
|
+
border-width: var(--axi-border-control);
|
|
57
|
+
box-shadow: var(--axi-shadow-control);
|
|
58
|
+
padding: var(--axi-panel-pad, 12px);
|
|
59
|
+
}
|
|
60
|
+
/* A tile you can press moves under the press, the way every other control in
|
|
61
|
+
the language does. Keyed off what the tile already is rather than a second
|
|
62
|
+
class: a tile that is a button, a link, or a div wearing the button role has
|
|
63
|
+
said so once, and should not have to say it again for the shadow. The role
|
|
64
|
+
selector is there because it is what a pressable div in real markup actually
|
|
65
|
+
carries - the alternative is a consumer with a keyboard handler and no
|
|
66
|
+
hover, which is the worse half of the bargain. */
|
|
67
|
+
a.axi-panel--tile:hover,
|
|
68
|
+
button.axi-panel--tile:hover,
|
|
69
|
+
.axi-panel--tile[role='button']:hover { box-shadow: var(--axi-shadow-control-hover); }
|
|
70
|
+
|
|
41
71
|
/* ---------- well ---------- */
|
|
42
72
|
/* The panel's inverse: a field sunk into the surface around it rather than
|
|
43
73
|
raised off it. No block, because a recess casts nothing, and the rule rather
|
|
@@ -48,7 +78,13 @@
|
|
|
48
78
|
.axi-well {
|
|
49
79
|
background: var(--axi-well-fill);
|
|
50
80
|
border: var(--axi-border-control) solid var(--axi-well-line);
|
|
51
|
-
|
|
81
|
+
/* A knob rather than a fixed radius, unlike the panel's, because a well is
|
|
82
|
+
the one form in the language that is used at two scales: a field the size
|
|
83
|
+
of a page column, and a recess the size of a single reading. At reading
|
|
84
|
+
scale the large radius is the wrong one - it is the radius everything else
|
|
85
|
+
that small already declines - so those instances say --axi-radius-sm here
|
|
86
|
+
rather than reaching for a modifier or a second class. */
|
|
87
|
+
border-radius: var(--axi-well-radius, var(--axi-radius));
|
|
52
88
|
/* Tighter than a panel's 26px: a well is a container for objects that carry
|
|
53
89
|
their own padding, not a page margin. */
|
|
54
90
|
padding: var(--axi-well-pad, 10px);
|
package/src/shells.css
CHANGED
|
@@ -264,7 +264,11 @@
|
|
|
264
264
|
font-size: 14px; font-weight: 900;
|
|
265
265
|
border: var(--axi-border-control) solid var(--axi-ink-line);
|
|
266
266
|
}
|
|
267
|
-
|
|
267
|
+
/* :where() around the element, here and on the card's and the quote's copy,
|
|
268
|
+
for the reason spelled out over `.axi-table :where(thead th)` in data.css: a
|
|
269
|
+
slot that holds a consumer's words must not out-rank the ink the consumer
|
|
270
|
+
puts on them. */
|
|
271
|
+
.axi-notice :where(p) { margin: 0; font: var(--axi-t-small); color: var(--axi-text-dim); }
|
|
268
272
|
.axi-notice b { color: var(--axi-accent); font-weight: 800; }
|
|
269
273
|
|
|
270
274
|
/* ---------- toolbar ---------- */
|
|
@@ -533,7 +537,7 @@
|
|
|
533
537
|
color: var(--axi-text-faint);
|
|
534
538
|
letter-spacing: .08em; text-transform: uppercase;
|
|
535
539
|
}
|
|
536
|
-
.axi-card p { margin: 0; font: var(--axi-t-small); color: var(--axi-text-dim); }
|
|
540
|
+
.axi-card :where(p) { margin: 0; font: var(--axi-t-small); color: var(--axi-text-dim); }
|
|
537
541
|
/* Pushed to the bottom so that in an equalised grid row every card's meta
|
|
538
542
|
strip lands on the same line and the rules read as continuous across the
|
|
539
543
|
grid. The cost is empty space on cards with less content. */
|
|
@@ -596,7 +600,7 @@
|
|
|
596
600
|
background: var(--axi-ground);
|
|
597
601
|
border-radius: 0 var(--axi-radius-sm) var(--axi-radius-sm) 0;
|
|
598
602
|
}
|
|
599
|
-
.axi-quote p { margin: 0; font-size: 13px; font-style: italic; color: var(--axi-text-dim); line-height: 1.5; }
|
|
603
|
+
.axi-quote :where(p) { margin: 0; font-size: 13px; font-style: italic; color: var(--axi-text-dim); line-height: 1.5; }
|
|
600
604
|
.axi-quote cite {
|
|
601
605
|
display: block; margin-top: 7px;
|
|
602
606
|
font-style: normal; font-size: 11.5px; font-weight: 700;
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/* axi design language - utilities.
|
|
2
|
+
Two families of single-purpose class, and the file is last in the cascade
|
|
3
|
+
because that is the whole point of it: a utility has to be able to overrule
|
|
4
|
+
the component it sits inside, and it is not allowed to buy that with
|
|
5
|
+
!important or with a padded selector.
|
|
6
|
+
|
|
7
|
+
Why the language needs them at all. Rules 5 and 6 draw a distinction the
|
|
8
|
+
reader is expected to make at a glance - a filled status against a cool ink
|
|
9
|
+
that is commentary - and until now the only way to say either was to be a
|
|
10
|
+
component that said it for you. Real markup is full of places that are not
|
|
11
|
+
components: a number in a sentence, a word in a legend, a value beside a
|
|
12
|
+
label. An app with no way to say "this reading is bad" in those places will
|
|
13
|
+
reach for a colour literal, and at that moment the theme stops reaching it.
|
|
14
|
+
So the language names the meanings, and the app spends them by name.
|
|
15
|
+
|
|
16
|
+
What they deliberately are not. An ink sets colour and nothing else - no
|
|
17
|
+
size, no weight, no spacing, no surface - and an edge sets border-colour
|
|
18
|
+
without asserting that there is a border. Neither is a shorthand for a
|
|
19
|
+
component: a status that belongs to a whole object still wants the chip or
|
|
20
|
+
the cap that rule 5 describes, because an object's verdict should be a shape
|
|
21
|
+
the eye finds, not a recoloured word inside it. These are for the marks
|
|
22
|
+
inside those shapes.
|
|
23
|
+
|
|
24
|
+
And there is no fill family. Under rule 2 colour at partial opacity over the
|
|
25
|
+
ground is not available, and an opaque status fill behind arbitrary text is a
|
|
26
|
+
chip - which the language already ships. A surface stays a surface token. */
|
|
27
|
+
|
|
28
|
+
/* The five meanings. Ordered as rule 5 orders them: the three statuses, then
|
|
29
|
+
the cool ink that is not a status, then the accent - which means "the thing
|
|
30
|
+
you picked" and never "good". */
|
|
31
|
+
.axi-ink-ok { color: var(--axi-ok); }
|
|
32
|
+
.axi-ink-warn { color: var(--axi-warn); }
|
|
33
|
+
.axi-ink-danger { color: var(--axi-danger); }
|
|
34
|
+
.axi-ink-meta { color: var(--axi-meta); }
|
|
35
|
+
.axi-ink-accent { color: var(--axi-accent); }
|
|
36
|
+
|
|
37
|
+
/* The three neutral steps. `plain` rather than `text` so that reading the class
|
|
38
|
+
list does not suggest it does something to the text other than ink it, and so
|
|
39
|
+
the three read as one scale. */
|
|
40
|
+
.axi-ink-plain { color: var(--axi-text); }
|
|
41
|
+
.axi-ink-dim { color: var(--axi-text-dim); }
|
|
42
|
+
.axi-ink-faint { color: var(--axi-text-faint); }
|
|
43
|
+
|
|
44
|
+
/* Edges. `rule` and `line` are the two neutral weights of meaning, not of
|
|
45
|
+
width: --axi-rule is the quiet separator inside a surface, --axi-ink-line the
|
|
46
|
+
full ink a raised thing is outlined in. Width stays with whoever drew the
|
|
47
|
+
border. */
|
|
48
|
+
.axi-edge-ok { border-color: var(--axi-ok); }
|
|
49
|
+
.axi-edge-warn { border-color: var(--axi-warn); }
|
|
50
|
+
.axi-edge-danger { border-color: var(--axi-danger); }
|
|
51
|
+
.axi-edge-meta { border-color: var(--axi-meta); }
|
|
52
|
+
.axi-edge-accent { border-color: var(--axi-accent); }
|
|
53
|
+
.axi-edge-rule { border-color: var(--axi-rule); }
|
|
54
|
+
.axi-edge-line { border-color: var(--axi-ink-line); }
|