@axiapps/axi-design 1.17.0 → 1.18.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 CHANGED
@@ -149,6 +149,8 @@ not "what does the system look like". Everything else is
149
149
  | `--axi-stack-gap` | gap between `.axi-stack` children | `12px` | `<div class="axi-stack" style="--axi-stack-gap: 20px">` |
150
150
  | `--axi-panel-pad` | `.axi-panel`'s own padding | `26px` | `<div class="axi-panel" style="--axi-panel-pad: 14px">` |
151
151
  | `--axi-page-pad` | `.axi-page`'s horizontal gutter | `var(--axi-gutter)` | `<div class="axi-page axi-page--narrow" style="--axi-page-pad: 0">` |
152
+ | `--axi-palette-w` | the widest an `.axi-palette__panel` gets (it fills the room below that) | `560px` | `<div class="axi-palette__panel" style="--axi-palette-w: 720px">` |
153
+ | `--axi-palette-top` | how far down the screen an `.axi-palette` opens | `12vh` | `<div class="axi-scrim axi-palette" style="--axi-palette-top: 6vh">` |
152
154
  | `--axi-menu-width` | width of `.axi-menu__pop` | `310px` | `<div class="axi-menu__pop" style="--axi-menu-width: 380px">` |
153
155
  | `--axi-drawer-width` | width of `.axi-drawer` (capped at `100vw`) | `560px` | `<aside class="axi-drawer" style="--axi-drawer-width: 720px">` |
154
156
  | `--axi-series` | the ink a meter fill, bar, plot line or `.axi-diamond--series` is drawn in | `var(--axi-accent)` | `<span class="axi-meter__fill" style="--axi-series: var(--axi-ok)">` |
package/dist/axi.css CHANGED
@@ -32,6 +32,20 @@
32
32
  --axi-ground-image: none;
33
33
  --axi-surface: #222731; /* a panel raised off the page */
34
34
  --axi-surface-raised: #2b313d; /* a chip or popover raised off a panel */
35
+ /* The fill for a surface that FLOATS over content which scrolls behind it: a
36
+ command palette, a menu popover, a modal. Holds --axi-surface, because for
37
+ a theme whose panels are opaque a floating panel is just a panel and there
38
+ is nothing to decide.
39
+
40
+ It exists for the theme whose panels are not. A translucent pane is legible
41
+ standing still on the page and stops being legible the moment a table
42
+ scrolls under it - the text it is carrying now has text behind it. The blur
43
+ that was supposed to rescue that is not something a language can promise:
44
+ backdrop-filter is unavailable or switched off on whole platforms, and
45
+ where it is missing the alpha is the only thing left. So the float gets its
46
+ own token, and a theme that goes translucent restates it near-opaque
47
+ without giving up the tint on everything that merely sits still. */
48
+ --axi-surface-float: var(--axi-surface);
35
49
  --axi-ink-line: #0c0e12; /* the outline every raised element is drawn with */
36
50
  /* The tone a shape is made of when it is made of the line ink rather than
37
51
  outlined in it - the tooltip, the titlebar strip, the switch's slug. Holds
@@ -501,6 +515,27 @@ a { color: inherit; }
501
515
  color: var(--axi-accent); font-weight: 900; pointer-events: none;
502
516
  }
503
517
 
518
+ /* ---------- keyboard key ---------- */
519
+ /* A key on the keyboard, named in the interface: the Esc that closes a
520
+ palette, the Ctrl K that opens it. Drawn as a small control rather than as a
521
+ label, because what it depicts is a thing you press - so it takes the
522
+ control edge and the control radius, and every consumer that has a shortcut
523
+ to show stops having to invent a box for it.
524
+
525
+ It sits on --axi-surface, not --axi-ground: a key is raised out of whatever
526
+ it is printed on, and the fields and bars these appear in are already the
527
+ recessed thing. */
528
+ .axi-kbd {
529
+ display: inline-block;
530
+ padding: 2px 5px;
531
+ background: var(--axi-surface);
532
+ border: var(--axi-border-control) solid var(--axi-ink-line);
533
+ border-radius: var(--axi-radius-sm);
534
+ color: var(--axi-text-dim);
535
+ font: 700 10px/1 var(--axi-sans);
536
+ white-space: nowrap;
537
+ }
538
+
504
539
  /* ---------- select ---------- */
