@adminiumjs/tokens 0.2.1 → 0.2.2

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.
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,sFAAsF;AACtF,eAAO,MAAM,MAAM,sCAAuC,CAAC;AAC3D,MAAM,MAAM,SAAS,GAAG,CAAC,OAAO,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC;AAChD,0DAA0D;AAC1D,MAAM,MAAM,aAAa,GAAG,OAAO,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;AAEzD;;;;;;;;;;GAUG;AACH,eAAO,MAAM,OAAO;;;;;;;;;CASV,CAAC;AAEX;;;;GAIG;AACH,eAAO,MAAM,YAAY;;;;;;;;;CASf,CAAC;AAEX,+BAA+B;AAC/B,MAAM,MAAM,MAAM,GAAG,MAAM,OAAO,OAAO,CAAC;AAE1C,4DAA4D;AAC5D,wBAAgB,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,aAAa,GAAG,MAAM,CAEtE;AAED,qCAAqC;AACrC,eAAO,MAAM,SAAS,qCAAsC,CAAC;AAC7D,MAAM,MAAM,OAAO,GAAG,CAAC,OAAO,SAAS,CAAC,CAAC,MAAM,CAAC,CAAC;AAEjD,4EAA4E;AAC5E,eAAO,MAAM,IAAI,yBAA0B,CAAC;AAC5C,MAAM,MAAM,GAAG,GAAG,CAAC,OAAO,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC;AAExC,mFAAmF;AACnF,eAAO,MAAM,WAAW,mGASd,CAAC;AAEX,uEAAuE;AACvE,eAAO,MAAM,eAAe,4CAA6C,CAAC;AAE1E;;;;GAIG;AACH,eAAO,MAAM,gBAAgB;;;;;;CAMnB,CAAC;AAEX;;;GAGG;AACH,eAAO,MAAM,YAAY;;;;;;CAMf,CAAC;AAEX,8DAA8D;AAC9D,eAAO,MAAM,aAAa;;;;;CAKhB,CAAC;AAEX,OAAO,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA;;;;;GAKG;AAEH,sFAAsF;AACtF,eAAO,MAAM,MAAM,sCAAuC,CAAC;AAC3D,MAAM,MAAM,SAAS,GAAG,CAAC,OAAO,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC;AAChD,0DAA0D;AAC1D,MAAM,MAAM,aAAa,GAAG,OAAO,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;AAEzD;;;;;;;;;;GAUG;AACH,eAAO,MAAM,OAAO;;;;;;;;;CASV,CAAC;AAEX;;;;GAIG;AACH,eAAO,MAAM,YAAY;;;;;;;;;CASf,CAAC;AAEX,+BAA+B;AAC/B,MAAM,MAAM,MAAM,GAAG,MAAM,OAAO,OAAO,CAAC;AAE1C,4DAA4D;AAC5D,wBAAgB,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,aAAa,GAAG,MAAM,CAEtE;AAED,qCAAqC;AACrC,eAAO,MAAM,SAAS,qCAAsC,CAAC;AAC7D,MAAM,MAAM,OAAO,GAAG,CAAC,OAAO,SAAS,CAAC,CAAC,MAAM,CAAC,CAAC;AAEjD,4EAA4E;AAC5E,eAAO,MAAM,IAAI,yBAA0B,CAAC;AAC5C,MAAM,MAAM,GAAG,GAAG,CAAC,OAAO,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC;AAExC,mFAAmF;AACnF,eAAO,MAAM,WAAW,mGASd,CAAC;AAEX,uEAAuE;AACvE,eAAO,MAAM,eAAe,4CAA6C,CAAC;AAE1E;;;;GAIG;AACH,eAAO,MAAM,gBAAgB;;;;;;CAMnB,CAAC;AAEX;;;GAGG;AACH,eAAO,MAAM,YAAY;;;;;;CAMf,CAAC;AAEX,8DAA8D;AAC9D,eAAO,MAAM,aAAa;;;;;CAKhB,CAAC;AAEX,OAAO,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC"}
package/dist/index.js CHANGED
@@ -1,3 +1,4 @@
1
+ // SPDX-License-Identifier: AGPL-3.0-only
1
2
  /**
2
3
  * @adminium/tokens — JS-side constants for the four theming axes plus the pre-hydration
3
4
  * script. CSS custom properties live in the sibling .css files; these exports exist so
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,sFAAsF;AACtF,MAAM,CAAC,MAAM,MAAM,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,CAAU,CAAC;AAK3D;;;;;;;;;;GAUG;AACH,MAAM,CAAC,MAAM,OAAO,GAAG;IACrB,MAAM,EAAE,SAAS;IACjB,IAAI,EAAE,SAAS;IACf,IAAI,EAAE,SAAS;IACf,MAAM,EAAE,SAAS;IACjB,IAAI,EAAE,SAAS;IACf,GAAG,EAAE,SAAS;IACd,MAAM,EAAE,SAAS;IACjB,KAAK,EAAE,SAAS;CACR,CAAC;AAEX;;;;GAIG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG;IAC1B,MAAM,EAAE,SAAS;IACjB,IAAI,EAAE,SAAS;IACf,IAAI,EAAE,SAAS;IACf,MAAM,EAAE,SAAS;IACjB,IAAI,EAAE,SAAS;IACf,GAAG,EAAE,SAAS;IACd,MAAM,EAAE,SAAS;IACjB,KAAK,EAAE,SAAS;CACR,CAAC;AAKX,4DAA4D;AAC5D,MAAM,UAAU,SAAS,CAAC,MAAc,EAAE,KAAoB;IAC5D,OAAO,KAAK,KAAK,MAAM,CAAC,CAAC,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;AACnE,CAAC;AAED,qCAAqC;AACrC,MAAM,CAAC,MAAM,SAAS,GAAG,CAAC,aAAa,EAAE,SAAS,CAAU,CAAC;AAG7D,4EAA4E;AAC5E,MAAM,CAAC,MAAM,IAAI,GAAG,CAAC,KAAK,EAAE,KAAK,CAAU,CAAC;AAG5C,mFAAmF;AACnF,MAAM,CAAC,MAAM,WAAW,GAAG;IACzB,SAAS;IACT,SAAS;IACT,SAAS;IACT,SAAS;IACT,SAAS;IACT,SAAS;IACT,SAAS;IACT,SAAS;CACD,CAAC;AAEX,uEAAuE;AACvE,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAU,CAAC;AAE1E;;;;GAIG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG;IAC9B,KAAK,EAAE,YAAY;IACnB,MAAM,EAAE,aAAa;IACrB,OAAO,EAAE,cAAc;IACvB,GAAG,EAAE,KAAK;IACV,IAAI,EAAE,MAAM;CACJ,CAAC;AAEX;;;GAGG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG;IAC1B,KAAK,EAAE,gBAAgB;IACvB,MAAM,EAAE,iBAAiB;IACzB,OAAO,EAAE,kBAAkB;IAC3B,MAAM,EAAE,iBAAiB;IACzB,GAAG,EAAE,cAAc;CACX,CAAC;AAEX,8DAA8D;AAC9D,MAAM,CAAC,MAAM,aAAa,GAAG;IAC3B,KAAK,EAAE,QAAQ;IACf,MAAM,EAAE,QAAQ;IAChB,OAAO,EAAE,aAAa;IACtB,MAAM,EAAE,OAAO;CACP,CAAC;AAEX,OAAO,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,yCAAyC;AACzC;;;;;GAKG;AAEH,sFAAsF;AACtF,MAAM,CAAC,MAAM,MAAM,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,CAAU,CAAC;AAK3D;;;;;;;;;;GAUG;AACH,MAAM,CAAC,MAAM,OAAO,GAAG;IACrB,MAAM,EAAE,SAAS;IACjB,IAAI,EAAE,SAAS;IACf,IAAI,EAAE,SAAS;IACf,MAAM,EAAE,SAAS;IACjB,IAAI,EAAE,SAAS;IACf,GAAG,EAAE,SAAS;IACd,MAAM,EAAE,SAAS;IACjB,KAAK,EAAE,SAAS;CACR,CAAC;AAEX;;;;GAIG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG;IAC1B,MAAM,EAAE,SAAS;IACjB,IAAI,EAAE,SAAS;IACf,IAAI,EAAE,SAAS;IACf,MAAM,EAAE,SAAS;IACjB,IAAI,EAAE,SAAS;IACf,GAAG,EAAE,SAAS;IACd,MAAM,EAAE,SAAS;IACjB,KAAK,EAAE,SAAS;CACR,CAAC;AAKX,4DAA4D;AAC5D,MAAM,UAAU,SAAS,CAAC,MAAc,EAAE,KAAoB;IAC5D,OAAO,KAAK,KAAK,MAAM,CAAC,CAAC,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;AACnE,CAAC;AAED,qCAAqC;AACrC,MAAM,CAAC,MAAM,SAAS,GAAG,CAAC,aAAa,EAAE,SAAS,CAAU,CAAC;AAG7D,4EAA4E;AAC5E,MAAM,CAAC,MAAM,IAAI,GAAG,CAAC,KAAK,EAAE,KAAK,CAAU,CAAC;AAG5C,mFAAmF;AACnF,MAAM,CAAC,MAAM,WAAW,GAAG;IACzB,SAAS;IACT,SAAS;IACT,SAAS;IACT,SAAS;IACT,SAAS;IACT,SAAS;IACT,SAAS;IACT,SAAS;CACD,CAAC;AAEX,uEAAuE;AACvE,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAU,CAAC;AAE1E;;;;GAIG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG;IAC9B,KAAK,EAAE,YAAY;IACnB,MAAM,EAAE,aAAa;IACrB,OAAO,EAAE,cAAc;IACvB,GAAG,EAAE,KAAK;IACV,IAAI,EAAE,MAAM;CACJ,CAAC;AAEX;;;GAGG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG;IAC1B,KAAK,EAAE,gBAAgB;IACvB,MAAM,EAAE,iBAAiB;IACzB,OAAO,EAAE,kBAAkB;IAC3B,MAAM,EAAE,iBAAiB;IACzB,GAAG,EAAE,cAAc;CACX,CAAC;AAEX,8DAA8D;AAC9D,MAAM,CAAC,MAAM,aAAa,GAAG;IAC3B,KAAK,EAAE,QAAQ;IACf,MAAM,EAAE,QAAQ;IAChB,OAAO,EAAE,aAAa;IACtB,MAAM,EAAE,OAAO;CACP,CAAC;AAEX,OAAO,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"pre-hydration.d.ts","sourceRoot":"","sources":["../src/pre-hydration.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,kBAAkB,QAauC,CAAC"}
1
+ {"version":3,"file":"pre-hydration.d.ts","sourceRoot":"","sources":["../src/pre-hydration.ts"],"names":[],"mappings":"AACA;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,kBAAkB,QAauC,CAAC"}
@@ -1,3 +1,4 @@
1
+ // SPDX-License-Identifier: AGPL-3.0-only
1
2
  /**
2
3
  * Pre-hydration script — flash prevention. See 02-design-system.md §4.3.
3
4
  *
@@ -1 +1 @@
1
- {"version":3,"file":"pre-hydration.js","sourceRoot":"","sources":["../src/pre-hydration.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAC7B,gEAAgE;IAChE,8CAA8C;IAC9C,sFAAsF;IACtF,iCAAiC;IACjC,uEAAuE;IACvE,8EAA8E;IAC9E,kCAAkC;IAClC,2CAA2C;IAC3C,qCAAqC;IACrC,mEAAmE;IACnE,6EAA6E;IAC7E,8BAA8B;IAC9B,oEAAoE,CAAC"}
1
+ {"version":3,"file":"pre-hydration.js","sourceRoot":"","sources":["../src/pre-hydration.ts"],"names":[],"mappings":"AAAA,yCAAyC;AACzC;;;;;;;;;;;;GAYG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAC7B,gEAAgE;IAChE,8CAA8C;IAC9C,sFAAsF;IACtF,iCAAiC;IACjC,uEAAuE;IACvE,8EAA8E;IAC9E,kCAAkC;IAClC,2CAA2C;IAC3C,qCAAqC;IACrC,mEAAmE;IACnE,6EAA6E;IAC7E,8BAA8B;IAC9B,oEAAoE,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adminiumjs/tokens",
3
- "version": "0.2.1",
3
+ "version": "0.2.2",
4
4
  "license": "AGPL-3.0-only",
5
5
  "repository": {
6
6
  "type": "git",
package/src/accents.css CHANGED
@@ -83,7 +83,9 @@
83
83
  --surface-3, both live in the axe sweep (active nav rows, sticky headers, chips).
84
84
  --accent-selection was 22% — an earlier note here claimed it "keeps --fg at >=9.9:1", which
85
85
  is true and beside the point: ::selection paints over WHATEVER text the user drags across,
86
- including secondary and tertiary copy, which measured 4.36:1 and 3.33:1.
86
+ including secondary and tertiary copy, which measured 4.36:1 and 3.33:1. Lowering it to 12%
87
+ fixed that ON A PLAIN SURFACE and nowhere else — see THE SELECTION PAIR below, which is why
88
+ the token is no longer translucent at all.
87
89
  --accent-border was 25% — and the note here asserted it "has no consumer … so no WCAG
88
90
  obligation attaches". The first half is still literally true of the TOKEN (no `bg-`/
89
91
  `border-accent-border` utility and no var(--accent-border) read outside tailwind.css), but
@@ -100,8 +102,27 @@
100
102
  :root {
101
103
  --accent: var(--accent-light);
102
104
  --accent-soft: color-mix(in srgb, var(--accent) 10%, transparent);
105
+ /* The accent half of THE OPAQUE CHIP TINTS (tokens.css states the reasoning once, for all five
106
+ tones). Same 10% as the wash above, but mixed with --surface instead of `transparent`, so an
107
+ accent chip's contrast is a property of the token rather than of whatever it was re-parented
108
+ onto. --accent-soft itself is UNCHANGED and still translucent: active nav rows, selected table
109
+ rows and panel washes have to layer, and layering is exactly what a chip must not do. */
110
+ --accent-soft-solid: color-mix(in srgb, var(--accent) 10%, var(--surface));
103
111
  --accent-hover: color-mix(in srgb, var(--accent) 82%, #000);
104
- --accent-selection: color-mix(in srgb, var(--accent) 12%, transparent);
112
+ /* THE SELECTION PAIR — the same pre-composition as the chip tints, for the same reason, plus a
113
+ pinned foreground. tokens.css `::selection` sets BOTH halves; read the note there first.
114
+ A translucent selection tint is the worst case of "contrast depends on what it lands on",
115
+ because the user chooses the backdrop by dragging: 12% over --surface is the number this
116
+ comment used to quote, but the same wash over an ALREADY tinted row (a selected table row or
117
+ an active nav item, both --accent-soft) measured 3.474:1 for --fg-subtle and 3.892:1 for
118
+ --accent, and over a primary button's fill it put --fg at 1.080:1 (monochrome accent; 2.78:1 on
119
+ indigo). Freezing the backdrop into
120
+ the token, exactly as the chips do, makes the pair a property of the palette: --fg on it now
121
+ measures >=13.038:1 in every theme x accent x scope, on every surface AND on --accent itself.
122
+ The `selection` group in scripts/contrast-check.mjs measures all of it, including the
123
+ button-fill backdrop no other group covers. 12% is unchanged, and over a plain --surface the
124
+ colour is byte-identical to the translucent version — only the layered cases move. */
125
+ --accent-selection: color-mix(in srgb, var(--accent) 12%, var(--surface));
105
126
  --accent-border: color-mix(in srgb, var(--accent) 12%, transparent);
106
127
  --accent-glow: 0 2px 8px color-mix(in srgb, var(--accent) 36%, transparent);
107
128
  }
