@tangle-network/brand 0.8.0 → 0.8.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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,26 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.8.2
4
+
5
+ ### Patch Changes
6
+
7
+ - 26cc012: WCAG 1.4.3 AA contrast fixes across all 7 themes (measured with a cascade-resolved contrast audit).
8
+
9
+ - **Primary buttons**: `text-primary-foreground` on `bg-primary` was below 4.5:1 in `dark` (4.41) and `arena-light` (4.20). Darkened those two primaries (dark L 67%→62%, arena-light L 30%→27%) — all 7 themes now ≥5.0:1, hue unchanged.
10
+ - **Status colors in the named light themes**: `aubergine-light` / `arena-light` / `tangle-light` inherited the dark `:root` bright status palette (`#f87171`/`#34D399`/…), so danger/success text + glyphs dropped to ~2.5:1 on their light surfaces. Added a shared light-tuned status palette (dark-on-light text, mirroring the base light theme) — status text now passes AA and glyphs pass 1.4.11.
11
+ - **Running tool state**: the "running" label + spinner used `text-primary`, which fell to 2.98:1 on the dark row surface. Switched to `--accent-text` (the readable accent tier) — passes in every theme.
12
+ - **Thinking timer**: the elapsed-seconds counter used the faint `--text-dim` tier (~3:1). Moved it to `--text-muted` (passes AA everywhere).
13
+
14
+ Text now meets AA in all 7 themes; most pairs are AAA.
15
+
16
+ ## 0.8.1
17
+
18
+ ### Patch Changes
19
+
20
+ - d18fce7: Fix `[data-theme]` scopes not re-skinning components, and lift the aubergine palette off near-black so it reads as purple.
21
+
22
+ The named themes changed `--hsl-*` spine vars, but Tailwind utilities (`bg-card`, `bg-primary`, `border-border`, `bg-surface-container*`) read the `--color-*` layer, which is declared only at `:root` — so its computed neutral value was inherited by themed subtrees regardless of the spine override (a double-indirection custom-property inheritance trap). Each `[data-theme]` scope now redeclares the `--color-*` layer directly, forcing it to recompute from that element's own `--hsl-*`. Aubergine's base lightness is raised (~7%→12–20% L, higher saturation) so surfaces read aubergine-purple instead of black.
23
+
3
24
  ## 0.8.0
4
25
 
5
26
  ### Minor Changes
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tangle-network/brand",
3
- "version": "0.8.0",
3
+ "version": "0.8.2",
4
4
  "description": "Tangle brand system — design tokens, logo, Tailwind v4 theme. Single source of truth for every Tangle app.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -4,25 +4,79 @@
4
4
  * data-theme="<name>" on a wrapper (or <html>). The default :root / .dark spine
5
5
  * is the neutral "tangle" theme; "<name>-light" scopes are the light variants. */
6
6
 
