@celestia-island/hikari 0.43.10 → 0.43.13

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 (121) hide show
  1. package/package.json +1 -1
  2. package/src/components/HkAboutModal.scss +12 -1
  3. package/src/components/HkAdaptiveDialog.scss +2 -2
  4. package/src/components/HkAffixPicker.scss +55 -27
  5. package/src/components/HkAlert.scss +35 -31
  6. package/src/components/HkAltSignIn.scss +10 -4
  7. package/src/components/HkAuthMethodList.scss +5 -5
  8. package/src/components/HkAuthSubmitButton.scss +3 -3
  9. package/src/components/HkAvatar.scss +10 -49
  10. package/src/components/HkBadge.scss +6 -9
  11. package/src/components/HkBlockingToast.scss +27 -10
  12. package/src/components/HkBoard.scss +26 -6
  13. package/src/components/HkBreadcrumb.scss +82 -268
  14. package/src/components/HkButton.scss +26 -3
  15. package/src/components/HkCaptchaWidget.scss +2 -3
  16. package/src/components/HkCard.scss +14 -8
  17. package/src/components/HkCheckbox.scss +11 -9
  18. package/src/components/HkColorPicker.scss +22 -8
  19. package/src/components/HkContextRing.scss +8 -4
  20. package/src/components/HkCookieConsent.scss +12 -3
  21. package/src/components/HkDatePicker.scss +49 -65
  22. package/src/components/HkDateTimePicker.scss +48 -31
  23. package/src/components/HkDivider.scss +14 -15
  24. package/src/components/HkDraggableGrid.scss +41 -11
  25. package/src/components/HkDraggableList.scss +22 -11
  26. package/src/components/HkDrawer.scss +24 -4
  27. package/src/components/HkEmptyState.scss +10 -11
  28. package/src/components/HkErrorLanding.scss +5 -5
  29. package/src/components/HkExpansionPanel.scss +6 -2
  30. package/src/components/HkFab.scss +29 -12
  31. package/src/components/HkFileBrowserDialog.scss +21 -10
  32. package/src/components/HkFileField.scss +20 -9
  33. package/src/components/HkFilePickerField.scss +12 -6
  34. package/src/components/HkGaugeRing.scss +8 -0
  35. package/src/components/HkHoverRevealAction.scss +30 -12
  36. package/src/components/HkIcon.scss +0 -18
  37. package/src/components/HkIconButton.scss +29 -62
  38. package/src/components/HkIconButtonVars.scss +8 -28
  39. package/src/components/HkImageLightbox.scss +4 -3
  40. package/src/components/HkImagePreview.scss +17 -9
  41. package/src/components/HkImageViewer.scss +8 -0
  42. package/src/components/HkInput.scss +28 -28
  43. package/src/components/HkJsonTree.scss +13 -9
  44. package/src/components/HkKeywordSearchModal.scss +40 -29
  45. package/src/components/HkLabel.scss +8 -3
  46. package/src/components/HkListTransition.scss +16 -1
  47. package/src/components/HkLoadMore.scss +11 -2
  48. package/src/components/HkLocalizedInput.scss +11 -11
  49. package/src/components/HkLogWindow.scss +22 -4
  50. package/src/components/HkLogo.scss +12 -3
  51. package/src/components/HkMarkdownRenderer.scss +19 -13
  52. package/src/components/HkMediaControlBar.scss +2 -4
  53. package/src/components/HkMediaSlider.scss +0 -2
  54. package/src/components/HkMenu.scss +32 -20
  55. package/src/components/HkMenuIdentityItem.scss +3 -3
  56. package/src/components/HkMinimap.scss +23 -8
  57. package/src/components/HkModal.scss +17 -20
  58. package/src/components/HkModalBreadcrumb.scss +25 -6
  59. package/src/components/HkModelTag.scss +23 -13
  60. package/src/components/HkNavItem.scss +27 -14
  61. package/src/components/HkNumberInput.scss +25 -21
  62. package/src/components/HkPageHeader.scss +7 -6
  63. package/src/components/HkPasswordInput.scss +36 -36
  64. package/src/components/HkPhaseTransition.scss +16 -0
  65. package/src/components/HkPhoneInput.scss +10 -5
  66. package/src/components/HkPickerPane.scss +32 -5
  67. package/src/components/HkPlaceholderMarquee.scss +7 -2
  68. package/src/components/HkPlaceholderMarquee.test.ts +27 -0
  69. package/src/components/HkPlaceholderMarquee.tsx +14 -6
  70. package/src/components/HkPopover.scss +18 -10
  71. package/src/components/HkPopupSelect.scss +28 -7
  72. package/src/components/HkProgressBar.scss +29 -7
  73. package/src/components/HkProgressDialog.scss +4 -2
  74. package/src/components/HkProgressRing.scss +7 -14
  75. package/src/components/HkProtocolModal.scss +0 -3
  76. package/src/components/HkQrCode.scss +2 -2
  77. package/src/components/HkRadio.scss +15 -6
  78. package/src/components/HkRichInput.scss +29 -13
  79. package/src/components/HkRollingNumber.scss +14 -6
  80. package/src/components/HkScrollContainer.scss +20 -8
  81. package/src/components/HkSearchInput.scss +12 -10
  82. package/src/components/HkSecretRevealModal.scss +11 -1
  83. package/src/components/HkSelect.scss +35 -17
  84. package/src/components/HkSelectionGrid.scss +41 -20
  85. package/src/components/HkSelectionWaterfall.scss +21 -9
  86. package/src/components/HkShareBar.scss +14 -5
  87. package/src/components/HkSidebar.scss +23 -9
  88. package/src/components/HkSkeleton.scss +16 -8
  89. package/src/components/HkSlider.scss +12 -2
  90. package/src/components/HkSpinner.scss +15 -9
  91. package/src/components/HkSplash.scss +10 -10
  92. package/src/components/HkStatCard.scss +7 -3
  93. package/src/components/HkStatusPill.scss +4 -7
  94. package/src/components/HkStepFlow.scss +24 -4
  95. package/src/components/HkSwitch.scss +41 -9
  96. package/src/components/HkTable.scss +25 -20
  97. package/src/components/HkTabs.scss +40 -26
  98. package/src/components/HkTag.scss +35 -29
  99. package/src/components/HkTagInput.scss +22 -16
  100. package/src/components/HkTextarea.scss +8 -6
  101. package/src/components/HkThemeToggle.scss +28 -18
  102. package/src/components/HkTimeline.scss +46 -29
  103. package/src/components/HkTimeline.test.tsx +39 -0
  104. package/src/components/HkTimeline.tsx +16 -2
  105. package/src/components/HkTitleBar.scss +16 -7
  106. package/src/components/HkToast.scss +40 -10
  107. package/src/components/HkTokenUsagePanel.scss +11 -6
  108. package/src/components/HkToolBlock.scss +23 -11
  109. package/src/components/HkTooltip.scss +5 -9
  110. package/src/components/HkTree.scss +26 -35
  111. package/src/components/HkVoiceInputPopup.scss +11 -6
  112. package/src/components/HkWindowedItem.scss +3 -9
  113. package/src/components/HkZoomToolbar.scss +12 -10
  114. package/src/components/_menu-item.scss +4 -3
  115. package/src/components/window-close.scss +8 -13
  116. package/src/composables/layoutGeometry.test.ts +177 -0
  117. package/src/composables/layoutGeometry.ts +231 -0
  118. package/src/composables/useOverlayScrollbar.test.ts +32 -0
  119. package/src/composables/useOverlayScrollbar.ts +9 -1
  120. package/src/composables/usePointerReorder.test.ts +5 -2
  121. package/src/composables/usePointerReorder.ts +83 -147