505
540
  /* The closed box is ours everywhere: strip the native control and draw the
506
541
  caret, so a select sits alongside the other controls as just another
@@ -1131,6 +1166,144 @@ textarea.axi-input {
1131
1166
  .axi-menu__pop label:hover { background: var(--axi-ground); color: var(--axi-text); }
1132
1167
  .axi-menu__pop input { margin: 3px 0 0; }
1133
1168
 
1169
+ /* ---------- command palette ---------- */
1170
+ /* Everything in an app, reachable by typing its name. Not .axi-modal, which is
1171
+ a <dialog> with a head, a body and a foot and asks you a question: a palette
1172
+ has no question and no buttons, it is a field with a list under it, and it
1173
+ sits near the top of the screen because the list has to grow downward
1174
+ without moving the field you are typing into.
1175
+
1176
+ Two things travel with it. The panel is .axi-surface-float, not
1177
+ .axi-surface: whatever the app was showing is still behind it and still
1178
+ scrolling, and that is the case the float token exists for. And the host
1179
+ element wears .axi-scrim alongside .axi-palette - the scrim already knows
1180
+ what darkening the page looks like, and a second spelling of it here is one
1181
+ more place for a theme to be restated in only one of them.
1182
+
1183
+ The cursor is not the hover. A palette is driven from the keyboard, so the
1184
+ row Enter would take is marked with the accent fill outright, while hover is
1185
+ the quieter raised-surface wash - both visible at once, saying different
1186
+ things, with the filled one winning on sight. The consumer sets
1187
+ `data-active` on the cursor row and keeps it scrolled into view. */
1188
+ .axi-palette {
1189
+ display: flex; align-items: flex-start; justify-content: center;
1190
+ padding: var(--axi-palette-top, 12vh) 16px 16px;
1191
+ }
1192
+ .axi-palette__panel {
1193
+ display: flex; flex-direction: column;
1194
+ width: 100%; max-width: var(--axi-palette-w, 560px);
1195
+ max-height: 70vh; overflow: hidden;
1196
+ background: var(--axi-surface-float);
1197
+ backdrop-filter: var(--axi-surface-filter);
1198
+ border: var(--axi-border-panel) solid var(--axi-ink-line);
1199
+ border-radius: var(--axi-radius);
1200
+ box-shadow: var(--axi-shadow-panel);
1201
+ }
1202
+ /* The bar holds the field and the filters. It is the raised surface so the
1203
+ list below it reads as the panel's contents rather than as more bar. */
1204
+ .axi-palette__bar {
1205
+ flex: none; padding: 8px 10px;
1206
+ background: var(--axi-surface-raised);
1207
+ border-bottom: var(--axi-border-control) solid var(--axi-ink-line);
1208
+ }
1209
+ /* The field is an .axi-search wrapping an .axi-input, same as anywhere else;
1210
+ only the height comes down, because a palette's field is a row in a bar and
1211
+ not a form control standing on a page. No focus ring: the palette opens with
1212
+ the caret already here, so a permanent outline says nothing, and it would
1213
+ argue with the one mark that does - the accent on the cursor row. */
1214
+ .axi-palette__bar .axi-input { padding-top: 7px; padding-bottom: 7px; font-size: 13px; }
1215
+ .axi-palette__bar .axi-input:focus-visible { outline: none; }
1216
+ .axi-palette__filters { display: flex; align-items: center; gap: 6px; margin-top: 8px; }
1217
+ /* What the list is not showing. Meta, at the end of the filter row, because it
1218
+ is a reading about the results and not another control among them. */
1219
+ .axi-palette__count {
1220
+ margin-left: auto; flex: none;
1221
+ color: var(--axi-text-faint);
1222
+ font: var(--axi-t-label); font-size: 10px; letter-spacing: var(--axi-ls-label);
1223
+ text-transform: uppercase;
1224
+ }
1225
+ /* min-height: 0 because the panel is a flex column and a list that cannot
1226
+ shrink below its content pushes the panel past its own max-height. The
1227
+ scrollbar is hidden: at twelve rows behind a fixed cap the bar is a channel
1228
+ carved down the side of a small panel to report a fact the row count in the
1229
+ bar has already given. */
1230
+ .axi-palette__list {
1231
+ flex: 1; min-height: 0; overflow-y: auto; padding: 4px 0;
1232
+ scrollbar-width: none;
1233
+ }
1234
+ .axi-palette__list::-webkit-scrollbar { width: 0; height: 0; }
1235
+ /* One .axi-palette__section per group of rows, each opening with a
1236
+ .axi-palette__group heading. The section is a named part rather than left to
1237
+ the consumer's wrapper so the rule between groups can be stated as what it
1238
+ is - a parting between two sections - instead of guessed at from structure. */
1239
+ .axi-palette__section + .axi-palette__section {
1240
+ border-top: var(--axi-border-hairline) solid var(--axi-rule);
1241
+ margin-top: 4px;
1242
+ }
1243
+ .axi-palette__group {
1244
+ padding: 8px 10px 4px;
1245
+ color: var(--axi-text-faint);
1246
+ font: var(--axi-t-label); font-size: 10px; letter-spacing: var(--axi-ls-label);
1247
+ text-transform: uppercase;
1248
+ }
1249
+ .axi-palette__row {
1250
+ display: flex; align-items: center; gap: 8px;
1251
+ width: 100%; padding: 7px 10px;
1252
+ background: transparent; border: 0; border-radius: 0;
1253
+ color: var(--axi-text-dim);
1254
+ font: var(--axi-t-small); text-align: left; cursor: pointer;
1255
+ }
1256
+ .axi-palette__row:hover { background: var(--axi-surface-raised); color: var(--axi-text); }
1257
+ .axi-palette__row[data-active] { background: var(--axi-accent); color: var(--axi-accent-ink); }
1258
+ /* The row's own ink is set above, but a row carries a glyph and a second line
1259
+ of text that were coloured on their own; on the filled row they all become
1260
+ the ink the fill is written in. */
1261
+ .axi-palette__row[data-active] svg,
1262
+ .axi-palette__row[data-active] .axi-palette__meta { color: var(--axi-accent-ink); }
1263
+ /* Where the row is, as against what it is. */
1264
+ .axi-palette__meta { margin-left: auto; flex: none; color: var(--axi-text-faint); font-size: 11px; }
1265
+ .axi-palette__empty {
1266
+ padding: 24px 12px; text-align: center;
1267
+ color: var(--axi-text-faint); font: var(--axi-t-small);
1268
+ }
1269
+ /* The palette's field at rest, wherever the app keeps the way in. It is a
1270
+ button, and it is drawn as the field it opens - the same ground, the same
1271
+ edge, the same magnifier at the head - so opening the palette reads as this
1272
+ control growing rather than as a different object arriving.
1273
+
1274
+ It keeps the field's fill instead of a button's because what it stands for
1275
+ is somewhere to type. What it takes from a button is the answer to the
1276
+ cursor: the block and the lift, because it is still a thing you press. */
1277
+ .axi-palette__trigger {
1278
+ display: flex; align-items: center; width: 100%; overflow: hidden;
1279
+ padding: 0 10px 0 0;
1280
+ background: var(--axi-ground);
1281
+ border: var(--axi-border-control) solid var(--axi-ink-line);
1282
+ border-radius: var(--axi-radius-sm);
1283
+ color: var(--axi-text-dim);
1284
+ font: var(--axi-t-label); font-size: 12px; font-weight: 600;
1285
+ cursor: pointer;
1286
+ transition: transform .1s, box-shadow .1s, color .1s;
1287
+ }
1288
+ .axi-palette__trigger:hover {
1289
+ color: var(--axi-text);
1290
+ box-shadow: var(--axi-shadow-control);
1291
+ transform: translate(-2px, -2px);
1292
+ }
1293
+ /* The magnifier at the head of the well, carrying the accent on its own. Its
1294
+ own element and stretched to the trigger's height so the glyph is inside the
1295
+ outline rather than floating in the fill. It was a solid accent block once,
1296
+ which at a 30px row spends a lot of the loudest colour in the palette on a
1297
+ control nobody is meant to look at until they want it - the glyph says the
1298
+ same thing at a fraction of the volume. */
1299
+ .axi-palette__mark {
1300
+ display: flex; align-items: center; align-self: stretch; flex: none;
1301
+ padding: 0 8px 0 10px; margin-right: 10px;
1302
+ color: var(--axi-accent);
1303
+ }
1304
+ .axi-palette__label { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
1305
+ .axi-palette__trigger .axi-kbd { margin-left: auto; flex: none; }
1306
+
1134
1307
  /* ---------- tooltip ---------- */
1135
1308
  /* One line of ink on the darkest surface in the language, so it reads over
1136
1309
  anything it lands on. The class draws the box only; coordinates come from
@@ -6,6 +6,7 @@
6
6
  --axi-ground-image: radial-gradient(900px 500px at 15% 0%, rgba(120, 90, 255, .30), transparent 60%), radial-gradient(700px 500px at 95% 30%, rgba(0, 190, 255, .22), transparent 62%), radial-gradient(600px 600px at 60% 100%, rgba(255, 90, 170, .20), transparent 60%);
7
7
  --axi-surface: linear-gradient(145deg, rgba(58, 68, 92, .55), rgba(28, 33, 46, .42));
8
8
  --axi-surface-raised: linear-gradient(145deg, rgba(86, 99, 130, .5), rgba(44, 52, 71, .38));
9
+ --axi-surface-float: linear-gradient(145deg, rgba(38, 45, 62, .97), rgba(22, 26, 36, .97));
9
10
  --axi-surface-filter: blur(18px) saturate(140%);
10
11
  --axi-ink-line: rgba(180, 200, 255, .16);
11
12
  --axi-rule: rgba(180, 200, 255, .14);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@axiapps/axi-design",
3
- "version": "1.17.0",
3
+ "version": "1.18.0",
4
4
  "description": "The design language for the axi suite — flat and outlined, dark, drawn in saturated ink.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -257,6 +257,27 @@
257
257
  color: var(--axi-accent); font-weight: 900; pointer-events: none;
258
258
  }
259
259
 
260
+ /* ---------- keyboard key ---------- */
261
+ /* A key on the keyboard, named in the interface: the Esc that closes a
262
+ palette, the Ctrl K that opens it. Drawn as a small control rather than as a
263
+ label, because what it depicts is a thing you press - so it takes the
264
+ control edge and the control radius, and every consumer that has a shortcut
265
+ to show stops having to invent a box for it.
266
+
267
+ It sits on --axi-surface, not --axi-ground: a key is raised out of whatever
268
+ it is printed on, and the fields and bars these appear in are already the
269
+ recessed thing. */
270
+ .axi-kbd {
271
+ display: inline-block;
272
+ padding: 2px 5px;
273
+ background: var(--axi-surface);
274
+ border: var(--axi-border-control) solid var(--axi-ink-line);
275
+ border-radius: var(--axi-radius-sm);
276
+ color: var(--axi-text-dim);
277
+ font: 700 10px/1 var(--axi-sans);
278
+ white-space: nowrap;
279
+ }
280
+
260
281
  /* ---------- select ---------- */
261
282
  /* The closed box is ours everywhere: strip the native control and draw the
262
283
  caret, so a select sits alongside the other controls as just another
package/src/shells.css CHANGED
@@ -267,6 +267,144 @@
267
267
  .axi-menu__pop label:hover { background: var(--axi-ground); color: var(--axi-text); }
268
268
  .axi-menu__pop input { margin: 3px 0 0; }
269
269
 
270
+ /* ---------- command palette ---------- */
271
+ /* Everything in an app, reachable by typing its name. Not .axi-modal, which is
272
+ a <dialog> with a head, a body and a foot and asks you a question: a palette
273
+ has no question and no buttons, it is a field with a list under it, and it
274
+ sits near the top of the screen because the list has to grow downward
275
+ without moving the field you are typing into.
276
+
277
+ Two things travel with it. The panel is .axi-surface-float, not
278
+ .axi-surface: whatever the app was showing is still behind it and still
279
+ scrolling, and that is the case the float token exists for. And the host
280
+ element wears .axi-scrim alongside .axi-palette - the scrim already knows
281
+ what darkening the page looks like, and a second spelling of it here is one
282
+ more place for a theme to be restated in only one of them.
283
+
284
+ The cursor is not the hover. A palette is driven from the keyboard, so the
285
+ row Enter would take is marked with the accent fill outright, while hover is
286
+ the quieter raised-surface wash - both visible at once, saying different
287
+ things, with the filled one winning on sight. The consumer sets
288
+ `data-active` on the cursor row and keeps it scrolled into view. */
289
+ .axi-palette {
290
+ display: flex; align-items: flex-start; justify-content: center;
291
+ padding: var(--axi-palette-top, 12vh) 16px 16px;
292
+ }
293
+ .axi-palette__panel {
294
+ display: flex; flex-direction: column;
295
+ width: 100%; max-width: var(--axi-palette-w, 560px);
296
+ max-height: 70vh; overflow: hidden;
297
+ background: var(--axi-surface-float);
298
+ backdrop-filter: var(--axi-surface-filter);
299
+ border: var(--axi-border-panel) solid var(--axi-ink-line);
300
+ border-radius: var(--axi-radius);
301
+ box-shadow: var(--axi-shadow-panel);
302
+ }
303
+ /* The bar holds the field and the filters. It is the raised surface so the
304
+ list below it reads as the panel's contents rather than as more bar. */
305
+ .axi-palette__bar {
306
+ flex: none; padding: 8px 10px;
307
+ background: var(--axi-surface-raised);
308
+ border-bottom: var(--axi-border-control) solid var(--axi-ink-line);
309
+ }
310
+ /* The field is an .axi-search wrapping an .axi-input, same as anywhere else;
311
+ only the height comes down, because a palette's field is a row in a bar and
312
+ not a form control standing on a page. No focus ring: the palette opens with
313
+ the caret already here, so a permanent outline says nothing, and it would
314
+ argue with the one mark that does - the accent on the cursor row. */
315
+ .axi-palette__bar .axi-input { padding-top: 7px; padding-bottom: 7px; font-size: 13px; }
316
+ .axi-palette__bar .axi-input:focus-visible { outline: none; }
317
+ .axi-palette__filters { display: flex; align-items: center; gap: 6px; margin-top: 8px; }
318
+ /* What the list is not showing. Meta, at the end of the filter row, because it
319
+ is a reading about the results and not another control among them. */
320
+ .axi-palette__count {
321
+ margin-left: auto; flex: none;
322
+ color: var(--axi-text-faint);
323
+ font: var(--axi-t-label); font-size: 10px; letter-spacing: var(--axi-ls-label);
324
+ text-transform: uppercase;
325
+ }
326
+ /* min-height: 0 because the panel is a flex column and a list that cannot
327
+ shrink below its content pushes the panel past its own max-height. The
328
+ scrollbar is hidden: at twelve rows behind a fixed cap the bar is a channel
329
+ carved down the side of a small panel to report a fact the row count in the
330
+ bar has already given. */
331
+ .axi-palette__list {
332
+ flex: 1; min-height: 0; overflow-y: auto; padding: 4px 0;
333
+ scrollbar-width: none;
334
+ }
335
+ .axi-palette__list::-webkit-scrollbar { width: 0; height: 0; }
336
+ /* One .axi-palette__section per group of rows, each opening with a
337
+ .axi-palette__group heading. The section is a named part rather than left to
338
+ the consumer's wrapper so the rule between groups can be stated as what it
339
+ is - a parting between two sections - instead of guessed at from structure. */
340
+ .axi-palette__section + .axi-palette__section {
341
+ border-top: var(--axi-border-hairline) solid var(--axi-rule);
342
+ margin-top: 4px;
343
+ }
344
+ .axi-palette__group {
345
+ padding: 8px 10px 4px;
346
+ color: var(--axi-text-faint);
347
+ font: var(--axi-t-label); font-size: 10px; letter-spacing: var(--axi-ls-label);
348
+ text-transform: uppercase;
349
+ }
350
+ .axi-palette__row {
351
+ display: flex; align-items: center; gap: 8px;
352
+ width: 100%; padding: 7px 10px;
353
+ background: transparent; border: 0; border-radius: 0;
354
+ color: var(--axi-text-dim);
355
+ font: var(--axi-t-small); text-align: left; cursor: pointer;
356
+ }
357
+ .axi-palette__row:hover { background: var(--axi-surface-raised); color: var(--axi-text); }
358
+ .axi-palette__row[data-active] { background: var(--axi-accent); color: var(--axi-accent-ink); }
359
+ /* The row's own ink is set above, but a row carries a glyph and a second line
360
+ of text that were coloured on their own; on the filled row they all become
361
+ the ink the fill is written in. */
362
+ .axi-palette__row[data-active] svg,
363
+ .axi-palette__row[data-active] .axi-palette__meta { color: var(--axi-accent-ink); }
364
+ /* Where the row is, as against what it is. */
365
+ .axi-palette__meta { margin-left: auto; flex: none; color: var(--axi-text-faint); font-size: 11px; }
366
+ .axi-palette__empty {
367
+ padding: 24px 12px; text-align: center;
368
+ color: var(--axi-text-faint); font: var(--axi-t-small);
369
+ }
370
+ /* The palette's field at rest, wherever the app keeps the way in. It is a
371
+ button, and it is drawn as the field it opens - the same ground, the same
372
+ edge, the same magnifier at the head - so opening the palette reads as this
373
+ control growing rather than as a different object arriving.
374
+
375
+ It keeps the field's fill instead of a button's because what it stands for
376
+ is somewhere to type. What it takes from a button is the answer to the
377
+ cursor: the block and the lift, because it is still a thing you press. */
378
+ .axi-palette__trigger {
379
+ display: flex; align-items: center; width: 100%; overflow: hidden;
380
+ padding: 0 10px 0 0;
381
+ background: var(--axi-ground);
382
+ border: var(--axi-border-control) solid var(--axi-ink-line);
383
+ border-radius: var(--axi-radius-sm);
384
+ color: var(--axi-text-dim);
385
+ font: var(--axi-t-label); font-size: 12px; font-weight: 600;
386
+ cursor: pointer;
387
+ transition: transform .1s, box-shadow .1s, color .1s;
388
+ }
389
+ .axi-palette__trigger:hover {
390
+ color: var(--axi-text);
391
+ box-shadow: var(--axi-shadow-control);
392
+ transform: translate(-2px, -2px);
393
+ }
394
+ /* The magnifier at the head of the well, carrying the accent on its own. Its
395
+ own element and stretched to the trigger's height so the glyph is inside the
396
+ outline rather than floating in the fill. It was a solid accent block once,
397
+ which at a 30px row spends a lot of the loudest colour in the palette on a
398
+ control nobody is meant to look at until they want it - the glyph says the
399
+ same thing at a fraction of the volume. */
400
+ .axi-palette__mark {
401
+ display: flex; align-items: center; align-self: stretch; flex: none;
402
+ padding: 0 8px 0 10px; margin-right: 10px;
403
+ color: var(--axi-accent);
404
+ }
405
+ .axi-palette__label { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
406
+ .axi-palette__trigger .axi-kbd { margin-left: auto; flex: none; }
407
+
270
408
  /* ---------- tooltip ---------- */
271
409
  /* One line of ink on the darkest surface in the language, so it reads over
272
410
  anything it lands on. The class draws the box only; coordinates come from
package/src/tokens.css CHANGED
@@ -28,6 +28,20 @@
28
28
  --axi-ground-image: none;
29
29
  --axi-surface: #222731; /* a panel raised off the page */
30
30
  --axi-surface-raised: #2b313d; /* a chip or popover raised off a panel */
31
+ /* The fill for a surface that FLOATS over content which scrolls behind it: a
32
+ command palette, a menu popover, a modal. Holds --axi-surface, because for
33
+ a theme whose panels are opaque a floating panel is just a panel and there
34
+ is nothing to decide.
35
+
36
+ It exists for the theme whose panels are not. A translucent pane is legible
37
+ standing still on the page and stops being legible the moment a table
38
+ scrolls under it - the text it is carrying now has text behind it. The blur
39
+ that was supposed to rescue that is not something a language can promise:
40
+ backdrop-filter is unavailable or switched off on whole platforms, and
41
+ where it is missing the alpha is the only thing left. So the float gets its
42
+ own token, and a theme that goes translucent restates it near-opaque
43
+ without giving up the tint on everything that merely sits still. */
44
+ --axi-surface-float: var(--axi-surface);
31
45
  --axi-ink-line: #0c0e12; /* the outline every raised element is drawn with */
32
46
  /* The tone a shape is made of when it is made of the line ink rather than
33
47
  outlined in it - the tooltip, the titlebar strip, the switch's slug. Holds