@axiapps/axi-design 1.38.0 → 1.40.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
@@ -144,6 +144,7 @@ not "what does the system look like". Everything else is
144
144
  | `--axi-pill-size` | an `.axi-pill`'s text size, which travels with its padding | `13px` | `<button class="axi-pill" style="--axi-pill-size: 10px">` |
145
145
  | `--axi-input-pad` | the padding inside an `.axi-input`, for a field that is furniture in a header rather than a control on a page | `11px 12px` | `<input class="axi-input" style="--axi-input-pad: 7px 12px">` |
146
146
  | `--axi-input-size` | an `.axi-input`'s text size, which travels with its padding | `14px` | `<input class="axi-input" style="--axi-input-size: 13px">` |
147
+ | `--axi-action-hit` | the hit target of an `.axi-action--glyph`, whose label is one character and gives the pointer nothing to land on | `24px` | `<button class="axi-action axi-action--glyph" style="--axi-action-hit: 32px">` |
147
148
  | `--axi-well-pad` | the padding inside an `.axi-well` | `10px` | `<div class="axi-well" style="--axi-well-pad: 18px">` |
148
149
  | `--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)">` |
149
150
  | `--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">` |
package/dist/axi.css CHANGED
@@ -786,6 +786,74 @@ button.axi-panel--tile:hover,
786
786
  .axi-link:where(:hover),
787
787
  .axi-prose a:where(:hover) { color: var(--axi-text); }
788
788
 
789
+ /* ---------- quiet action ---------- */
790
+ /* A control that is only its label. Not a button - it draws no box, takes no
791
+ padding and sits inside running text or a dense header where a box would be
792
+ the loudest thing on screen. Not a link either: a link goes somewhere and
793
+ says so with an underline and the accent, while this does something to the
794
+ view you are already looking at.
795
+
796
+ It exists because the first consumer counted had ninety of them and no class
797
+ for any of them, so each spelled out its own resting colour and - the part
798
+ that actually broke - its own hover colour. Fifteen different hover colours
799
+ across ninety sites, every one a literal from a utility palette rather than
800
+ a token, which means every one of them left the theme at the moment the
801
+ cursor arrived.
802
+
803
+ Three of those ninety did worse than leave the theme. A control resting on
804
+ the warning ink hovered to a neutral grey, and one resting on the danger ink
805
+ hovered to white: the verdict disappearing exactly when the reader reaches
806
+ for it. That is the same failure rule 6's addendum describes on .axi-btn,
807
+ arriving by a different road - not a component out-ranking its own modifier,
808
+ but an author naming a colour that had no business being named. The fix is
809
+ the same shape, and it is why the hover below is `:where(:hover)`: it weighs
810
+ one class, so `axi-action axi-ink-danger` stays red under the cursor and
811
+ takes its feedback from the underline instead.
812
+
813
+ `font: inherit` and not the label font: these land at 10px in a chart
814
+ legend, 11px in a section header and 14px in a modal, and a control that is
815
+ only its label has no business resizing the text around it. The weight is
816
+ inherited too, which is where this parts company with .axi-link - a link is
817
+ 600 wherever it lands because it must be findable in a paragraph; an action
818
+ already sits where the reader is looking. */
819
+ .axi-action {
820
+ padding: 0;
821
+ background: none;
822
+ border: 0;
823
+ font: inherit;
824
+ text-align: inherit;
825
+ color: var(--axi-text-dim);
826
+ cursor: pointer;
827
+ transition: color .1s;
828
+ }
829
+ /* Brighten for the uninked case, underline for every case. The colour change
830
+ is a fallback the ink layer beats by design, so an inked action would have
831
+ no hover feedback at all without a second signal that names no colour. An
832
+ underline is the one this language already trusts - it is how .axi-link
833
+ marks itself actionable - and it reads on amber, on red and on plain alike. */
834
+ .axi-action:where(:hover) {
835
+ color: var(--axi-text);
836
+ text-decoration: underline;
837
+ text-underline-offset: 2px;
838
+ }
839
+
840
+ /* An action whose label is a single glyph: a clear-field cross, a stepper
841
+ arrow, a star that marks a favourite. Same control, but a glyph gives the
842
+ pointer almost nothing to land on, so this is the one thing the plain action
843
+ does not need - a hit target. The box stays invisible; only its size is
844
+ declared. */
845
+ .axi-action--glyph {
846
+ display: inline-flex;
847
+ align-items: center;
848
+ justify-content: center;
849
+ min-width: var(--axi-action-hit, 24px);
850
+ min-height: var(--axi-action-hit, 24px);
851
+ /* The label is a glyph, so there is no text to underline - the brighten is
852
+ the whole signal and the underline would draw a stray rule beside it. */
853
+ text-decoration: none;
854
+ }
855
+ .axi-action--glyph:where(:hover) { text-decoration: none; }
856
+
789
857
  /* ---------- keyboard key ---------- */