@@ -20,7 +20,7 @@
20
20
  }
21
21
 
22
22
  .hk-popup-select-required {
23
- margin-left: var(--space-2);
23
+ margin-inline-start: var(--space-2);
24
24
  color: rgb(var(--color-error));
25
25
  }
26
26
 
@@ -28,7 +28,10 @@
28
28
  display: flex;
29
29
  align-items: center;
30
30
  width: 100%;
31
- padding: var(--space-8) var(--space-32) var(--space-8) var(--space-12);
31
+ // Logical longhand: the wide end inset clears the arrow on the inline END
32
+ // edge, so an RTL locale mirrors both the padding and the arrow with it.
33
+ padding: var(--space-8) var(--space-12);
34
+ padding-inline-end: var(--space-32);
32
35
  min-height: 2.5rem;
33
36
  background: color-mix(in srgb, rgb(var(--color-surface)) 55%, transparent);
34
37
 
@@ -41,7 +44,13 @@
41
44
  text-align: center;
42
45
  cursor: pointer;
43
46
  outline: none;
44
- transition: background-color, border-color, color, box-shadow, opacity, transform, filter var(--duration-normal) var(--ease-standard);
47
+ /* Longhand on purpose: the former comma-separated shorthand declared one
48
+ * transition per property where only `filter` carried the duration — the
49
+ * rest animated at 0s so hover/focus snapped (HkButton.scss precedent). */
50
+ transition-property: background-color, border-color, color, box-shadow,
51
+ opacity, transform, filter;
52
+ transition-duration: var(--duration-normal);
53
+ transition-timing-function: var(--ease-standard);
45
54
  position: relative;
