@celestia-island/hikari 0.55.239 → 0.55.241

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 (93) hide show
  1. package/package.json +1 -1
  2. package/src/components/HkAboutModal.scss +2 -1
  3. package/src/components/HkAlert.scss +3 -2
  4. package/src/components/HkAvatar.scss +3 -1
  5. package/src/components/HkBadge.scss +2 -2
  6. package/src/components/HkBlockingToast.scss +6 -6
  7. package/src/components/HkBoard.scss +3 -1
  8. package/src/components/HkBoard3D.scss +3 -1
  9. package/src/components/HkBreadcrumb.scss +2 -1
  10. package/src/components/HkButton.scss +3 -2
  11. package/src/components/HkCard.scss +2 -1
  12. package/src/components/HkCheckbox.scss +3 -1
  13. package/src/components/HkColorPicker.scss +5 -3
  14. package/src/components/HkConfirmDialog.scss +3 -2
  15. package/src/components/HkCopyBadge.test.tsx +1 -1
  16. package/src/components/HkDatePicker.scss +3 -2
  17. package/src/components/HkDateTimePicker.scss +2 -1
  18. package/src/components/HkDiffViewer.scss +6 -6
  19. package/src/components/HkDockBar.scss +4 -2
  20. package/src/components/HkDockBar.test.tsx +1 -1
  21. package/src/components/HkDraggableGrid.scss +4 -3
  22. package/src/components/HkDraggableList.scss +4 -3
  23. package/src/components/HkDrawer.scss +5 -4
  24. package/src/components/HkEmptyState.scss +3 -1
  25. package/src/components/HkEmptyState.surface.contract.test.ts +5 -2
  26. package/src/components/HkErrorLanding.scss +3 -1
  27. package/src/components/HkFab.scss +5 -2
  28. package/src/components/HkFaceShell.rail.test.tsx +285 -4
  29. package/src/components/HkFaceShell.tsx +14 -0
  30. package/src/components/HkImageLightbox.scss +3 -1
  31. package/src/components/HkImageViewer.scss +3 -1
  32. package/src/components/HkJsonTree.scss +3 -3
  33. package/src/components/HkLoadingVeil.scss +4 -2
  34. package/src/components/HkLogWindow.scss +2 -2
  35. package/src/components/HkLogo.scss +3 -1
  36. package/src/components/HkMarkdownRenderer.scss +3 -3
  37. package/src/components/HkMediaControlBar.scss +4 -2
  38. package/src/components/HkMediaSlider.scss +3 -1
  39. package/src/components/HkMenu.rail.test.tsx +29 -0
  40. package/src/components/HkMenu.tsx +62 -17
  41. package/src/components/HkMenuPanel.scss +4 -0
  42. package/src/components/HkMenuSection.test.tsx +191 -0
  43. package/src/components/HkMenuSection.tsx +95 -0
  44. package/src/components/HkMessageBox.scss +3 -2
  45. package/src/components/HkMinimap.scss +5 -3
  46. package/src/components/HkModal.scss +10 -11
  47. package/src/components/HkModal.sheetmorph.test.ts +8 -6
  48. package/src/components/HkModalBreadcrumb.blur.test.ts +3 -3
  49. package/src/components/HkModalBreadcrumb.scss +6 -4
  50. package/src/components/HkNavItem.scss +2 -1
  51. package/src/components/HkNodeCanvas.scss +3 -1
  52. package/src/components/HkOtpInput.scss +2 -1
  53. package/src/components/HkPasswordSurface.scss +4 -3
  54. package/src/components/HkPillToggleGroup.scss +13 -18
  55. package/src/components/HkPopover.scss +5 -6
  56. package/src/components/HkProgressRing.scss +3 -1
  57. package/src/components/HkRadio.scss +3 -1
  58. package/src/components/HkScrollContainer.fade.contract.test.ts +7 -2
  59. package/src/components/HkScrollContainer.scss +23 -46
  60. package/src/components/HkScrollPin.scss +3 -1
  61. package/src/components/HkSelect.scss +4 -5
  62. package/src/components/HkSelectionGrid.scss +3 -1
  63. package/src/components/HkSelectionWaterfall.scss +3 -1
  64. package/src/components/HkSidebar.rail.test.tsx +105 -3
  65. package/src/components/HkSidebar.scss +4 -1
  66. package/src/components/HkSidebar.tsx +15 -0
  67. package/src/components/HkSidebarRailSwap.tsx +9 -3
  68. package/src/components/HkSlider.scss +3 -1
  69. package/src/components/HkSpinner.scss +5 -2
  70. package/src/components/HkSwitch.scss +3 -1
  71. package/src/components/HkTable.interactions.test.tsx +4 -2
  72. package/src/components/HkTable.scss +8 -8
  73. package/src/components/HkTag.scss +3 -1
  74. package/src/components/HkTagInput.scss +5 -6
  75. package/src/components/HkTagInput.test.tsx +5 -4
  76. package/src/components/HkTemplateField.scss +22 -7
  77. package/src/components/HkTemplateField.styles.test.ts +50 -2
  78. package/src/components/HkTextarea.scss +3 -1
  79. package/src/components/HkThemeToggle.scss +2 -2
  80. package/src/components/HkTitleBar.scss +4 -3
  81. package/src/components/HkToast.scss +5 -4
  82. package/src/components/HkTreemapStage.scss +3 -1
  83. package/src/components/HkZoomToolbar.scss +3 -2
  84. package/src/components/_menu-item.contract.test.ts +450 -0
  85. package/src/components/_menu-item.scss +98 -4
  86. package/src/components/window-close.scss +4 -2
  87. package/src/composables/useMenuGroupState.ts +90 -0
  88. package/src/index.ts +1 -0
  89. package/src/styles/admin-tokens.scss +21 -3
  90. package/src/styles/polyfill.contract.test.ts +294 -0
  91. package/src/styles/polyfill.scss +110 -0
  92. package/src/styles/selection.scss +4 -4
  93. package/src/theme/_field.scss +3 -1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@celestia-island/hikari",