@@ -121,5 +142,7 @@
121
142
  [data-theme="dark"] {
122
143
  --accent: var(--accent-dark);
123
144
  --accent-soft: color-mix(in srgb, var(--accent) 12%, transparent);
145
+ /* 12% here too, matching the dark wash — a chip on --surface is byte-identical to before. */
146
+ --accent-soft-solid: color-mix(in srgb, var(--accent) 12%, var(--surface));
124
147
  --accent-hover: color-mix(in srgb, var(--accent) 88%, #fff);
125
148
  }
package/src/density.css CHANGED
@@ -5,12 +5,29 @@
5
5
  --row-py: 13px;
6
6
  --cell-fs: 13px;
7
7
  --card-pad: 20px;
8
- --main-pad: 26px 28px 40px;
8
+ /* Widget cards run tighter than a generic Card: every `.nb-card` in the
9
+ Analytics comp is a flat 18px box, where --card-pad's 20px is the comp's
10
+ HERO tier. Kept separate so the two can't drift into one number — and so
11
+ the opt-in `bleed` config flag has exactly one knob to zero out. */
12
+ --widget-pad: 18px;
13
+ /* The one page gutter. Split into axes because the page-padding choice an
14
+ admin makes in Studio is an x/y pair, and a shorthand cannot be overridden
15
+ one axis at a time. The shorthand stays derived so `p-[var(--main-pad)]`
16
+ call sites keep working. Bottom is no longer a third, larger value: a
17
+ 40px floor under a 24px ceiling read as a mistake on every short page. */
18
+ --main-pad-x: 28px;
19
+ --main-pad-y: 24px;
20
+ --main-pad: var(--main-pad-y) var(--main-pad-x);
9
21
  }