46
55
  }
47
56
 
@@ -49,6 +58,11 @@
49
58
  border-color: var(--c-primary-strong);
50
59
  }
51
60
 
61
+ // Press feedback (house pattern: HkButton.scss :active brightness dip).
62
+ .hk-popup-select-trigger:active:not(:disabled):not([data-disabled]) {
63
+ filter: brightness(0.95);
64
+ }
65
+
52
66
  .hk-popup-select-trigger:focus,
53
67
  .hk-popup-select-trigger[data-state="open"] {
54
68
  border-color: rgb(var(--color-focused-border));
@@ -80,10 +94,9 @@
80
94
 
81
95
  .hk-popup-select-arrow {
82
96
  position: absolute;
83
- right: 0.75rem;
97
+ inset-inline-end: var(--space-12);
84
98
  color: color-mix(in srgb, rgb(var(--color-muted)) 70%, rgb(var(--color-background)));
85
99
  pointer-events: none;
86
- flex-shrink: 0;
87
100
  transition: transform var(--duration-normal) ease;
88
101
  }
89
102
 
@@ -115,8 +128,8 @@
115
128
  @include mi.item;
116
129
  }
117
130
 
118
- /* Highlight face yields to checked/active (see HkSelect.scss). */
119
- .hk-popup-select-item:hover:not([data-checked]):not([data-active]),
131
+ /* Keyboard highlight face yields to checked/active; the hover face comes
132
+ * from mi.item's own guarded :hover (identical values, higher specificity). */
120
133
  .hk-popup-select-item[data-highlighted]:not([data-checked]):not([data-active]) {
121
134
  background: var(--c-primary-subtle, rgb(var(--color-primary) / 8%));
122
135
  border-color: var(--c-primary-medium, rgb(var(--color-primary) / 25%));
@@ -137,3 +150,11 @@
137
150
  // lit a second nested scrollbar inside the same window. The desktop
138
151
  // popout keeps its 240px content cap + viewport scroll, where the
139
152
  // viewport bar is the popup's only scrollbar.
153
+
154
+ // Chevron flip is a transform animation — house reduced-motion guard
155
+ // (HkExpansionPanel.scss silences its chevron the same way).
156
+ @media (prefers-reduced-motion: reduce) {
157
+ .hk-popup-select-arrow {
158
+ transition: none;
159
+ }
160
+ }
@@ -31,10 +31,12 @@
31
31
  .hk-progress-bar-secondary {
32
32
  position: absolute;
33
33
  top: 0;
34
- left: 0;
34
+ // Logical: anchors to the inline start like the in-flow fill, so an RTL
35
+ // track keeps the secondary bar on the same side as the fill.
36
+ inset-inline-start: 0;
35
37
  height: 100%;
36
38
  border-radius: var(--radius-full);
37
- transition: width 0.3s cubic-bezier(0.4, 0, 0.2, 1);
39
+ transition: width var(--duration-normal) var(--ease-standard);
38
40
  opacity: 0.3;
39
41
 
40
42
  &-loading {
@@ -54,7 +56,7 @@
54
56
  position: relative;
55
57
  height: 100%;
56
58
  border-radius: var(--radius-full);
57
- transition: width 0.3s cubic-bezier(0.4, 0, 0.2, 1);
59
+ transition: width var(--duration-normal) var(--ease-standard);
58
60
 
59
61
  &-loading {
60
62
  background: rgb(var(--color-primary));
@@ -105,18 +107,38 @@
105
107
  // No per-block rounding — flush multi-color blocks would otherwise show
106
108
  // hairlines at the seams.
107
109
  border-radius: 0;
108
- transition: width 0.3s cubic-bezier(0.4, 0, 0.2, 1);
110
+ transition: width var(--duration-normal) var(--ease-standard);
109
111
  background: rgb(var(--color-primary));
110
112
  }
111
113
 
114
+ // Keyframes animate the logical inset so the sweep mirrors in RTL together
115
+ // with the fill/secondary anchoring (LTR-identical).
112
116
  @keyframes hk-progress-indeterminate {
113
117
  0% {
114
- left: -40%;
118
+ inset-inline-start: -40%;
115
119
  }
116
120
  60% {
117
- left: 100%;
121
+ inset-inline-start: 100%;
118
122
  }
119
123
  100% {
120
- left: 100%;
124
+ inset-inline-start: 100%;
125
+ }
126
+ }
127
+
128
+ // House pattern (HkExpansionPanel.scss / HkAffixPicker.scss guards): the
129
+ // infinite indeterminate sweep must not run under reduced motion; the bar
130
+ // rests as a static 40% block at the inline start, like the done/error
131
+ // variants rest at full width.
132
+ @media (prefers-reduced-motion: reduce) {
133
+ .hk-progress-bar-indeterminate {
134
+ animation: none;
135
+ }
136
+
137
+ // Width is a size animation — progress steps snap instead of animating
138
+ // (house guard: HkTokenUsagePanel's bar fill).
139
+ .hk-progress-bar-fill,
140
+ .hk-progress-bar-secondary,
141
+ .hk-progress-bar-seg {
142
+ transition: none;
121
143
  }
122
144
  }
@@ -9,9 +9,11 @@
9
9
 
10
10
  .s-progress-dialog-log {
11
11
  border-radius: 0.375rem;
12
+ /* 6% black wash, not the border token: --hi-color-border resolves to a
13
+ 15% tint that would visibly darken the log panel. */
12
14
  background: rgba(0, 0, 0, 0.06);
13
- padding: 0.5rem;
15
+ padding: var(--space-8, 0.5rem);
14
16
  font-family: var(--font-mono, vars.$hikari-font-family-mono);
15
- font-size: 0.75rem;
17
+ font-size: var(--text-xs, 0.75rem);
16
18
  line-height: 1.5;
17
19
  }
@@ -9,34 +9,27 @@
9
9
  .hk-progress-ring-svg {
10
10
  width: 100%;
11
11
  height: 100%;
12
- transform: rotate(0deg);
13
12
  }
14
13
 
15
14
  .hk-progress-ring-track {
16
15
  stroke: var(--hk-progress-ring-track, var(--hi-color-border, rgba(0, 0, 0, 0.12)));
17
- transition: stroke 0.3s ease;
16
+ transition: stroke var(--duration-normal) var(--ease-standard);
18
17
  }
19
18
 
20
- .hk-progress-ring-fill {
19
+ // Segmented-mode arcs: segments without an explicit `color` fall back to
20
+ // the theme primary (same default as the single-value fill).
21
+ .hk-progress-ring-fill,
22
+ .hk-progress-ring-seg {
21
23
  stroke: var(--hi-color-primary, #58a6ff);
22
24
  transition:
23
- stroke-dashoffset 0.3s ease,
24
- stroke 0.3s ease;
25
+ stroke-dashoffset var(--duration-normal) var(--ease-standard),
26
+ stroke var(--duration-normal) var(--ease-standard);
25
27
  }
26
28
 
27
29
  .hk-progress-ring-success .hk-progress-ring-fill {
28
30
  stroke: var(--hi-color-success, #3fb950);
29
31
  }
30
32
 
31
- // Segmented-mode arcs: segments without an explicit `color` fall back to
32
- // the theme primary (same default as the single-value fill).
33
- .hk-progress-ring-seg {
34
- stroke: var(--hi-color-primary, #58a6ff);
35
- transition:
36
- stroke-dashoffset 0.3s ease,
37
- stroke 0.3s ease;
38
- }
39
-
40
33
  .hk-progress-ring-exception .hk-progress-ring-fill {
41
34
  stroke: var(--hi-color-danger, #f85149);
42
35
  }
@@ -2,6 +2,3 @@
2
2
  * content and the HkModal body scroller is THE scrollbar. The old
3
3
  * `bodyHeight`-driven nested scroll region (with its own overlay chrome)
4
4
  * was removed as dead API — no consumer in the family ever passed it. */
5
- .s-protocol-modal {
6
- position: relative;
7
- }
@@ -16,8 +16,8 @@
16
16
  }
17
17
 
18
18
  .hk-qr-label {
19
- font-size: var(--text-2xs, 0.75rem);
19
+ font-size: var(--text-2xs, 0.625rem);
20
20
  line-height: 1.4;
21
- color: rgb(var(--color-muted, 120 113 108));
21
+ color: rgb(var(--color-muted, 108 108 108));
22
22
  text-align: center;
23
23
  }
@@ -1,6 +1,6 @@
1
1
  .hk-radio-group {
2
2
  display: flex;
3
- gap: 1rem;
3
+ gap: var(--space-16, 1rem);
4
4
 
5
5
  &-horizontal {
6
6
  flex-direction: row;
@@ -12,18 +12,18 @@
12
12
  }
13
13
 
14
14
  &-sm {
15
- gap: 0.5rem;
15
+ gap: var(--space-8, 0.5rem);
16
16
  }
17
17
 
18
18
  &-lg {
19
- gap: 1.25rem;
19
+ gap: var(--space-20, 1.25rem);
20
20
  }
21
21
  }
22
22
 
23
23
  .hk-radio {
24
24
  display: inline-flex;
25
25
  align-items: center;
26
- gap: 0.5rem;
26
+ gap: var(--space-8, 0.5rem);
27
27
  cursor: pointer;
28
28
  user-select: none;
29
29
 
@@ -43,8 +43,8 @@
43
43
  border: 1px solid var(--hi-color-border);
44
44
  background: var(--hi-color-surface);
45
45
  transition:
46
- border-color 0.3s ease,
47
- background 0.3s ease;
46
+ border-color var(--hi-duration-normal, 0.3s) ease,
47
+ background var(--hi-duration-normal, 0.3s) ease;
48
48
  flex-shrink: 0;
49
49
  position: relative;
50
50
 
@@ -83,6 +83,15 @@
83
83
  pointer-events: none;
84
84
  }
85
85
 
86
+ /* Keyboard focus: the native input is visually hidden, so draw the house
87
+ double ring (HkButton/HkCheckbox pattern) on the box via :has();
88
+ :focus-visible keeps mouse clicks ring-free. */
89
+ .hk-radio-box:has(.hk-radio-input:focus-visible) {
90
+ box-shadow:
91
+ 0 0 0 2px var(--hi-color-surface, rgba(255, 255, 255, 0.95)),
92
+ 0 0 0 4px var(--hi-color-primary, #ff6b9d);
93
+ }
94
+
86
95
  /* --- Dot --- */
87
96
 
88
97
  .hk-radio-dot {
@@ -27,11 +27,25 @@
27
27
  background: rgb(var(--color-surface) / 0.5);
28
28
  cursor: pointer;
29
29
  overflow: hidden;
30
+ transition:
31
+ border-color var(--duration-short, 0.15s) ease,
32
+ background var(--duration-short, 0.15s) ease;
30
33
 
31
34
  &[data-variant="media"] {
32
35
  width: 72px;
33
36
  height: 48px;
34
37
  }
38
+
39
+ /* Clickable tile (previewAttachment) with no hover/press affordance;
40
+ * color/background only, so no reduced-motion guard is needed. */
41
+ &:hover {
42
+ border-color: rgb(var(--color-primary) / 45%);
43
+ background: rgb(var(--color-surface) / 0.8);
44
+ }
45
+
46
+ &:active {
47
+ background: rgb(var(--color-surface) / 0.9);
48
+ }
35
49
  }
36
50
 
37
51
  .s-rich-input-attachment-thumb {
@@ -47,22 +61,21 @@
47
61
  }
48
62
  }
49
63
 
50
- .s-rich-input-attachment-play {
64
+ .s-rich-input-attachment-play,
65
+ .s-rich-input-attachment-progress {
51
66
  position: absolute;
52
67
  inset: 0;
53
68
  display: flex;
54
69
  align-items: center;
55
70
  justify-content: center;
71
+ }
72
+
73
+ .s-rich-input-attachment-play {
56
74
  color: #fff;
57
75
  background: rgb(0 0 0 / 25%);
58
76
  }
59
77
 
60
78
  .s-rich-input-attachment-progress {
61
- position: absolute;
62
- inset: 0;
63
- display: flex;
64
- align-items: center;
65
- justify-content: center;
66
79
  background: rgb(0 0 0 / 30%);
67
80
  }
68
81
 
@@ -90,12 +103,13 @@
90
103
  .s-rich-input-attachment-remove {
91
104
  position: absolute;
92
105
  top: 2px;
93
- right: 2px;
106
+ inset-inline-end: 2px;
94
107
  opacity: 0;
95
108
  transition: opacity var(--duration-short, 0.15s) ease;
96
109
  }
97
110
 
98
- .s-rich-input-attachment:hover .s-rich-input-attachment-remove {
111
+ .s-rich-input-attachment:hover .s-rich-input-attachment-remove,
112
+ .s-rich-input-attachment:focus-within .s-rich-input-attachment-remove {
99
113
  opacity: 1;
100
114
  }
101
115
 
@@ -125,17 +139,19 @@
125
139
  border-color: rgb(var(--color-primary));
126
140
  }
127
141
 
128
- .s-rich-input-textarea {
142
+ /* The `s-rich-input-textarea` class passed to HInput never reaches the
143
+ * DOM (inheritAttrs:false + filteredAttrs strip class), so strip the
144
+ * embedded input's chrome on its real carrier (.hk-input-box) instead.
145
+ * The :focus-within twin outranks HkInput's own focus ring regardless
146
+ * of stylesheet order. */
147
+ .hk-input-box,
148
+ .hk-input-box:focus-within {
129
149
  border: none;
130
150
  box-shadow: none;
131
151
  background: transparent;
132
152
  }
133
153
  }
134
154
 
135
- .s-rich-input-textarea {
136
- width: 100%;
137
- }
138
-
139
155
  /* ── Tools row ──────────────────────────────────────────────────── */
140
156
  .s-rich-input-tools {
141
157
  display: flex;
@@ -3,15 +3,13 @@
3
3
  font-variant-numeric: tabular-nums;
4
4
  line-height: 1;
5
5
 
6
- [data-el="char"] {
7
- display: inline-block;
8
- }
6
+ /* char/slot/digit are all flex items (root and roll are flex
7
+ containers), so their display blockifies and vertical-align never
8
+ applies — no explicit display/vertical-align declarations. */
9
9
 
10
10
  [data-el="slot"] {
11
- display: inline-block;
12
11
  position: relative;
13
12
  overflow: hidden;
14
- vertical-align: baseline;
15
13
  height: 1em;
16
14
  }
17
15
 
@@ -22,7 +20,6 @@
22
20
  }
23
21
 
24
22
  [data-el="digit"] {
25
- display: block;
26
23
  height: 1em;
27
24
  }
28
25
  }
@@ -35,3 +32,14 @@
35
32
  transform: translateY(-1em);
36
33
  }
37
34
  }
35
+
36
+ /* Reduced motion: stop the digit roll. The global switch
37
+ * (`html[data-css-animations="0"]`) pauses it too when the host wired
38
+ * it; the media block covers hosts that never did. Safe: the component
39
+ * arms a cron fallback that force-commits the final digit whenever
40
+ * `animationend` never fires. */
41
+ @media (prefers-reduced-motion: reduce) {
42
+ .hk-rolling-number [data-el="roll"] {
43
+ animation: none;
44
+ }
45
+ }
@@ -45,7 +45,7 @@
45
45
  content fade. The fade size custom property is declared on the
46
46
  root so consumers can override it from the container element. */
47
47
  .hk-scroll-container[data-fade="true"] {
48
- --hk-scroll-fade-size: 24px;
48
+ --hk-scroll-fade-size: var(--space-24);
49
49
  }
50
50
 
51
51
  .hk-scroll-container[data-fade="true"][data-h-overflow="end"] > .hk-scroll-container-viewport {
@@ -58,6 +58,18 @@
58
58
  mask-image: linear-gradient(to right, transparent 0, #000 var(--hk-scroll-fade-size));
59
59
  }
60
60
 
61
+ /* RTL: the horizontal scroll start/end edges swap sides, so the
62
+ * directional fades flip (the "both" mask is end-symmetric — no flip). */
63
+ [dir="rtl"] .hk-scroll-container[data-fade="true"][data-h-overflow="end"] > .hk-scroll-container-viewport {
64
+ -webkit-mask-image: linear-gradient(to right, transparent 0, #000 var(--hk-scroll-fade-size));
65
+ mask-image: linear-gradient(to right, transparent 0, #000 var(--hk-scroll-fade-size));
66
+ }
67
+
68
+ [dir="rtl"] .hk-scroll-container[data-fade="true"][data-h-overflow="start"] > .hk-scroll-container-viewport {
69
+ -webkit-mask-image: linear-gradient(to left, transparent 0, #000 var(--hk-scroll-fade-size));
70
+ mask-image: linear-gradient(to left, transparent 0, #000 var(--hk-scroll-fade-size));
71
+ }
72
+
61
73
  .hk-scroll-container[data-fade="true"][data-h-overflow="both"] > .hk-scroll-container-viewport {
62
74
  -webkit-mask-image: linear-gradient(
63
75
  to right,
@@ -90,18 +102,18 @@
90
102
 
91
103
  .hk-scroll-container-autotag {
92
104
  position: absolute;
93
- right: 0.625rem;
94
- bottom: 0.625rem;
105
+ right: var(--space-10);
106
+ bottom: var(--space-10);
95
107
  z-index: 6;
96
108
  pointer-events: none;
97
109
  user-select: none;
98
110
  -webkit-user-select: none;
99
- padding: 2px 8px;
100
- font-size: 0.625rem;
111
+ padding: var(--space-2) var(--space-8);
112
+ font-size: var(--text-2xs);
101
113
  letter-spacing: 0.04em;
102
- color: var(--hi-color-muted);
103
- background: color-mix(in srgb, var(--hi-color-surface) 78%, transparent);
104
- border: 1px solid color-mix(in srgb, var(--hi-color-border) 12%, transparent);
114
+ color: var(--hi-color-muted, #666);
115
+ background: color-mix(in srgb, var(--hi-color-surface, rgba(255, 255, 255, 0.95)) 78%, transparent);
116
+ border: 1px solid color-mix(in srgb, var(--hi-color-border, rgba(0, 0, 0, 0.08)) 12%, transparent);
105
117
  border-radius: var(--hi-radius-full, 9999px);
106
118
  backdrop-filter: blur(4px);
107
119
  opacity: 0.85;
@@ -30,7 +30,7 @@
30
30
  align-items: center;
31
31
  justify-content: center;
32
32
  flex-shrink: 0;
33
- padding-left: 0.75rem;
33
+ padding-inline-start: var(--space-12);
34
34
  color: var(--hi-color-muted);
35
35
 
36
36
  svg {
@@ -47,9 +47,9 @@
47
47
  outline: none;
48
48
  color: var(--hi-color-text-primary);
49
49
  font-family: inherit;
50
- font-size: 0.875rem;
50
+ font-size: var(--text-base);
51
51
  line-height: 1.5;
52
- padding: 0 0.5rem;
52
+ padding: 0 var(--space-8);
53
53
 
54
54
  &::placeholder {
55
55
  color: var(--hi-color-muted);
@@ -68,12 +68,11 @@
68
68
  align-items: center;
69
69
  justify-content: center;
70
70
  flex-shrink: 0;
71
- width: 1.75rem;
71
+ width: var(--space-28);
72
72
  height: 100%;
73
73
  padding: 0;
74
74
  background: transparent;
75
75
  border: none;
76
- border-radius: 0;
77
76
  color: var(--hi-color-muted);
78
77
  cursor: pointer;
79
78
  transition:
@@ -89,17 +88,21 @@
89
88
  background: color-mix(in srgb, var(--hi-color-surface) 60%, transparent);
90
89
  color: var(--hi-color-text-primary);
91
90
  }
91
+
92
+ &:active {
93
+ background: color-mix(in srgb, var(--hi-color-surface) 80%, transparent);
94
+ }
92
95
  }
93
96
 
94
97
  /* --- Size variants --- */
95
98
 
96
99
  .hk-search-input-sm .hk-search-input-field {
97
- font-size: 0.75rem;
100
+ font-size: var(--text-xs);
98
101
  height: 1.75rem;
99
102
  }
100
103
 
101
104
  .hk-search-input-sm .hk-search-input-icon {
102
- padding-left: 0.5rem;
105
+ padding-inline-start: var(--space-8);
103
106
 
104
107
  svg {
105
108
  width: 14px;
@@ -108,17 +111,16 @@
108
111
  }
109
112
 
110
113
  .hk-search-input-md .hk-search-input-field {
111
- font-size: 0.875rem;
112
114
  height: 2.25rem;
113
115
  }
114
116
 
115
117
  .hk-search-input-lg .hk-search-input-field {
116
- font-size: 1rem;
118
+ font-size: var(--text-md);
117
119
  height: 2.75rem;
118
120
  }
119
121
 
120
122
  .hk-search-input-lg .hk-search-input-icon {
121
- padding-left: 1rem;
123
+ padding-inline-start: var(--space-16);
122
124
 
123
125
  svg {
124
126
  width: 18px;
@@ -38,18 +38,28 @@
38
38
  gap: var(--space-6, 0.375rem);
39
39
  padding: var(--space-6, 0.375rem) var(--space-12, 0.75rem);
40
40
  border: none;
41
- border-radius: var(--radius-sm, 6px);
41
+ border-radius: var(--radius-sm, 4px);
42
42
  background: rgb(var(--color-primary));
43
43
  color: rgb(var(--color-on-solid-text, 255 255 255));
44
44
  font-size: var(--text-sm, 0.8125rem);
45
45
  font-weight: 600;
46
46
  cursor: pointer;
47
+ transition: filter 200ms ease;
47
48
  }
48
49
 
49
50
  .s-secret-modal-copy:hover {
50
51
  filter: brightness(1.1);
51
52
  }
52
53
 
54
+ .s-secret-modal-copy:active {
55
+ filter: brightness(0.92);
56
+ }
57
+
58
+ .s-secret-modal-copy:focus-visible {
59
+ box-shadow:
60
+ 0 0 0 2px rgb(var(--color-surface)),
61
+ 0 0 0 4px rgb(var(--color-primary));
62
+ }
53
63
 
54
64
  .s-secret-modal-copy:disabled {
55
65
  opacity: 0.5;