@axiapps/axi-design 1.12.0 → 1.13.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
@@ -67,13 +67,16 @@ import '@axiapps/axi-design/themes/glass.css'
67
67
  <html data-axi-theme="glass">
68
68
  ```
69
69
 
70
- `glass` keeps the outline, the hard block and every ink exactly as they are,
71
- and repaints the surface layer: translucent panels over a colder ground, with
72
- popovers, drawers and modals blurring what sits behind them. Remove the
73
- attribute and you are back on the main theme with no other change — a theme
74
- restates tokens and never adds a component, so nothing in your markup knows
75
- which one is on. That is the point: the look is maintained here rather than
76
- copied into your app as a custom theme that then has to be kept in step.
70
+ `glass` repaints the material: translucent panels lit from the top-left over a
71
+ near-black page with three wide colour washes on it, hairline edges, rounded
72
+ corners and a soft drop instead of the main theme's hard offset block, with
73
+ popovers, drawers and modals blurring what sits behind them. The five saturated
74
+ inks, the measure and the type are untouched — they are the language, not the
75
+ paint. Remove the attribute and you are back on the main theme with no other
76
+ change: a theme restates tokens and never adds a component, so nothing in your
77
+ markup knows which one is on. That is the point — the look is maintained here
78
+ rather than copied into your app as a custom theme that then has to be kept in
79
+ step.
77
80
 
78
81
  The main theme is the language and a theme is a repaint of it — [the
79
82
  rules](docs/RULES.md#themes) say what a theme may and may not do.
package/dist/axi.css CHANGED
@@ -16,6 +16,20 @@
16
16
  :root {
17
17
  /* --- surface & text --- */
18
18
  --axi-ground: #15181d; /* the page itself */
19
+ /* An image layer painted over the ground colour, on the page and nowhere
20
+ else. The second toll the Themes section describes, and it exists for the
21
+ same reason --axi-surface-filter does: a glass theme wants the page lit
22
+ from a few directions, and it does not get to introduce a gradient any
23
+ more than it got to introduce a blur. Declared here inert (`none`), read
24
+ unconditionally by body, and restated by the theme.
25
+
26
+ Why a second token rather than letting a theme put the gradient in
27
+ --axi-ground itself: --axi-ground is read as `background-color` by the
28
+ plot and the select, where an image value is invalid and drops out, and
29
+ as the flat fill of the masthead, the tooltip row and a dozen inset
30
+ shapes, where a page-positioned radial would render as an arbitrary
31
+ wedge of colour. The ground stays a colour. This is the page's light. */
32
+ --axi-ground-image: none;
19
33
  --axi-surface: #222731; /* a panel raised off the page */
20
34
  --axi-surface-raised: #2b313d; /* a chip or popover raised off a panel */
21
35
  --axi-ink-line: #0c0e12; /* the outline every raised element is drawn with */
@@ -143,7 +157,13 @@ html { color-scheme: dark; }
143
157
 
144
158
  body {
145
159
  margin: 0;
146
- background: var(--axi-ground);
160
+ /* Longhands rather than the shorthand: the ground is a colour and the light
161
+ over it is an image, and `background:` would make setting either one
162
+ reset the other. Fixed so a theme's light stays put as the page scrolls
163
+ instead of stretching to the document's height. */
164
+ background-color: var(--axi-ground);
165
+ background-image: var(--axi-ground-image);
166
+ background-attachment: fixed;
147
167
  color: var(--axi-text);
148
168
  font: var(--axi-t-body);
149
169
  -webkit-font-smoothing: antialiased;
@@ -3,13 +3,26 @@
3
3
 
4
4
  [data-axi-theme="glass"] {
5
5
  --axi-ground: #0a0c10;
6
- --axi-surface: rgba(255, 255, 255, .09);
7
- --axi-surface-raised: rgba(255, 255, 255, .15);
8
- --axi-ink-line: #242b38;
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
+ --axi-surface: linear-gradient(145deg, rgba(58, 68, 92, .55), rgba(28, 33, 46, .42));
8
+ --axi-surface-raised: linear-gradient(145deg, rgba(86, 99, 130, .5), rgba(44, 52, 71, .38));
9
+ --axi-surface-filter: blur(18px) saturate(140%);
10
+ --axi-ink-line: rgba(180, 200, 255, .16);
11
+ --axi-rule: rgba(180, 200, 255, .14);
9
12
  --axi-ground-deep: #0c0e12;
10
13
  --axi-accent-ink: #0c0e12;
11
14
  --axi-ink-on-fill: #0c0e12;
12
- --axi-rule: rgba(255, 255, 255, .17);
13
- --axi-scrim: rgba(6, 7, 9, .55);
14
- --axi-surface-filter: blur(14px) saturate(140%);
15
+ --axi-text: #f2f5fb;
16
+ --axi-text-dim: #b3bdd0;
17
+ --axi-text-faint: #7f8aa0;
18
+ --axi-scrim: rgba(4, 6, 12, .66);
19
+ --axi-shadow-panel: 0 18px 44px rgba(0, 0, 0, .55), inset 0 1px 0 rgba(255, 255, 255, .14);
20
+ --axi-shadow-control: 0 6px 16px rgba(0, 0, 0, .45), inset 0 1px 0 rgba(255, 255, 255, .12);
21
+ --axi-shadow-panel-hover: 0 26px 60px rgba(0, 0, 0, .6), inset 0 1px 0 rgba(255, 255, 255, .2);
22
+ --axi-shadow-control-hover: 0 10px 24px rgba(0, 0, 0, .5), inset 0 1px 0 rgba(255, 255, 255, .18);
23
+ --axi-border-panel: 1px;
24
+ --axi-border-control: 1px;
25
+ --axi-border-hairline: 1px;
26
+ --axi-radius: 16px;
27
+ --axi-radius-sm: 10px;
15
28
  }
package/docs/RULES.md CHANGED
@@ -16,10 +16,11 @@ gridlines (a `repeating-linear-gradient` of hard stops, which is how N evenly
16
16
  spaced rules get drawn without asking every consumer to emit N empty divs).
17
17
  A gradient across a surface is still forbidden in every component file, and
18
18
  always will be. The single relief is a *theme* restating the surface tokens
19
- themselves — see [Themes](#themes) — which is what lets a glass theme exist
20
- without one component ever learning the word "glass". A component cannot reach
21
- for that exception, because it cannot see it: what it reads is the same surface
22
- token it was already reading.
19
+ themselves — and `--axi-ground-image`, the page's own light, which is declared
20
+ inert in `tokens.css` and read only by `body`; see [Themes](#themes). That is
21
+ what lets a glass theme exist without one component ever learning the word
22
+ "glass". A component cannot reach for that exception, because it cannot see it:
23
+ what it reads is the same surface token it was already reading.
23
24
 
24
25
  ## 2. No colour at partial opacity over the ground
25
26
 
@@ -28,13 +29,19 @@ just brown, and five muted inks over near-black are five browns. When something
28
29
  should be quieter, reach for a neutral from the ramp — that is what the ramp is
29
30
  for.
30
31
 
31
- A theme gets the same carve-out as rule 1 and not one inch more: it may hold the
32
- *surface* tokens at partial opacity, because a translucent surface is that
33
- surface's own definition rather than a colour laid over the ground. The inks are
34
- untouched. A muted `--axi-warn`, a faded accent, a status ink at 60% — still
35
- forbidden, in a theme exactly as in a component, because the paragraph above is
36
- about what happens to meaning when five inks become five browns, and changing
37
- which stylesheet does the muting does not change that.
32
+ A theme gets the same carve-out as rule 1: it may hold the *surface layer* at
33
+ partial opacity, because a translucent surface is that surface's own definition
34
+ rather than a colour laid over the ground. That layer is the two surfaces and
35
+ the lines that bound and divide them — `--axi-ink-line` and `--axi-rule` — for
36
+ the same reason: the edge of a translucent panel is as much the panel as its
37
+ face, and an opaque hairline around a pane of glass is a picture frame.
38
+
39
+ The five saturated inks are untouched. A muted `--axi-warn`, a faded accent, a
40
+ status ink at 60% — still forbidden, in a theme exactly as in a component,
41
+ because the paragraph above is about what happens to meaning when five inks
42
+ become five browns, and changing which stylesheet does the muting does not
43
+ change that. The neutral text ramp is likewise a theme's to restate but not to
44
+ fade: a theme picks where `--axi-text-dim` sits, it does not write text at 60%.
38
45
 
39
46
  ## 3. Every raised element is outlined and blocked
40
47
 
@@ -474,13 +481,47 @@ main-theme token first.** A glass theme wants a `backdrop-filter`; it does not
474
481
  get to introduce one. `--axi-surface-filter` is declared in `tokens.css` with an
475
482
  inert default (`none`), the surfaces read it unconditionally, and the theme
476
483
  restates it. The main theme is unchanged in appearance and the hook is part of
477
- the language rather than part of the theme. Every theme pays this toll, and it
478
- is what keeps the mirror true: a token the theme could set that the main theme
479
- had never heard of is the first step back toward theme-only components.
480
-
481
- Rules 1 and 2 name the only relief a theme gets, and it is confined to the
482
- surface layer: a theme may put a gradient on a surface and may hold a surface
483
- token at partial opacity. It may not mute an ink. Read those two rules for why.
484
+ the language rather than part of the theme. `--axi-ground-image` is the second
485
+ of these, on the same terms: the page's light, inert at `none`, read by `body`
486
+ and nowhere else. Every theme pays this toll, and it is what keeps the mirror
487
+ true: a token the theme could set that the main theme had never heard of is the
488
+ first step back toward theme-only components.
489
+
490
+ ### What a theme may restate
491
+
492
+ Rules 1 and 2 name the relief a theme gets in the surface layer: a theme may
493
+ put a gradient on a surface and may hold a surface token at partial opacity. It
494
+ may not mute an ink. Read those two rules for why.
495
+
496
+ The relief is not confined to that layer, though, and the first draft of this
497
+ section said it was. **A theme may also restate the block and the corner** —
498
+ `--axi-shadow-*`, `--axi-border-*`, `--axi-radius` and `--axi-radius-sm`. Rule 3
499
+ requires that a raised element read as raised and an outlined one as outlined.
500
+ A hard offset block in the line ink is how the main theme answers that; a soft
501
+ drop with an inset top highlight is a different answer to the same question,
502
+ and a translucent panel wearing an opaque theme's block does not look like
503
+ glass, it looks like a bug. The block and the corner are how a theme says what
504
+ its material is.
505
+
506
+ What is **not** a theme's to restate, and each for its own reason:
507
+
508
+ - **The five saturated fills.** `--axi-accent`, `--axi-meta`, `--axi-ok`,
509
+ `--axi-warn`, `--axi-danger` carry meaning (rules 5, 6, 9, 10). Their `-ink`
510
+ companions are not on this list: `--axi-accent-ink` and `--axi-ink-on-fill`
511
+ are the colour a word is written in when it sits on a fill, and a theme that
512
+ lightens the outline has to be able to hold them dark.
513
+ - **The offset scale.** `--axi-offset-*` is what the main theme's block is
514
+ composed *from*. A theme restates the composed `--axi-shadow-*` wholesale or
515
+ leaves it; retuning the offsets underneath would leave the two spellings of
516
+ "the block" disagreeing.
517
+ - **The measure.** `--axi-page`, `--axi-gutter`. Where the text wraps is not a
518
+ look, and moving it would reflow every page rather than repaint it.
519
+ - **The type.** `--axi-sans`, `--axi-mono`, `--axi-t-*`, `--axi-ls-*`. The same
520
+ call, harder: the type scale is the voice.
521
+
522
+ The line to hold is the one-for-one rule above, not a list of layers. A theme
523
+ that restates the block still paints every component; a theme that invents one
524
+ does not.
484
525
 
485
526
  **What is mechanically enforced.** `tests/themes.test.mjs` reads every
486
527
  `dist/themes/*.css` and checks the mirror rather than trusting it: the file
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@axiapps/axi-design",
3
- "version": "1.12.0",
3
+ "version": "1.13.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/base.css CHANGED
@@ -11,7 +11,13 @@ html { color-scheme: dark; }
11
11
 
12
12
  body {
13
13
  margin: 0;
14
- background: var(--axi-ground);
14
+ /* Longhands rather than the shorthand: the ground is a colour and the light
15
+ over it is an image, and `background:` would make setting either one
16
+ reset the other. Fixed so a theme's light stays put as the page scrolls
17
+ instead of stretching to the document's height. */
18
+ background-color: var(--axi-ground);
19
+ background-image: var(--axi-ground-image);
20
+ background-attachment: fixed;
15
21
  color: var(--axi-text);