10
22
 
11
23
  [data-density="compact"] {
12
24
  --row-py: 7px;
13
25
  --cell-fs: 12px;
14
26
  --card-pad: 16px;
15
- --main-pad: 16px 20px 30px;
27
+ /* The comp has no compact mode; 14px keeps the comfortable→compact ratio the
28
+ hand-rolled `px-4 → compact:px-3` pair used before the token existed. */
29
+ --widget-pad: 14px;
30
+ --main-pad-x: 20px;
31
+ --main-pad-y: 16px;
32
+ --main-pad: var(--main-pad-y) var(--main-pad-x);
16
33
  }
@@ -35,8 +35,12 @@
35
35
  --accent: var(--accent-dark);
36
36
  --accent-fg: #0f0f14;
37
37
  --accent-soft: color-mix(in srgb, var(--accent) 12%, transparent);
38
+ --accent-soft-solid: color-mix(in srgb, var(--accent) 12%, var(--surface));
38
39
  --accent-hover: color-mix(in srgb, var(--accent) 88%, #fff);
39
- --accent-selection: color-mix(in srgb, var(--accent) 12%, transparent);
40
+ /* Pre-composited against THIS scope's --surface, not the root's (accents.css, THE SELECTION
41
+ PAIR). A selection tint left to the root would arrive mixed with the page's surface and
42
+ paint a light pill inside a dark code block. */
43
+ --accent-selection: color-mix(in srgb, var(--accent) 12%, var(--surface));
40
44
  --accent-border: color-mix(in srgb, var(--accent) 12%, transparent);
41
45
  --pos: #3ecf8e;
42
46
  --pos-soft: rgba(62,207,142,.14);
@@ -46,6 +50,13 @@
46
50
  --danger-soft: rgba(255,107,107,.14);
47
51
  --info: #6ea8ff;
48
52
  --info-soft: rgba(110,168,255,.14);
53
+ /* The `-soft-solid` chip tints are PRE-COMPOSITED over --surface, so they must be re-declared
54
+ here for the same reason --accent-soft is: a value left to the root would arrive already
55
+ mixed with the ROOT's --surface — a near-white pill inside a #0f0f14 code block. */
56
+ --pos-soft-solid: color-mix(in srgb, var(--pos) 14%, var(--surface));
57
+ --warn-soft-solid: color-mix(in srgb, var(--warn) 14%, var(--surface));
58
+ --danger-soft-solid: color-mix(in srgb, var(--danger) 14%, var(--surface));
59
+ --info-soft-solid: color-mix(in srgb, var(--info) 14%, var(--surface));
49
60
  --shadow: 0 1px 2px rgba(0,0,0,.4);
50
61
  --shadow-md: 0 6px 20px rgba(0,0,0,.5);
51
62
  --shadow-lg: 0 16px 40px rgba(0,0,0,.6);
@@ -79,8 +90,10 @@
79
90
  --accent: var(--accent-light);
80
91
  --accent-fg: #ffffff;
81
92
  --accent-soft: color-mix(in srgb, var(--accent) 10%, transparent);
93
+ --accent-soft-solid: color-mix(in srgb, var(--accent) 10%, var(--surface));
82
94
  --accent-hover: color-mix(in srgb, var(--accent) 82%, #000);
83
- --accent-selection: color-mix(in srgb, var(--accent) 12%, transparent);
95
+ /* Pre-composited against THIS scope's --surface — see the .adm-always-dark note above. */
96
+ --accent-selection: color-mix(in srgb, var(--accent) 12%, var(--surface));
84
97
  --accent-border: color-mix(in srgb, var(--accent) 12%, transparent);
85
98
  --pos: #0b7d59;
86
99
  --pos-soft: #e6f5ee;
@@ -90,6 +103,13 @@
90
103
  --danger-soft: #fdecec;
91
104
  --info: #1c59e0;
92
105
  --info-soft: #e7edfd;
106
+ /* Opaque already (light's semantic softs are hexes), so these alias rather than re-derive —
107
+ but they still have to be DECLARED here, or the scope would inherit the root's, which under
108
+ a dark root are 14% mixes over #141419. */
109
+ --pos-soft-solid: var(--pos-soft);
110
+ --warn-soft-solid: var(--warn-soft);
111
+ --danger-soft-solid: var(--danger-soft);
112
+ --info-soft-solid: var(--info-soft);
93
113
  --shadow: 0 1px 2px rgba(20,20,35,.04), 0 1px 3px rgba(20,20,35,.05);
94
114
  --shadow-md: 0 4px 14px rgba(20,20,35,.09);
95
115
  --shadow-lg: 0 12px 34px rgba(20,20,35,.13);
package/src/index.ts CHANGED
@@ -1,3 +1,4 @@
1
+ // SPDX-License-Identifier: AGPL-3.0-only
1
2
  /**
2
3
  * @adminium/tokens — JS-side constants for the four theming axes plus the pre-hydration
3
4
  * script. CSS custom properties live in the sibling .css files; these exports exist so
package/src/motion.css CHANGED
@@ -84,6 +84,21 @@
84
84
  border-color: var(--border-strong);
85
85
  }
86
86
 
87
+ /* card hover bloom: shadow only, NO lift. Distinct from .nb-lift on purpose —
88
+ a dashboard is ~40 cards, and translating each one on mouseover reads as
89
+ noise. Matches the comp's `.nb-card:hover` (Analytics.dc.html lines 32-33).
90
+ The dark value has no comp counterpart (the comp's dark block never restates
91
+ it); it is the light recipe re-tuned for a #141419 surface. */
92
+ .nb-cardh {
93
+ transition: box-shadow .16s ease, border-color .16s ease;
94
+ }
95
+ .nb-cardh:hover {
96
+ box-shadow: 0 6px 18px -10px rgba(20, 20, 35, .24);
97
+ }
98
+ [data-theme="dark"] .nb-cardh:hover {
99
+ box-shadow: 0 6px 18px -10px rgba(0, 0, 0, .6);
100
+ }
101
+
87
102
  /* button press: hover brighten, active shrink */
88
103
  .nb-press {
89
104
  transition: transform .12s ease, filter .12s ease;
@@ -1,3 +1,4 @@
1
+ // SPDX-License-Identifier: AGPL-3.0-only
1
2
  /**
2
3
  * Pre-hydration script — flash prevention. See 02-design-system.md §4.3.
3
4
  *
package/src/tailwind.css CHANGED
@@ -22,12 +22,20 @@
22
22
  --color-accent: var(--accent);
23
23
  --color-accent-fg: var(--accent-fg);
24
24
  --color-accent-soft: var(--accent-soft);
25
+ --color-accent-soft-solid: var(--accent-soft-solid);
25
26
  --color-accent-hover: var(--accent-hover);
26
27
  --color-accent-border: var(--accent-border);
27
28
  --color-pos: var(--pos); --color-pos-soft: var(--pos-soft);
28
29
  --color-warn: var(--warn); --color-warn-soft: var(--warn-soft);
29
30
  --color-danger: var(--danger); --color-danger-soft: var(--danger-soft);
30
31
  --color-info: var(--info); --color-info-soft: var(--info-soft);
32
+ /* `bg-*-soft-solid` — the pre-composited chip tints (tokens.css, THE OPAQUE CHIP TINTS).
33
+ Mapped alongside the washes, not instead of them: `bg-*-soft` still paints the translucent
34
+ row/panel wash, and a chip that must clear 4.5:1 wherever it lands takes the solid one. */
35
+ --color-pos-soft-solid: var(--pos-soft-solid);
36
+ --color-warn-soft-solid: var(--warn-soft-solid);
37
+ --color-danger-soft-solid: var(--danger-soft-solid);
38
+ --color-info-soft-solid: var(--info-soft-solid);
31
39
  --color-viz-1: var(--viz-1); --color-viz-2: var(--viz-2); --color-viz-3: var(--viz-3);
32
40
  --color-viz-4: var(--viz-4); --color-viz-5: var(--viz-5); --color-viz-6: var(--viz-6);
33
41
  --color-viz-7: var(--viz-7); --color-viz-8: var(--viz-8);
@@ -51,6 +59,11 @@
51
59
  --text-title: 20px; --text-title--font-weight: 800; --text-title--letter-spacing: -0.02em;
52
60
  --text-modal: 16.5px; --text-modal--font-weight: 800;
53
61
  --text-section: 14.5px; --text-section--font-weight: 700; --text-section--letter-spacing: -0.01em;
62
+ /* Widget-card and topbar headings. Neither can reuse --text-section: the comp's
63
+ card title carries NO tracking (14px/700 flat) and its topbar h1 is a full
64
+ tier larger and heavier (18px/800/-0.02em). */
65
+ --text-card-title: 14px; --text-card-title--font-weight: 700;
66
+ --text-topbar-title: 18px; --text-topbar-title--font-weight: 800; --text-topbar-title--letter-spacing: -0.02em;
54
67
  --text-body: 13px; --text-body--line-height: 1.5;
55
68
  --text-body-sm: 12.5px; --text-body-sm--line-height: 1.5;
56
69
  --text-caption: 11.5px;
@@ -59,5 +72,13 @@
59
72
  /* layout */
60
73
  --spacing-sidebar: 256px;
61
74
  --container-form: 640px; --container-narrow: 720px; --container-page: 1080px;
62
- --container-marketing: 1160px; --container-wide: 1200px; --container-max: 1360px;
75
+ --container-marketing: 1160px; --container-wide: 1200px; --container-max: 1360px; --container-widest: 1800px;
76
+ /* The reading column for pages whose content is a short stack of controls
77
+ rather than a grid — import, settings, account. Wide enough for a two-up
78
+ field row, narrow enough that a lone label does not run the full monitor.
79
+ `--container-narrow` (720px) is a text measure and squeezes those rows. */
80
+ --container-content: 900px;
81
+ /* Dashboard column. Deliberately NOT --container-page (1080px), which form and
82
+ settings pages depend on staying narrow. */
83
+ --container-dash: 1320px;
63
84
  }
package/src/tokens.css CHANGED
@@ -60,6 +60,27 @@
60
60
  --danger-soft: #fdecec;
61
61
  --info: #1c59e0;
62
62
  --info-soft: #e7edfd;
63
+ /* THE OPAQUE CHIP TINTS. `-soft` is a WASH — row highlights, panel fills, callout backgrounds —
64
+ and stays translucent so it can layer. `-soft-solid` is that same tint PRE-COMPOSITED over
65
+ --surface, for the small tinted CHIPS whose own label has to clear 4.5:1 no matter where the
66
+ chip lands.
67
+ A translucent chip has no contrast of its own: it inherits whatever it was re-parented onto.
68
+ The same "Canceled" tag therefore measured one number on a plain table row and another on a
69
+ selected (already-tinted) one, and a nav count badge fell to 4.36:1 at the exact moment its
70
+ row went active — a tint over a tint. The pair matrix in scripts/contrast-check.mjs cannot
71
+ enumerate that case: it knows the four surfaces a tint can composite over, but not that a
72
+ component will be nested inside ANOTHER component's tint. Freezing the backdrop into the
73
+ token moves the chip's contrast out of the DOM and into a value, where the gate can prove it.
74
+ THE COST, accepted deliberately: a chip on a --surface-2 or --surface-3 card now paints a
75
+ --surface-based pill, so it reads a shade lighter than the card under it. That is the trade
76
+ for a number that cannot vary with nesting.
77
+ Light's semantic softs are ALREADY opaque hexes, so these alias them rather than deriving the
78
+ same colour a second way — two spellings of one colour is a drift bug waiting to happen. Only
79
+ dark has to composite; see the dark block. */
80
+ --pos-soft-solid: var(--pos-soft);
81
+ --warn-soft-solid: var(--warn-soft);
82
+ --danger-soft-solid: var(--danger-soft);
83
+ --info-soft-solid: var(--info-soft);
63
84
  --shadow: 0 1px 2px rgba(20,20,35,.04), 0 1px 3px rgba(20,20,35,.05);
64
85
  --shadow-md: 0 4px 14px rgba(20,20,35,.09);
65
86
  --shadow-lg: 0 12px 34px rgba(20,20,35,.13);
@@ -101,11 +122,34 @@
101
122
  --danger-soft: rgba(255,107,107,.14);
102
123
  --info: #6ea8ff;
103
124
  --info-soft: rgba(110,168,255,.14);
125
+ /* The opaque chip tints (see the light block for why they exist). Dark's semantic softs are
126
+ translucent, so these composite the SAME 14% over --surface that the wash reaches there —
127
+ a chip already sitting on --surface is byte-identical before and after; only chips on the
128
+ deeper greys change, which is the appearance cost named above. */
129
+ --pos-soft-solid: color-mix(in srgb, var(--pos) 14%, var(--surface));
130
+ --warn-soft-solid: color-mix(in srgb, var(--warn) 14%, var(--surface));
131
+ --danger-soft-solid: color-mix(in srgb, var(--danger) 14%, var(--surface));
132
+ --info-soft-solid: color-mix(in srgb, var(--info) 14%, var(--surface));
104
133
  --shadow: 0 1px 2px rgba(0,0,0,.4);
105
134
  --shadow-md: 0 6px 20px rgba(0,0,0,.5);
106
135
  --shadow-lg: 0 16px 40px rgba(0,0,0,.6);
107
136
  }
108
137
 
138
+ /* ::selection SETS BOTH HALVES OF THE PAIR, and that is the whole point.
139
+ Left to the browser, only the background was ours and the foreground was "whatever text the
140
+ user happened to drag across" — so the selection pair was undefined by construction and no gate
141
+ could state it. Measured on the palette before this: --fg-subtle on the selection wash over a
142
+ selected table row 3.474:1, --accent on it over an active sidebar row 3.892:1, and --fg over a
143
+ primary button's accent fill 1.080:1 (monochrome accent; 2.78:1 on indigo — near-invisible either way). axe never sees any of that: it does not
144
+ evaluate ::selection, so none of it appeared in the sweep — a real low-vision failure with no
145
+ automated witness, which is exactly the kind this palette keeps having to find by measuring.
146
+ With --accent-selection pre-composited (accents.css, THE SELECTION PAIR) and the colour pinned
147
+ to the theme's own --fg, the pair is fixed at >=13.038:1 everywhere, including inside the
148
+ .adm-always-dark / .adm-always-light scopes, which re-declare both tokens together.
149
+ THE COST, accepted: selected text loses its own colour for as long as it is selected — an
150
+ accent link or a --pos status reads as body text under the highlight. That is what every
151
+ browser's default selection does, and it is the price of a pair that cannot be composed away. */
109
152
  ::selection {
110
153
  background: var(--accent-selection);
154
+ color: var(--fg);
111
155
  }