790
858
  /* A key on the keyboard, named in the interface: the Esc that closes a
791
859
  palette, the Ctrl K that opens it. Drawn as a small control rather than as a
@@ -2429,7 +2497,19 @@ textarea.axi-input {
2429
2497
  alternative of filling the container and leaving the cells transparent: a
2430
2498
  sticky head has to carry its own fill, because a fill on `thead` stays
2431
2499
  behind while the cells travel. */
2432
- .axi-table tbody tr:hover :is(td, th) {
2500
+ /* Written to weigh exactly one class, which takes some doing for a rule that
2501
+ has to reach a descendant. `.axi-table tbody tr:hover :is(td, th)` weighed
2502
+ three classes and four elements, so it beat the ink layer's one - and the
2503
+ consumer that found this had six cells inked danger and six inked ok, every
2504
+ one of which went plain the moment its row was hovered. A red value and a
2505
+ green value both losing their verdict exactly as the reader reaches for them
2506
+ is rule 6's addendum again, arriving through a descendant selector.
2507
+
2508
+ `.axi-table` is the only thing here that counts, so this lands level with the
2509
+ resting cell rule (`.axi-table :where(td, tbody th)`, also one class) and
2510
+ wins on order, while an ink class in utilities.css - one class, later file -
2511
+ wins over both. */
2512
+ .axi-table :where(tbody tr:hover) :where(td, th) {
2433
2513
  background: var(--axi-surface-raised);
2434
2514
  background-attachment: fixed;
2435
2515
  color: var(--axi-text);
@@ -0,0 +1,27 @@
1
+ /* axi design language - generated by scripts/build.mjs.
2
+ Edit the files in src/ and run `npm run build`; do not edit this file. */
3
+
4
+ [data-axi-theme="flat"] {
5
+ --axi-ground: #090b10;
6
+ --axi-surface: linear-gradient(#1c2130, #181d2c);
7
+ --axi-surface-raised: linear-gradient(#242a3b, #202636);
8
+ --axi-well-fill: #141822;
9
+ --axi-ink-line: rgba(255, 255, 255, .10);
10
+ --axi-rule: rgba(255, 255, 255, .07);
11
+ --axi-ground-deep: #0c1015;
12
+ --axi-accent-ink: #0c1015;
13
+ --axi-ink-on-fill: #0c1015;
14
+ --axi-text: #e8eaed;
15
+ --axi-text-dim: #8b929e;
16
+ --axi-text-faint: #5d6577;
17
+ --axi-shadow-panel: 0 2px 8px rgba(0, 0, 0, .4), 0 1px 3px rgba(0, 0, 0, .3), inset 0 1px 0 rgba(255, 255, 255, .05);
18
+ --axi-shadow-control: 0 1px 4px rgba(0, 0, 0, .3), inset 0 1px 0 rgba(255, 255, 255, .045);
19
+ --axi-shadow-panel-hover: 0 6px 18px rgba(0, 0, 0, .5), 0 2px 5px rgba(0, 0, 0, .35), inset 0 1px 0 rgba(255, 255, 255, .07);
20
+ --axi-shadow-control-hover: 0 3px 10px rgba(0, 0, 0, .4), inset 0 1px 0 rgba(255, 255, 255, .06);
21
+ --axi-border-panel: 1px;
22
+ --axi-border-control: 1px;
23
+ --axi-border-hairline: 1px;
24
+ --axi-radius: 6px;
25
+ --axi-radius-sm: 4px;
26
+ --axi-radius-xs: 2px;
27
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@axiapps/axi-design",
3
- "version": "1.38.0",
3
+ "version": "1.40.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",
package/src/data.css CHANGED
@@ -127,7 +127,19 @@
127
127
  alternative of filling the container and leaving the cells transparent: a
128
128
  sticky head has to carry its own fill, because a fill on `thead` stays
129
129
  behind while the cells travel. */
130
- .axi-table tbody tr:hover :is(td, th) {
130
+ /* Written to weigh exactly one class, which takes some doing for a rule that
131
+ has to reach a descendant. `.axi-table tbody tr:hover :is(td, th)` weighed
132
+ three classes and four elements, so it beat the ink layer's one - and the
133
+ consumer that found this had six cells inked danger and six inked ok, every
134
+ one of which went plain the moment its row was hovered. A red value and a
135
+ green value both losing their verdict exactly as the reader reaches for them
136
+ is rule 6's addendum again, arriving through a descendant selector.
137
+
138
+ `.axi-table` is the only thing here that counts, so this lands level with the
139
+ resting cell rule (`.axi-table :where(td, tbody th)`, also one class) and
140
+ wins on order, while an ink class in utilities.css - one class, later file -
141
+ wins over both. */
142
+ .axi-table :where(tbody tr:hover) :where(td, th) {
131
143
  background: var(--axi-surface-raised);
132
144
  background-attachment: fixed;
133
145
  color: var(--axi-text);
@@ -493,6 +493,74 @@ button.axi-panel--tile:hover,
493
493
  .axi-link:where(:hover),
494
494
  .axi-prose a:where(:hover) { color: var(--axi-text); }
495
495
 
496
+ /* ---------- quiet action ---------- */
497
+ /* A control that is only its label. Not a button - it draws no box, takes no
498
+ padding and sits inside running text or a dense header where a box would be
499
+ the loudest thing on screen. Not a link either: a link goes somewhere and
500
+ says so with an underline and the accent, while this does something to the
501
+ view you are already looking at.
502
+
503
+ It exists because the first consumer counted had ninety of them and no class
504
+ for any of them, so each spelled out its own resting colour and - the part
505
+ that actually broke - its own hover colour. Fifteen different hover colours
506
+ across ninety sites, every one a literal from a utility palette rather than
507
+ a token, which means every one of them left the theme at the moment the
508
+ cursor arrived.
509
+
510
+ Three of those ninety did worse than leave the theme. A control resting on
511
+ the warning ink hovered to a neutral grey, and one resting on the danger ink
512
+ hovered to white: the verdict disappearing exactly when the reader reaches
513
+ for it. That is the same failure rule 6's addendum describes on .axi-btn,
514
+ arriving by a different road - not a component out-ranking its own modifier,
515
+ but an author naming a colour that had no business being named. The fix is
516
+ the same shape, and it is why the hover below is `:where(:hover)`: it weighs
517
+ one class, so `axi-action axi-ink-danger` stays red under the cursor and
518
+ takes its feedback from the underline instead.
519
+
520
+ `font: inherit` and not the label font: these land at 10px in a chart
521
+ legend, 11px in a section header and 14px in a modal, and a control that is
522
+ only its label has no business resizing the text around it. The weight is
523
+ inherited too, which is where this parts company with .axi-link - a link is
524
+ 600 wherever it lands because it must be findable in a paragraph; an action
525
+ already sits where the reader is looking. */
526
+ .axi-action {
527
+ padding: 0;
528
+ background: none;
529
+ border: 0;
530
+ font: inherit;
531
+ text-align: inherit;
532
+ color: var(--axi-text-dim);
533
+ cursor: pointer;
534
+ transition: color .1s;
535
+ }
536
+ /* Brighten for the uninked case, underline for every case. The colour change
537
+ is a fallback the ink layer beats by design, so an inked action would have
538
+ no hover feedback at all without a second signal that names no colour. An
539
+ underline is the one this language already trusts - it is how .axi-link
540
+ marks itself actionable - and it reads on amber, on red and on plain alike. */
541
+ .axi-action:where(:hover) {
542
+ color: var(--axi-text);
543
+ text-decoration: underline;
544
+ text-underline-offset: 2px;
545
+ }
546
+
547
+ /* An action whose label is a single glyph: a clear-field cross, a stepper
548
+ arrow, a star that marks a favourite. Same control, but a glyph gives the
549
+ pointer almost nothing to land on, so this is the one thing the plain action
550
+ does not need - a hit target. The box stays invisible; only its size is
551
+ declared. */
552
+ .axi-action--glyph {
553
+ display: inline-flex;
554
+ align-items: center;
555
+ justify-content: center;
556
+ min-width: var(--axi-action-hit, 24px);
557
+ min-height: var(--axi-action-hit, 24px);
558
+ /* The label is a glyph, so there is no text to underline - the brighten is
559
+ the whole signal and the underline would draw a stray rule beside it. */
560
+ text-decoration: none;
561
+ }
562
+ .axi-action--glyph:where(:hover) { text-decoration: none; }
563
+
496
564
  /* ---------- keyboard key ---------- */
497
565
  /* A key on the keyboard, named in the interface: the Esc that closes a
498
566
  palette, the Ctrl K that opens it. Drawn as a small control rather than as a