7
+ /* Bridge — the actual re-skin mechanism. Tailwind utilities read the --color-*
8
+ * layer (theme.css @theme: `bg-card` → var(--color-card) = hsl(var(--card))).
9
+ * Both --color-* and its --card/--hsl-card source are declared only at :root, so
10
+ * a descendant [data-theme] that changes --hsl-card never re-substitutes the
11
+ * :root-computed --color-card the utility consumes — the value is frozen at the
12
+ * root color (double-indirection inheritance trap). Redeclaring the --color-*
13
+ * layer directly on any themed element forces each one to recompute from that
14
+ * element's own --hsl-*. Tokens a theme doesn't override fall back to the
15
+ * inherited neutral --hsl-* (all defined at :root), so this is always valid. */
16
+ [data-theme] {
17
+ --color-background: hsl(var(--hsl-background));
18
+ --color-foreground: hsl(var(--hsl-foreground));
19
+ --color-card: hsl(var(--hsl-card));
20
+ --color-card-foreground: hsl(var(--hsl-card-foreground));
21
+ --color-popover: hsl(var(--hsl-popover));
22
+ --color-popover-foreground: hsl(var(--hsl-popover-foreground));
23
+ --color-primary: hsl(var(--hsl-primary));
24
+ --color-primary-foreground: hsl(var(--hsl-primary-foreground));
25
+ --color-secondary: hsl(var(--hsl-secondary));
26
+ --color-secondary-foreground: hsl(var(--hsl-secondary-foreground));
27
+ --color-muted: hsl(var(--hsl-muted));
28
+ --color-muted-foreground: hsl(var(--hsl-muted-foreground));
29
+ --color-accent: hsl(var(--hsl-accent));
30
+ --color-accent-foreground: hsl(var(--hsl-accent-foreground));
31
+ --color-destructive: hsl(var(--hsl-destructive));
32
+ --color-destructive-foreground: hsl(var(--hsl-destructive-foreground));
33
+ --color-border: hsl(var(--hsl-border));
34
+ --color-input: hsl(var(--hsl-input));
35
+ --color-ring: hsl(var(--hsl-ring));
36
+ --color-surface-container-lowest: var(--md3-surface-container-lowest);
37
+ --color-surface-container-low: var(--md3-surface-container-low);
38
+ --color-surface-container: var(--md3-surface-container);
39
+ --color-surface-container-high: var(--md3-surface-container-high);
40
+ --color-surface-container-highest: var(--md3-surface-container-highest);
41
+ --color-fg: var(--text-primary);
42
+ --color-fg-muted: var(--text-muted);
43
+ --color-fg-dim: var(--text-dim);
44
+ }
45
+
46
+ /* Light-tuned status palette for the named light scopes. Without this they
47
+ * inherit the dark :root status colors (bright #f87171/#34D399/…), which fail
48
+ * WCAG on a light surface — status text + glyphs drop to ~2.5:1. These mirror
49
+ * tokens.css `[data-theme="light"]` (dark-on-light status text that passes AA). */
50
+ [data-theme="aubergine-light"],
51
+ [data-theme="arena-light"],
52
+ [data-theme="tangle-light"] {
53
+ --surface-success-bg: #ecfdf5; --surface-success-border: #a7f3d0; --surface-success-text: #047857;
54
+ --surface-warning-bg: #fffbeb; --surface-warning-border: #fde68a; --surface-warning-text: #b45309;
55
+ --surface-danger-bg: #fff1f2; --surface-danger-border: #fecdd3; --surface-danger-text: #b91c1c;
56
+ --surface-info-bg: #f0f9ff; --surface-info-border: #bae6fd; --surface-info-text: #0369a1;
57
+ }
58
+
7
59
  /* ───────────────────────── Aubergine (bazaar) — dark purple ──────────────── */