16
22
  font: var(--axi-t-body);
17
23
  -webkit-font-smoothing: antialiased;
package/src/tokens.css CHANGED
@@ -12,6 +12,20 @@
12
12
  :root {
13
13
  /* --- surface & text --- */
14
14
  --axi-ground: #15181d; /* the page itself */
15
+ /* An image layer painted over the ground colour, on the page and nowhere
16
+ else. The second toll the Themes section describes, and it exists for the
17
+ same reason --axi-surface-filter does: a glass theme wants the page lit
18
+ from a few directions, and it does not get to introduce a gradient any
19
+ more than it got to introduce a blur. Declared here inert (`none`), read
20
+ unconditionally by body, and restated by the theme.
21
+
22
+ Why a second token rather than letting a theme put the gradient in
23
+ --axi-ground itself: --axi-ground is read as `background-color` by the
24
+ plot and the select, where an image value is invalid and drops out, and
25
+ as the flat fill of the masthead, the tooltip row and a dozen inset
26
+ shapes, where a page-positioned radial would render as an arbitrary
27
+ wedge of colour. The ground stays a colour. This is the page's light. */
28
+ --axi-ground-image: none;
15
29
  --axi-surface: #222731; /* a panel raised off the page */
16
30
  --axi-surface-raised: #2b313d; /* a chip or popover raised off a panel */
17
31
  --axi-ink-line: #0c0e12; /* the outline every raised element is drawn with */