@celestia-island/hikari 0.55.127 → 0.55.130

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@celestia-island/hikari",
3
- "version": "0.55.127",
3
+ "version": "0.55.130",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "description": "Hikari Vue 3 component library — production-grade UI components based on shittim-chest design system",
@@ -93,6 +93,87 @@
93
93
  color: #fff;
94
94
  }
95
95
 
96
+ // ── Actions on a tinted surface ─────────────────────────────────────
97
+ // The card's surface IS the variant color, so the action row takes its
98
+ // ink from that surface instead of leaking the global accent: a plain
99
+ // primary button reads as a foreign brand on the tinted card (a pink
100
+ // confirm on the teal info card under a pink-themed consumer), and the
101
+ // danger confirm's own red dissolves into its red card. The confirm
102
+ // inverts to a filled white control labeled in a deepened shade of the
103
+ // variant color — the strongest move on every variant surface — and the
104
+ // cancel quiets to a translucent outline in the card's own ink (the
105
+ // house grammar for quiet controls on tinted toast surfaces).
106
+ .hk-blocking-toast-info {
107
+ --hk-blocking-toast-ink: var(--hi-color-info, #6abed6);
108
+ }
109
+
110
+ .hk-blocking-toast-warning {
111
+ --hk-blocking-toast-ink: var(--hi-color-warning, #eed677);
112
+ }
113
+
114
+ .hk-blocking-toast-danger {
115
+ --hk-blocking-toast-ink: var(--hi-color-danger, #f85149);
116
+ }
117
+
118
+ /* The confirm arrives as .hk-btn-primary (info/warning cards) or
119
+ .hk-btn-danger (danger card) — both recolor to the same inverted
120
+ control. Labels darken the variant ink (55% toward black) so every
121
+ variant stays readable on the white fill; svg rides the label color
122
+ so a themed glyph ink can't wash out against it. */
123
+ .hk-blocking-toast-actions .hk-btn-primary,
124
+ .hk-blocking-toast-actions .hk-btn-danger {
125
+ background: #fff;
126
+ border-color: transparent;
127
+ color: color-mix(in srgb, var(--hk-blocking-toast-ink, #6abed6) 55%, #000);
128
+
129
+ svg {
130
+ color: inherit;
131
+ }
132
+ }
133
+
134
+ .hk-blocking-toast-actions .hk-btn-primary:hover:not(:disabled):not(:focus-visible),
135
+ .hk-blocking-toast-actions .hk-btn-danger:hover:not(:disabled):not(:focus-visible) {
136
+ filter: none;
137
+ box-shadow: none;
138
+ background: rgb(255 255 255 / 88%);
139
+ }
140
+
141
+ .hk-blocking-toast-actions .hk-btn-primary:active:not(:disabled),
142
+ .hk-blocking-toast-actions .hk-btn-danger:active:not(:disabled) {
143
+ filter: none;
144
+ background: rgb(255 255 255 / 78%);
145
+ }
146
+
147
+ /* The secondary cancel stops being a heavy surface block (it rendered
148
+ as a white pill competing with the confirm on the tinted card) and
149
+ picks up the quiet outline in the card's currentColor — white on
150
+ info/danger, near-black on warning — so it reads on every variant
151
+ without its own per-variant table. */
152
+ .hk-blocking-toast-actions .hk-btn-secondary {
153
+ background: transparent;
154
+ border-color: color-mix(in srgb, currentColor 45%, transparent);
155
+ backdrop-filter: none;
156
+ color: inherit;
157
+ }
158
+
159
+ .hk-blocking-toast-actions .hk-btn-secondary:hover:not(:disabled) {
160
+ border-color: color-mix(in srgb, currentColor 70%, transparent);
161
+ background: color-mix(in srgb, currentColor 18%, transparent);
162
+ }
163
+
164
+ .hk-blocking-toast-actions .hk-btn-secondary:active:not(:disabled) {
165
+ filter: none;
166
+ background: color-mix(in srgb, currentColor 28%, transparent);
167
+ }
168
+
169
+ /* The keyboard ring follows the card ink too — the global primary ring
170
+ would leak the same foreign accent the fill just removed. */
171
+ .hk-blocking-toast-actions .hk-btn:focus-visible {
172
+ box-shadow:
173
+ 0 0 0 2px rgb(255 255 255 / 60%),
174
+ 0 0 0 4px currentColor;
175
+ }
176
+
96
177
  // Enter/leave mirrors the toast slide (settle, no bounce); leaving
97
178
  // cards go absolute so the remaining ones glide up (hk-toast pattern).
98
179
  .hk-blocking-toast-enter-active {
@@ -18,8 +18,20 @@ import type { SurfacePhase } from "../runtime/surfaceMachine";
18
18
  * always plays over the content the user was actually looking at. Vue's
19
19
  * patch skips identical vnode references, so the held DOM is never
20
20
  * re-patched during the close; child components with their own store
21
- * subscriptions may still self-update (harmless — the failure mode under
22
- * repair is content VANISHING, not content ticking).
21
+ * subscriptions may still self-update.
22
+ *
23
+ * ⚠️ CONTRACT for bodies under this hold (the 2026-10-06 chest crash:
24
+ * `TypeError: Cannot read properties of null (reading 'content')` in a
25
+ * report window's close fold): a held child that subscribed to the body's
26
+ * reactive reads re-renders with the FROZEN slot closures, so any slot
27
+ * body that re-reads a live ref at invocation time sees the host's
28
+ * teardown null and throws. The "self-updates are harmless" claim the
29
+ * original comment made is wrong in exactly that case. Bodies must render
30
+ * a per-render SNAPSHOT of their nullable state (read it once in the
31
+ * render function, hand the captured value to every deferred closure) —
32
+ * never re-read the live ref inside a slot or callback the fold can
33
+ * re-run. (The failure mode under repair remains content VANISHING; a
34
+ * throwing deferred read is the second, sharper failure mode.)
23
35
  *
24
36
  * The hold releases the moment the surface leaves a closing phase: a
25
37
  * reopen interrupt (closing → openingFrom) serves live slots again, and
package/src/scale.scss CHANGED
@@ -7,7 +7,7 @@
7
7
  * foundation) were normalized to the values the production composition
8
8
  * resolves to (chest: admin-tokens + foundation last). This file is the
9
9
  * upstream of styles/theme/scale.scss — edit here, then re-run
10
- * scripts/theme/sync-vendored.sh; do not hand-edit the vendored copy.
10
+ * scripts/theme/sync-vendored.py; do not hand-edit the vendored copy.
11
11
  */
12
12
  :root {
13
13
  /* Spacing (N px at the 16px root). */
@@ -9,7 +9,7 @@
9
9
  * foundation) were normalized to the values the production composition
10
10
  * resolves to (chest: admin-tokens + foundation last). This file is the
11
11
  * upstream of styles/theme/scale.scss — edit here, then re-run
12
- * scripts/theme/sync-vendored.sh; do not hand-edit the vendored copy.
12
+ * scripts/theme/sync-vendored.py; do not hand-edit the vendored copy.
13
13
  */
14
14
  :root {
15
15
  /* Spacing (N px at the 16px root). */
@@ -16,7 +16,7 @@ import { describe, expect, it } from "vitest";
16
16
  *
17
17
  * The re-copy adds exactly one provenance header comment block; everything
18
18
  * after it must match the upstream byte-for-byte. Edit the UPSTREAM, then
19
- * re-run scripts/theme/sync-vendored.sh — never hand-edit the copies.
19
+ * re-run scripts/theme/sync-vendored.py — never hand-edit the copies.
20
20
  */
21
21
 
22
22
  const stylesDir = resolve(dirname(fileURLToPath(import.meta.url)));