@axiapps/axi-design 1.37.0 → 1.38.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.
Files changed (3) hide show
  1. package/dist/axi.css +67 -19
  2. package/package.json +1 -1
  3. package/src/data.css +66 -18
package/dist/axi.css CHANGED
@@ -2442,31 +2442,60 @@ textarea.axi-input {
2442
2442
  the row is the whole fact, and a class beside it would be a second source of
2443
2443
  truth for one thing.
2444
2444
 
2445
- The fill is the float step, not the raised one, and the reason is the hover
2446
- directly above: hovering a row ALREADY raises it, so a selection drawn at the
2447
- raised step is indistinguishable from the row under the cursor -- and every
2448
- consumer who has hand-written this state has hit that and reached for a hue
2449
- instead, which is rule 2's tinted-everything failure arrived at honestly.
2450
- Hover is a transient lift and selection is a held one, so selection sits one
2451
- step beyond it and hovering a selected row must not pull it back down.
2452
-
2453
- No accent, and no leading edge either. The accent is for one claim per screen
2454
- and a selected row spends it on something a detail pane usually spends again;
2455
- an edge would need a border reserved on every cell of every row, which is the
2456
- grid-of-boxes rule 8 refuses. The attachment is the one-surface-many-elements
2457
- case, same as the hover. */
2445
+ The MARK is the leading edge, not the fill, and that is the whole design. The
2446
+ hover directly above already raises a row, so any selection drawn as a fill
2447
+ has to find a neutral step that hover is not using -- and there isn't one. The
2448
+ ramp a theme is guaranteed to give is ground, surface, surface-raised; the
2449
+ fourth token, --axi-surface-float, is not a step on it at all but a promise of
2450
+ OPACITY for things that sit over content, which is why the default theme sets
2451
+ it equal to --axi-surface and glass sets it darker than --axi-surface-raised.
2452
+ A selection filled from it is invisible in one theme and a step backwards in
2453
+ the other. This is the trap the token's name invites and the reason this
2454
+ comment says so: float is an axis, not a rung.
2455
+
2456
+ So selection and hover share the raised fill and are told apart by the edge,
2457
+ the same answer and the same reasoning as `.axi-rail__nav--quiet`. The first
2458
+ cell of every body row reserves a transparent control-weight border for it, so
2459
+ lighting the edge costs no reflow -- again exactly what `.axi-rail__item`
2460
+ does. One edge is a mark; rule 8's refusal is of a BOX around a row, which is
2461
+ what turns a list of numbers into a grid.
2462
+
2463
+ The attachment is the one-surface-many-elements case, same as the hover. */
2464
+ .axi-table :where(tbody tr) > :where(td, th):first-child {
2465
+ border-inline-start: var(--axi-border-control) solid transparent;
2466
+ }
2458
2467
  .axi-table tbody tr[aria-current] :is(td, th) {
2459
- background: var(--axi-surface-float);
2468
+ background: var(--axi-surface-raised);
2460
2469
  background-attachment: fixed;
2461
2470
  color: var(--axi-text);
2462
2471
  }
2463
- .axi-table tbody tr[aria-current]:hover :is(td, th) {
2464
- background: var(--axi-surface-float);
2465
- background-attachment: fixed;
2472
+ .axi-table tbody tr[aria-current] > :is(td, th):first-child {
2473
+ border-inline-start-color: var(--axi-accent);
2466
2474
  }
2467
2475
  .axi-table__num { color: var(--axi-text); }
2468
- /* A name cell: an icon, a diamond or a rank beside the label. */
2469
- .axi-table__who { display: flex; align-items: center; gap: 9px; }
2476
+ /* A name cell: an icon, a diamond or a rank beside the label.
2477
+
2478
+ The label truncates and the mark does not. A name is arbitrarily long - a
2479
+ skill called "Chapter 4: Scorched Aftermath" measured 417px against a 183px
2480
+ column - and with nothing said, a flex row lets it spill across its
2481
+ neighbours rather than shrink. The same reasoning as the comment on
2482
+ .axi-tabs__tab, and the same pair of requirements: min-width: 0 on the
2483
+ container AND on the shrinking child, because a flex item's default
2484
+ min-width is its content, so the ellipsis never appears without both.
2485
+
2486
+ Selected by element, not by a class the consumer adds: which child is the
2487
+ icon and which is the label is visible in the markup, and asking every
2488
+ consumer to label it invites exactly the omission this rule exists to fix.
2489
+ The `flex: none` on the mark is the load-bearing half - without it the icon
2490
+ squashes toward zero before the text gives up any room at all. */
2491
+ .axi-table__who { display: flex; align-items: center; gap: 9px; min-width: 0; }
2492
+ .axi-table__who > :where(img, svg) { flex: none; }
2493
+ .axi-table__who > :where(span, a, div, p) {
2494
+ min-width: 0;
2495
+ overflow: hidden;
2496
+ text-overflow: ellipsis;
2497
+ white-space: nowrap;
2498
+ }
2470
2499
  /* Rank is the only fill a table gets, and only where the position is real -
2471
2500
  a podium, not a row number. An outlined rank is the ordinary case. */
2472
2501
  .axi-table__rank {
@@ -2544,6 +2573,25 @@ textarea.axi-input {
2544
2573
  its being a modifier rather than a second table. */
2545
2574
  .axi-table--dense thead th { padding: 0 7px 6px; }
2546
2575
  .axi-table--dense :is(td, tbody th) { padding: 5px 7px; font: var(--axi-t-micro); }
2576
+ /* Proportional columns, for a table inside a pane rather than a page.
2577
+
2578
+ `width: 100%` is a floor, not a cap. Under the default auto layout the
2579
+ columns size to their content, and because every cell here is `nowrap`,
2580
+ content wins: a three-column table measured 581px inside a 360px pane.
2581
+ A page-width table absorbs that, and .axi-table__scroll turns it into a
2582
+ horizontal scrollbar on purpose. A table sharing a 480px pane with a
2583
+ selector list has neither option - it needs the columns to divide the room
2584
+ it has, which is what a grid's `fr` gives for free and is the reason
2585
+ hand-built tables in panes were grids.
2586
+
2587
+ The consumer sets the proportions in a <colgroup>, because they are facts
2588
+ about one table's columns and nothing here can know them.
2589
+
2590
+ Cells get the clip, not just the ellipsis: fixed layout makes a cell
2591
+ narrower than its content the normal case rather than the exception, and
2592
+ an unclipped cell paints over the column beside it. */
2593
+ .axi-table--fixed { table-layout: fixed; }
2594
+ .axi-table--fixed :where(td, th) { overflow: hidden; text-overflow: ellipsis; }
2547
2595
  /* The sorted column, named with the attribute a screen reader already needs
2548
2596
  in order to announce it. A class beside `aria-sort` would be a second
2549
2597
  source of truth for one fact. The mark is ink on the head and its edge -
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@axiapps/axi-design",
3
- "version": "1.37.0",
3
+ "version": "1.38.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
@@ -140,31 +140,60 @@
140
140
  the row is the whole fact, and a class beside it would be a second source of
141
141
  truth for one thing.
142
142
 
143
- The fill is the float step, not the raised one, and the reason is the hover
144
- directly above: hovering a row ALREADY raises it, so a selection drawn at the
145
- raised step is indistinguishable from the row under the cursor -- and every
146
- consumer who has hand-written this state has hit that and reached for a hue
147
- instead, which is rule 2's tinted-everything failure arrived at honestly.
148
- Hover is a transient lift and selection is a held one, so selection sits one
149
- step beyond it and hovering a selected row must not pull it back down.
143
+ The MARK is the leading edge, not the fill, and that is the whole design. The
144
+ hover directly above already raises a row, so any selection drawn as a fill
145
+ has to find a neutral step that hover is not using -- and there isn't one. The
146
+ ramp a theme is guaranteed to give is ground, surface, surface-raised; the
147
+ fourth token, --axi-surface-float, is not a step on it at all but a promise of
148
+ OPACITY for things that sit over content, which is why the default theme sets
149
+ it equal to --axi-surface and glass sets it darker than --axi-surface-raised.
150
+ A selection filled from it is invisible in one theme and a step backwards in
151
+ the other. This is the trap the token's name invites and the reason this
152
+ comment says so: float is an axis, not a rung.
150
153
 
151
- No accent, and no leading edge either. The accent is for one claim per screen
152
- and a selected row spends it on something a detail pane usually spends again;
153
- an edge would need a border reserved on every cell of every row, which is the
154
- grid-of-boxes rule 8 refuses. The attachment is the one-surface-many-elements
155
- case, same as the hover. */
154
+ So selection and hover share the raised fill and are told apart by the edge,
155
+ the same answer and the same reasoning as `.axi-rail__nav--quiet`. The first
156
+ cell of every body row reserves a transparent control-weight border for it, so
157
+ lighting the edge costs no reflow -- again exactly what `.axi-rail__item`
158
+ does. One edge is a mark; rule 8's refusal is of a BOX around a row, which is
159
+ what turns a list of numbers into a grid.
160
+
161
+ The attachment is the one-surface-many-elements case, same as the hover. */
162
+ .axi-table :where(tbody tr) > :where(td, th):first-child {
163
+ border-inline-start: var(--axi-border-control) solid transparent;
164
+ }
156
165
  .axi-table tbody tr[aria-current] :is(td, th) {
157
- background: var(--axi-surface-float);
166
+ background: var(--axi-surface-raised);
158
167
  background-attachment: fixed;
159
168
  color: var(--axi-text);
160
169
  }
161
- .axi-table tbody tr[aria-current]:hover :is(td, th) {
162
- background: var(--axi-surface-float);
163
- background-attachment: fixed;
170
+ .axi-table tbody tr[aria-current] > :is(td, th):first-child {
171
+ border-inline-start-color: var(--axi-accent);
164
172
  }
165
173
  .axi-table__num { color: var(--axi-text); }
166
- /* A name cell: an icon, a diamond or a rank beside the label. */
167
- .axi-table__who { display: flex; align-items: center; gap: 9px; }
174
+ /* A name cell: an icon, a diamond or a rank beside the label.
175
+
176
+ The label truncates and the mark does not. A name is arbitrarily long - a
177
+ skill called "Chapter 4: Scorched Aftermath" measured 417px against a 183px
178
+ column - and with nothing said, a flex row lets it spill across its
179
+ neighbours rather than shrink. The same reasoning as the comment on
180
+ .axi-tabs__tab, and the same pair of requirements: min-width: 0 on the
181
+ container AND on the shrinking child, because a flex item's default
182
+ min-width is its content, so the ellipsis never appears without both.
183
+
184
+ Selected by element, not by a class the consumer adds: which child is the
185
+ icon and which is the label is visible in the markup, and asking every
186
+ consumer to label it invites exactly the omission this rule exists to fix.
187
+ The `flex: none` on the mark is the load-bearing half - without it the icon
188
+ squashes toward zero before the text gives up any room at all. */
189
+ .axi-table__who { display: flex; align-items: center; gap: 9px; min-width: 0; }
190
+ .axi-table__who > :where(img, svg) { flex: none; }
191
+ .axi-table__who > :where(span, a, div, p) {
192
+ min-width: 0;
193
+ overflow: hidden;
194
+ text-overflow: ellipsis;
195
+ white-space: nowrap;
196
+ }
168
197
  /* Rank is the only fill a table gets, and only where the position is real -
169
198
  a podium, not a row number. An outlined rank is the ordinary case. */
170
199
  .axi-table__rank {
@@ -242,6 +271,25 @@
242
271
  its being a modifier rather than a second table. */
243
272
  .axi-table--dense thead th { padding: 0 7px 6px; }
244
273
  .axi-table--dense :is(td, tbody th) { padding: 5px 7px; font: var(--axi-t-micro); }
274
+ /* Proportional columns, for a table inside a pane rather than a page.
275
+
276
+ `width: 100%` is a floor, not a cap. Under the default auto layout the
277
+ columns size to their content, and because every cell here is `nowrap`,
278
+ content wins: a three-column table measured 581px inside a 360px pane.
279
+ A page-width table absorbs that, and .axi-table__scroll turns it into a
280
+ horizontal scrollbar on purpose. A table sharing a 480px pane with a
281
+ selector list has neither option - it needs the columns to divide the room
282
+ it has, which is what a grid's `fr` gives for free and is the reason
283
+ hand-built tables in panes were grids.
284
+
285
+ The consumer sets the proportions in a <colgroup>, because they are facts
286
+ about one table's columns and nothing here can know them.
287
+
288
+ Cells get the clip, not just the ellipsis: fixed layout makes a cell
289
+ narrower than its content the normal case rather than the exception, and
290
+ an unclipped cell paints over the column beside it. */
291
+ .axi-table--fixed { table-layout: fixed; }
292
+ .axi-table--fixed :where(td, th) { overflow: hidden; text-overflow: ellipsis; }
245
293
  /* The sorted column, named with the attribute a screen reader already needs
246
294
  in order to announce it. A class beside `aria-sort` would be a second
247
295
  source of truth for one fact. The mark is ink on the head and its edge -