3
- "version": "0.55.239",
3
+ "version": "0.55.241",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "description": "Hikari UI library, Vue 3 runtime — one design system for Vue 3 and Rust/WASM applications",
@@ -1,5 +1,6 @@
1
1
  // Use theme variables with namespace to avoid conflicts
2
2
  @use "./hikari-vars" as vars;
3
+ @use "../styles/polyfill" as *;
3
4
 
4
5
  .s-about-modal {
5
6
  position: relative;
@@ -64,7 +65,7 @@
64
65
  width: 3.75rem;
65
66
  height: 3.75rem;
66
67
  object-fit: contain;
67
- user-select: none;
68
+ @include user-select(none);
68
69
  }
69
70
 
70
71
  .s-about-modal-logo {
@@ -1,3 +1,5 @@
1
+ @use "../styles/polyfill" as *;
2
+
1
3
  .hk-alert {
2
4
  display: flex;
3
5
  align-items: flex-start;
@@ -96,8 +98,7 @@
96
98
  /* Alert body = the same copy-this-error-detail content class as the
97
99
  * toast message and message-box text (L2 selection policy re-enables,
98
100
  * 2026-10-29); the title above stays chrome. */
99
- -webkit-user-select: text;
100
- user-select: text;
101
+ @include user-select(text);
101
102
  margin: 0;
102
103
  line-height: 1.5;
103
104
  color: color-mix(in srgb, var(--hi-color-text-secondary, #666666) 85%, transparent);
@@ -2,6 +2,8 @@
2
2
  // Hikari Avatar Component
3
3
  // ------
4
4
 
5
+ @use "../styles/polyfill" as *;
6
+
5
7
  .hk-avatar {
6
8
  display: inline-flex;
7
9
  align-items: center;
@@ -44,7 +46,7 @@
44
46
  display: flex;
45
47
  align-items: center;
46
48
  justify-content: center;
47
- user-select: none;
49
+ @include user-select(none);
48
50
  font-weight: 600;
49
51
  }
50
52
 
@@ -9,6 +9,7 @@
9
9
 
10
10
  // Use theme variables with namespace to avoid conflicts
11
11
  @use "./hikari-vars" as vars;
12
+ @use "../styles/polyfill" as *;
12
13
 
13
14
  .hk-badge {
14
15
  --hk-badge-text: inherit;
@@ -30,8 +31,7 @@
30
31
  /* Tags are labels, not prose: dragging across a row of pills must never
31
32
  start a text selection (the workspace tag contract makes HkCopyBadge
32
33
  the copy path instead). */
33
- user-select: none;
34
- -webkit-user-select: none;
34
+ @include user-select(none);
35
35
  }
36
36
 
37
37
  /* ---------- size ---------- */
@@ -6,6 +6,8 @@
6
6
  // with a button row appended. Pointer events pass through the column
7
7
  // and re-enable on the per-card slot, exactly like toasts.
8
8
 
9
+ @use "../styles/polyfill" as *;
10
+
9
11
  .hk-blocking-toast-container {
10
12
  position: fixed;
11
13
  top: 4rem;
@@ -38,7 +40,7 @@
38
40
  font-size: var(--text-base, 0.875rem);
39
41
  line-height: 1.4;
40
42
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.2);
41
- backdrop-filter: blur(12px);
43
+ @include backdrop-filter(blur(12px));
42
44
  }
43
45
 
44
46
  .hk-blocking-toast-icon {
@@ -61,14 +63,12 @@
61
63
  /* Content, not chrome — copy-worthy detail under the L2 selection
62
64
  * policy (2026-10-29): the card shell denies, these two text blocks
63
65
  * select again. */
64
- -webkit-user-select: text;
65
- user-select: text;
66
+ @include user-select(text);
66
67
  font-weight: 700;
67
68
  }
68
69
 
69
70
  .hk-blocking-toast-message {
70
- -webkit-user-select: text;
71
- user-select: text;
71
+ @include user-select(text);
72
72
  margin: 0;
73
73
  display: -webkit-box;
74
74
  -webkit-line-clamp: 5;
@@ -163,7 +163,7 @@
163
163
  .hk-blocking-toast-actions .hk-btn-secondary {
164
164
  background: transparent;
165
165
  border-color: color-mix(in srgb, currentColor 45%, transparent);
166
- backdrop-filter: none;
166
+ @include backdrop-filter(none);
167
167
  color: inherit;
168
168
  }
169
169
 
@@ -3,6 +3,8 @@
3
3
  // this file only styles the layers (grid, world, edges, node shells,
4
4
  // minimap dock).
5
5
 
6
+ @use "../styles/polyfill" as *;
7
+
6
8
  .hk-board {
7
9
  position: relative;
8
10
  width: 100%;
@@ -12,7 +14,7 @@
12
14
  background: rgb(var(--color-surface));
13
15
  // gestures own the surface: no native scroll/selection interference
14
16
  touch-action: none;
15
- user-select: none;
17
+ @include user-select(none);
16
18
  }
17
19
 
18
20
  .hk-board-grid {
@@ -2,6 +2,8 @@
2
2
  // The renderer owns the pixels; this file only styles the layers (canvas,
3
3
  // CSS2D labels, overlay slot, fallback note, minimap dock).
4
4
 
5
+ @use "../styles/polyfill" as *;
6
+
5
7
  .hk-board3d {
6
8
  position: relative;
7
9
  width: 100%;
@@ -12,7 +14,7 @@
12
14
  // Gestures own the surface: no native scroll/selection interference
13
15
  // (HkBoard precedent).
14
16
  touch-action: none;
15
- user-select: none;
17
+ @include user-select(none);
16
18
  }
17
19
 
18
20
  .hk-board3d-canvas {
@@ -1,6 +1,7 @@
1
1
  @use "./menu-item" as mi;
2
2
  // Use theme variables with namespace to avoid conflicts
3
3
  @use "./hikari-vars" as vars;
4
+ @use "../styles/polyfill" as *;
4
5
 
5
6
  // ------
6
7
  // Hikari Breadcrumb Component
@@ -218,7 +219,7 @@
218
219
  border-radius: vars.$hikari-radius-fine-md;
219
220
  border: 1px solid var(--hi-color-border);
220
221
  background: var(--hi-surface);
221
- backdrop-filter: blur(4px);
222
+ @include backdrop-filter(blur(4px));
222
223
  box-shadow:
223
224
  0 8px 16px var(--hi-black-30, rgba(0, 0, 0, 0.3)),
224
225
  0 0 0 1px var(--hi-white-5, rgba(255, 255, 255, 0.05)) inset;
@@ -1,4 +1,5 @@
1
1
  @use "../tokens";
2
+ @use "../styles/polyfill" as *;
2
3
 
3
4
  /* HkButton */
4
5
  .hk-btn {
@@ -22,7 +23,7 @@
22
23
  transition-duration: var(--duration-normal);
23
24
  transition-timing-function: var(--ease-standard);
24
25
  white-space: nowrap;
25
- user-select: none;
26
+ @include user-select(none);
26
27
  outline: none;
27
28
  position: relative;
28
29
  }
@@ -328,7 +329,7 @@
328
329
  background: rgb(var(--color-surface));
329
330
  color: rgb(var(--color-text));
330
331
  border-color: rgb(var(--color-border) / 20%);
331
- backdrop-filter: blur(var(--blur-sm));
332
+ @include backdrop-filter(blur(var(--blur-sm)));
332
333
  }
333
334
 
334
335
  /* background stays the base surface — the hover declaration only restated
@@ -1,4 +1,5 @@
1
1
  @use "../tokens";
2
+ @use "../styles/polyfill" as *;
2
3
 
3
4
  /* HkCard — canonical surface card. Hover emphasis is border-color only
4
5
  (the base elevation shadow is already at its resting value). No
@@ -7,7 +8,7 @@
7
8
  display: block;
8
9
  overflow: hidden;
9
10
  background: color-mix(in srgb, rgb(var(--color-surface)) 70%, transparent);
10
- backdrop-filter: blur(var(--blur-md));
11
+ @include backdrop-filter(blur(var(--blur-md)));
11
12
  border: 1px solid var(--border-subtle);
12
13
  border-radius: var(--radius-md);
13
14
  box-shadow: var(--shadow-elevated);
@@ -2,6 +2,8 @@
2
2
  * HkCheckbox / HkRadio — unified selection control.
3
3
  */
4
4
 
5
+ @use "../styles/polyfill" as *;
6
+
5
7
  .hk-checkbox {
6
8
  display: inline-flex;
7
9
  align-items: center;
@@ -12,7 +14,7 @@
12
14
  vertical-align: middle;
13
15
  gap: var(--space-8, 0.5rem);
14
16
  cursor: pointer;
15
- user-select: none;
17
+ @include user-select(none);
16
18
  }
17
19
 
18
20
  .hk-checkbox[data-disabled] {
@@ -1,3 +1,5 @@
1
+ @use "../styles/polyfill" as *;
2
+
1
3
  .hk-color-picker {
2
4
  display: inline-flex;
3
5
  min-width: 0;
@@ -88,7 +90,7 @@
88
90
  .hk-color-picker-panel {
89
91
  padding: var(--space-12);
90
92
  background: rgb(var(--color-surface));
91
- backdrop-filter: blur(var(--blur-lg));
93
+ @include backdrop-filter(blur(var(--blur-lg)));
92
94
  border: 1px solid var(--border-subtle);
93
95
  border-radius: var(--radius-md);
94
96
  box-shadow: var(--shadow-modal);
@@ -134,7 +136,7 @@
134
136
  flex: 1;
135
137
  height: 14px;
136
138
  touch-action: none;
137
- user-select: none;
139
+ @include user-select(none);
138
140
  }
139
141
 
140
142
  .hk-color-picker-slider-track {
@@ -245,7 +247,7 @@
245
247
  font-size: var(--text-xs);
246
248
  font-weight: 600;
247
249
  color: rgb(var(--color-muted));
248
- user-select: none;
250
+ @include user-select(none);
249
251
  pointer-events: none;
250
252
  line-height: 1;
251
253
  }
@@ -6,6 +6,8 @@
6
6
  // buttons share the row equally (no right-clustering of tiny sm buttons),
7
7
  // and on touch-width viewports they grow to the 44px thumb standard.
8
8
 
9
+ @use "../styles/polyfill" as *;
10
+
9
11
  .hk-confirm-dialog {
10
12
  display: flex;
11
13
  flex-direction: column;
@@ -17,8 +19,7 @@
17
19
  .hk-confirm-dialog-message {
18
20
  /* Dialog message = copy-worthy content, same class as the message-box
19
21
  * text (L2 selection policy re-enables, 2026-10-29). */
20
- -webkit-user-select: text;
21
- user-select: text;
22
+ @include user-select(text);
22
23
  margin: 0;
23
24
  color: color-mix(in srgb, var(--hi-color-text-secondary) 85%, transparent);
24
25
  font-size: var(--text-sm, 0.8125rem);
@@ -201,7 +201,7 @@ describe("HkCopyBadge", () => {
201
201
  // inherits the no-selection rule, copyable or not.
202
202
  const here = dirname(fileURLToPath(import.meta.url));
203
203
  const scss = readFileSync(join(here, "HkBadge.scss"), "utf-8");
204
- expect(scss).toMatch(/user-select:\s*none/);
204
+ expect(scss).toMatch(/@include user-select\(\s*none\s*\)/);
205
205
  });
206
206
 
207
207
  it("lands consumer class on the badge element, not the tooltip wrapper", () => {
@@ -3,6 +3,7 @@
3
3
  * Uses the shared --hi-* design tokens. */
4
4
 
5
5
  @use "./HkPickerPane" as picker-pane;
6
+ @use "../styles/polyfill" as *;
6
7
 
7
8
  .hk-dp {
8
9
  display: block;
@@ -40,7 +41,7 @@
40
41
  align-items: center;
41
42
  gap: var(--space-6, 6px);
42
43
  cursor: pointer;
43
- user-select: none;
44
+ @include user-select(none);
44
45
  }
45
46
 
46
47
  .hk-dp:not(.is-disabled) .hk-dp-trigger:hover,
@@ -139,7 +140,7 @@
139
140
  flex-direction: column;
140
141
  gap: var(--space-8, 8px);
141
142
  min-width: 17.5rem;
142
- user-select: none;
143
+ @include user-select(none);
143
144
  color: var(--hi-color-text-primary);
144
145
  }
145
146
 
@@ -3,12 +3,13 @@
3
3
  * stage and the direction-aware view transition live in HkPickerPane.scss. */
4
4
 
5
5
  @use "./HkPickerPane" as picker-pane;
6
+ @use "../styles/polyfill" as *;
6
7
 
7
8
  .hk-dtp {
8
9
  display: flex;
9
10
  flex-direction: column;
10
11
  gap: var(--space-8, 8px);
11
- user-select: none;
12
+ @include user-select(none);
12
13
  /* Fill the host (inline sheets/dialogs) instead of collapsing to the
13
14
  * grid's min-content width — a bottom-sheet calendar should use the
14
15
  * space it is given, not shrink to a cramped block. */
@@ -4,6 +4,7 @@
4
4
  // by the consumer's scroll container).
5
5
 
6
6
  @use "./hikari-vars" as vars;
7
+ @use "../styles/polyfill" as *;
7
8
 
8
9
  .hk-diff-viewer {
9
10
  border: 1px solid var(--hi-color-border, #646464);
@@ -57,11 +58,11 @@
57
58
  text-align: end;
58
59
  color: var(--hi-color-text-tertiary, #8b949e);
59
60
  opacity: 0.75;
60
- user-select: none;
61
+ @include user-select(none);
61
62
  }
62
63
 
63
64
  .hk-diff-viewer__sign {
64
- user-select: none;
65
+ @include user-select(none);
65
66
  text-align: center;
66
67
  font-weight: 600;
67
68
  }
@@ -69,8 +70,7 @@
69
70
  .hk-diff-viewer__code {
70
71
  /* The diff body is content (review text users copy into replies);
71
72
  * the line-number gutter above and the sign column stay denied. */
72
- -webkit-user-select: text;
73
- user-select: text;
73
+ @include user-select(text);
74
74
  padding-inline-end: 1ch;
75
75
  min-width: 0;
76
76
  }
@@ -93,7 +93,7 @@
93
93
  font: inherit;
94
94
  text-align: start;
95
95
  cursor: pointer;
96
- user-select: none;
96
+ @include user-select(none);
97
97
 
98
98
  &:hover {
99
99
  color: var(--hi-color-text-primary, #1e1e1e);
@@ -153,7 +153,7 @@
153
153
  color: var(--hi-color-text-tertiary, #8b949e);
154
154
  font: inherit;
155
155
  cursor: pointer;
156
- user-select: none;
156
+ @include user-select(none);
157
157
 
158
158
  &:hover:not(:disabled) {
159
159
  background: rgb(var(--color-primary) / 10%);
@@ -5,6 +5,8 @@
5
5
  * together.
6
6
  */
7
7
 
8
+ @use "../styles/polyfill" as *;
9
+
8
10
  .hk-dock-bar {
9
11
  /* Transparent anchor box — never intercepts canvas gestures around
10
12
  * the docked surface. */
@@ -137,12 +139,12 @@
137
139
 
138
140
  /* Glass surface (default) — blur the page canvas behind the dock. */
139
141
  .hk-dock-bar[data-surface="glass"] .hk-dock-bar-surface {
140
- backdrop-filter: blur(var(--blur-lg));
142
+ @include backdrop-filter(blur(var(--blur-lg)));
141
143
  }
142
144
 
143
145
  /* Solid surface — no blur, for moving 3D canvases (per-frame backdrop
144
146
  * re-sampling over a live WebGL scene is expensive; the surface must
145
147
  * stay opaque anyway for contrast over the scene). */
146
148
  .hk-dock-bar[data-surface="solid"] .hk-dock-bar-surface {
147
- backdrop-filter: none;
149
+ @include backdrop-filter(none);
148
150
  }
@@ -198,6 +198,6 @@ describe("HkDockBar anchor geometry contract", () => {
198
198
  /\.hk-dock-bar\[data-surface="solid"\] \.hk-dock-bar-surface\s*\{[^}]*\}/,
199
199
  )?.[0];
200
200
  expect(solid, "solid surface rule must exist").toBeTruthy();
201
- expect(solid).toContain("backdrop-filter: none");
201
+ expect(solid).toContain("@include backdrop-filter(none)");
202
202
  });
203
203
  });
@@ -1,3 +1,5 @@
1
+ @use "../styles/polyfill" as *;
2
+
1
3
  .hk-draggable-grid {
2
4
  display: flex;
3
5
  flex-direction: column;
@@ -33,8 +35,7 @@
33
35
  border-color 150ms ease,
34
36
  background 150ms ease,
35
37
  box-shadow 150ms ease;
36
- user-select: none;
37
- -webkit-user-select: none;
38
+ @include user-select(none);
38
39
  transform-origin: center;
39
40
 
40
41
  &:hover {
@@ -131,7 +132,7 @@
131
132
  0 2px 6px rgb(0 0 0 / 18%);
132
133
  border-radius: var(--radius-sm, 4px);
133
134
  background: var(--hi-color-bg-elevated, #161b22);
134
- backdrop-filter: blur(2px);
135
+ @include backdrop-filter(blur(2px));
135
136
  pointer-events: none;
136
137
  /* Drag ghost: above page chrome (--z-sidebar 900) but below every
137
138
  popup band (overlay 1000 < dropdown 2000 < tooltip 3000 < toast 4000)
@@ -1,3 +1,5 @@
1
+ @use "../styles/polyfill" as *;
2
+
1
3
  .hk-draggable-list {
2
4
  display: flex;
3
5
  flex-direction: column;
@@ -18,8 +20,7 @@
18
20
  opacity 150ms cubic-bezier(0.16, 1, 0.3, 1),
19
21
  border-color 150ms ease,
20
22
  background 150ms ease;
21
- user-select: none;
22
- -webkit-user-select: none;
23
+ @include user-select(none);
23
24
 
24
25
  &:hover {
25
26
  border-color: var(--hi-color-text-tertiary, #8b949e);
@@ -139,7 +140,7 @@
139
140
  0 2px 6px rgb(0 0 0 / 18%);
140
141
  border-radius: var(--radius-sm, 4px);
141
142
  background: var(--hi-color-bg-elevated, #161b22);
142
- backdrop-filter: blur(2px);
143
+ @include backdrop-filter(blur(2px));
143
144
  pointer-events: none;
144
145
  /* Drag ghost: above page chrome (--z-sidebar 900) but below every
145
146
  popup band (overlay 1000 < dropdown 2000 < tooltip 3000 < toast 4000)
@@ -1,4 +1,5 @@
1
1
  @use "./scrim-fade" as sf;
2
+ @use "../styles/polyfill" as *;
2
3
 
3
4
  .hk-drawer-overlay {
4
5
  /* Overlay-root contract: #hk-overlay-root fences pointer events
@@ -8,7 +9,7 @@
8
9
  position: fixed;
9
10
  inset: 0;
10
11
  background: var(--hk-drawer-overlay-bg, rgba(0, 0, 0, 0.45));
11
- backdrop-filter: var(--hk-drawer-overlay-blur, blur(6px));
12
+ @include backdrop-filter(var(--hk-drawer-overlay-blur, blur(6px)));
12
13
  }
13
14
 
14
15
  // Overlay enter/leave — fade-only classes from the shared window-layer
@@ -33,7 +34,7 @@
33
34
  // lag shows as patchy flicker along the moving edge. The mobile
34
35
  // guard below turns it off ≤767px; hosts restore a finish per
35
36
  // surface with --hk-drawer-blur / --hk-drawer-blur-mobile.
36
- backdrop-filter: var(--hk-drawer-blur, blur(12px));
37
+ @include backdrop-filter(var(--hk-drawer-blur, blur(12px)));
37
38
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.16);
38
39
  outline: none;
39
40
  // Scope layout/style invalidation to the drawer subtree — the page
@@ -226,11 +227,11 @@
226
227
  // family guard as the modal/select sheets, 2026-09-15 chest report).
227
228
  // The scrim's dim alone reads correctly there.
228
229
  .hk-drawer-overlay {
229
- backdrop-filter: var(--hk-drawer-overlay-blur-mobile, none);
230
+ @include backdrop-filter(var(--hk-drawer-overlay-blur-mobile, none));
230
231
  }
231
232
 
232
233
  .hk-drawer-panel {
233
- backdrop-filter: var(--hk-drawer-blur-mobile, none);
234
+ @include backdrop-filter(var(--hk-drawer-blur-mobile, none));
234
235
  }
235
236
 
236
237
  .hk-drawer-bottom {
@@ -1,3 +1,5 @@
1
+ @use "../styles/polyfill" as *;
2
+
1
3
  .hk-empty-state {
2
4
  display: flex;
3
5
  flex-direction: column;
@@ -13,7 +15,7 @@
13
15
  every in-card empty state into a nested placeholder layer. */
14
16
  .hk-empty-state--boxed {
15
17
  background: var(--hk-empty-bg, var(--hi-color-surface, rgba(255,255,255,0.95)));
16
- backdrop-filter: blur(var(--blur-sm, 8px));
18
+ @include backdrop-filter(blur(var(--blur-sm, 8px)));
17
19
  border: 1px solid var(--hi-color-border, rgba(100,100,100,0.06));
18
20
  border-radius: var(--radius-md, 0.5rem);
19
21
  }
@@ -14,9 +14,12 @@ import { fileURLToPath } from "node:url";
14
14
 
15
15
  const here = dirname(fileURLToPath(import.meta.url));
16
16
 
17
+ // `backdrop-filter` is matched without its colon because the blur is
18
+ // authored as `@include backdrop-filter(...)` (styles/polyfill.scss) —
19
+ // the marker must see both the include and any raw declaration.
17
20
  const SURFACE_PROPERTIES = [
18
21
  "background:",
19
- "backdrop-filter:",
22
+ "backdrop-filter",
20
23
  "border:",
21
24
  "border-radius:",
22
25
  ] as const;
@@ -56,7 +59,7 @@ describe("HkEmptyState surface contract", () => {
56
59
  "",
57
60
  );
58
61
  expect(withoutBoxed).not.toContain("background:");
59
- expect(withoutBoxed).not.toContain("backdrop-filter:");
62
+ expect(withoutBoxed).not.toContain("backdrop-filter");
60
63
  expect(withoutBoxed).not.toContain("border: 1px");
61
64
  expect(withoutBoxed).not.toContain("border-radius:");
62
65
  });
@@ -5,6 +5,8 @@
5
5
  // standalone (server error page without hikari theme init) and adapts to
6
6
  // host themes (dark mode etc.) when the vars exist.
7
7
 
8
+ @use "../styles/polyfill" as *;
9
+
8
10
  .hk-error-landing {
9
11
  --hel-background: var(--color-background, 246 247 249);
10
12
  --hel-surface: var(--color-surface, 255 255 255);
@@ -205,7 +207,7 @@
205
207
  font-weight: 500;
206
208
  letter-spacing: 0.02em;
207
209
  color: rgb(var(--hel-muted));
208
- user-select: none;
210
+ @include user-select(none);
209
211
  }
210
212
 
211
213
  // Standing-frame details pane: the raw payload keeps a STABLE height —
@@ -2,6 +2,9 @@
2
2
  // Attribute-driven positioning: data-positioning (absolute|fixed) +
3
3
  // data-corner select the anchored insets; --hk-fab-offset-* extends the
4
4
  // safe-area-aware base per instance (set from offsetX / offsetY).
5
+
6
+ @use "../styles/polyfill" as *;
7
+
5
8
  .hk-fab {
6
9
  position: absolute;
7
10
  z-index: var(--hk-z-fab);
@@ -87,7 +90,7 @@ $sizes: (sm: 34px, md: 42px, lg: 50px);
87
90
  color: var(--hi-color-text-secondary, #666666);
88
91
  background: color-mix(in srgb, var(--hi-color-surface, #ffffff) 78%, transparent);
89
92
  border: 1px solid color-mix(in srgb, var(--hi-color-border, rgba(100,100,100,0.12)) 25%, transparent);
90
- backdrop-filter: blur(var(--blur-xs, 4px)); // chip language shared with autotag pills
93
+ @include backdrop-filter(blur(var(--blur-xs, 4px))); // chip language shared with autotag pills
91
94
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.14);
92
95
 
93
96
  &:hover:not(:disabled) { background: color-mix(in srgb, var(--hi-color-surface, #ffffff) 92%, transparent); }
@@ -134,7 +137,7 @@ $sizes: (sm: 34px, md: 42px, lg: 50px);
134
137
  border: 1px solid color-mix(in srgb, var(--hi-color-border, rgba(100,100,100,0.12)) 25%, transparent);
135
138
  border-radius: var(--radius-full, 9999px);
136
139
  cursor: pointer;
137
- backdrop-filter: blur(var(--blur-xs, 4px));
140
+ @include backdrop-filter(blur(var(--blur-xs, 4px)));
138
141
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.12);
139
142
  opacity: 0;
140
143
  transform: scale(0.4);