8
60
  [data-theme="aubergine"] {
9
- --hsl-background: 258 43% 7%; --hsl-foreground: 258 50% 97%;
10
- --hsl-card: 258 39% 19%; --hsl-card-foreground: 258 50% 97%;
11
- --hsl-popover: 258 37% 25%; --hsl-popover-foreground: 258 50% 97%;
12
- --hsl-primary: 232 100% 75%; --hsl-primary-foreground: 258 45% 8%;
13
- --hsl-secondary: 257 42% 13%; --hsl-muted: 257 42% 13%;
14
- --hsl-muted-foreground: 258 22% 64%;
15
- --hsl-accent: 258 39% 19%; --hsl-border: 258 28% 27%;
16
- --hsl-input: 257 42% 13%; --hsl-ring: 232 100% 75%;
17
- --depth-1: #0f0a1a; --depth-2: #1a1330; --depth-3: #271d42; --depth-4: #362858;
18
- --bg-root: #0f0a1a; --bg-card: var(--depth-3); --bg-input: var(--depth-2);
19
- --md3-surface-container-lowest: #140d24; --md3-surface-container-low: #1a1330;
20
- --md3-surface-container: #221842; --md3-surface-container-high: #271d42;
21
- --md3-surface-container-highest: #362858; --md3-outline-variant: #392d52;
22
- --border-subtle: rgba(183,157,255,0.10); --border-default: rgba(183,157,255,0.18);
23
- --border-hover: rgba(183,157,255,0.34); --accent-text: #b69dff;
24
- --brand-primary: #8090ff; --brand-glow: #b69dff;
25
- --text-primary: #f4f1fd; --text-secondary: #c6bcdf; --text-muted: #998fb6; --text-dim: #6c6289;
61
+ /* Base lifted off near-black: at ~7% L the 258 hue read black; ~13-20% L with
62
+ * higher saturation makes the surfaces read unmistakably aubergine-purple. */
63
+ --hsl-background: 258 44% 12%; --hsl-foreground: 258 50% 97%;
64
+ --hsl-card: 258 40% 20%; --hsl-card-foreground: 258 50% 97%;
65
+ --hsl-popover: 258 40% 24%; --hsl-popover-foreground: 258 50% 97%;
66
+ --hsl-primary: 250 100% 76%; --hsl-primary-foreground: 258 45% 10%;
67
+ --hsl-secondary: 258 38% 17%; --hsl-muted: 258 38% 17%;
68
+ --hsl-muted-foreground: 258 26% 70%;
69
+ --hsl-accent: 258 40% 24%; --hsl-border: 258 32% 30%;
70
+ --hsl-input: 258 38% 17%; --hsl-ring: 250 100% 76%;
71
+ --depth-1: #1a1230; --depth-2: #241a42; --depth-3: #2f2253; --depth-4: #3d2d68;
72
+ --bg-root: #1a1230; --bg-card: var(--depth-3); --bg-input: var(--depth-2);
73
+ --md3-surface-container-lowest: #150e28; --md3-surface-container-low: #241a42;
74
+ --md3-surface-container: #2a1f4c; --md3-surface-container-high: #2f2253;
75
+ --md3-surface-container-highest: #3d2d68; --md3-outline-variant: #463571;
76
+ --border-subtle: rgba(183,157,255,0.12); --border-default: rgba(183,157,255,0.22);
77
+ --border-hover: rgba(183,157,255,0.40); --accent-text: #c4b0ff;
78
+ --brand-primary: #8f8bff; --brand-glow: #c4b0ff;
79
+ --text-primary: #f4f1fd; --text-secondary: #cec4e8; --text-muted: #a99fc8; --text-dim: #786d99;
26
80
  }
27
81
  [data-theme="aubergine-light"] {
28
82
  --hsl-background: 258 60% 96%; --hsl-foreground: 258 45% 11%;
@@ -68,7 +122,7 @@
68
122
  --hsl-background: 150 30% 96%; --hsl-foreground: 158 30% 10%;
69
123
  --hsl-card: 0 0% 100%; --hsl-card-foreground: 158 30% 10%;
70
124
  --hsl-popover: 0 0% 100%; --hsl-popover-foreground: 158 30% 10%;
71
- --hsl-primary: 160 84% 30%; --hsl-primary-foreground: 0 0% 100%;
125
+ --hsl-primary: 160 84% 27%; --hsl-primary-foreground: 0 0% 100%;
72
126
  --hsl-secondary: 150 25% 92%; --hsl-muted: 150 25% 92%;
73
127
  --hsl-muted-foreground: 158 14% 40%;
74
128
  --hsl-accent: 150 25% 92%; --hsl-border: 150 20% 86%;
@@ -57,7 +57,7 @@
57
57
  --hsl-card-foreground: 240 6% 93%;
58
58
  --hsl-popover: 240 5% 17%; /* #28282d elevated */
59
59
  --hsl-popover-foreground: 240 6% 93%;
60
- --hsl-primary: 239 84% 67%;
60
+ --hsl-primary: 239 84% 62%;
61
61
  --hsl-primary-foreground: 0 0% 100%;
62
62
  --hsl-secondary: 240 5% 15%; /* #242428 surface-2 */
63
63
  --hsl-secondary-foreground: 240 6% 93%;