@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
@@ -2,7 +2,7 @@
2
2
  @use "./hikari-vars" as vars;
3
3
 
4
4
  .hk-markdown {
5
- font-size: 0.875rem;
5
+ font-size: var(--text-base);
6
6
  line-height: 1.7;
7
7
  color: var(--hi-color-text-primary, #c9d1d9);
8
8
  position: relative;
@@ -31,7 +31,7 @@
31
31
  .hk-markdown ul,
32
32
  .hk-markdown ol {
33
33
  margin: 0.5em 0;
34
- padding-left: 1.5em;
34
+ padding-inline-start: 1.5em;
35
35
  }
36
36
 
37
37
  .hk-markdown li {
@@ -59,13 +59,11 @@
59
59
  position: relative;
60
60
  margin: 0.75em 0;
61
61
  padding: 1em;
62
- border-radius: 4px;
63
- font-size: 0.8125rem;
62
+ border-radius: var(--radius-sm);
63
+ font-size: var(--text-sm);
64
64
  line-height: 1.5;
65
- user-select: none;
66
- cursor: pointer;
67
65
  overflow-x: auto;
68
- background: var(--hi-color-bg-subtle, #0d1117);
66
+ background: var(--hi-color-bg-subtle, #21262d);
69
67
 
70
68
  /* Overlay scrollbar (useOverlayScrollbar) — the native chrome is
71
69
  hidden, never styled. */
@@ -83,7 +81,7 @@
83
81
  .hk-md-code-lang {
84
82
  position: absolute;
85
83
  top: 0.25em;
86
- right: 0.5em;
84
+ inset-inline-end: 0.5em;
87
85
  font-size: 0.625em;
88
86
  color: var(--hi-color-text-tertiary, #8b949e);
89
87
  opacity: 0.6;
@@ -97,7 +95,7 @@
97
95
  margin: 0;
98
96
  padding: 0.5rem 0;
99
97
  font-family: var(--font-mono, vars.$hikari-font-family-mono);
100
- font-size: 0.75rem;
98
+ font-size: var(--text-xs);
101
99
  line-height: 1.6;
102
100
  color: var(--hi-color-text-primary, #c9d1d9);
103
101
  white-space: pre-wrap;
@@ -107,7 +105,7 @@
107
105
  .hk-markdown blockquote {
108
106
  margin: 0.75em 0;
109
107
  padding: 0.5em 1em;
110
- border-left: 3px solid var(--hi-color-text-tertiary, #8b949e);
108
+ border-inline-start: 3px solid var(--hi-color-text-tertiary, #8b949e);
111
109
  color: var(--hi-color-text-secondary, #8b949e);
112
110
  }
113
111
 
@@ -121,7 +119,7 @@
121
119
  .hk-markdown td {
122
120
  padding: 0.5em 0.75em;
123
121
  border: 1px solid var(--hi-color-border, #30363d);
124
- text-align: left;
122
+ text-align: start;
125
123
  }
126
124
 
127
125
  .hk-markdown th {
@@ -138,6 +136,14 @@
138
136
  text-decoration: underline;
139
137
  }
140
138
 
139
+ /* Rendered GFM links are real anchors — keyboard-focusable, so they need
140
+ the house :focus-visible ring (HkFab/HkContextRing pattern). Ring uses
141
+ the same contract var as the link ink so it matches in every theme. */
142
+ .hk-markdown a:focus-visible {
143
+ outline: 2px solid var(--hi-color-primary, #58a6ff);
144
+ outline-offset: 2px;
145
+ }
146
+
141
147
  .hk-markdown hr {
142
148
  border: none;
143
149
  border-top: 1px solid var(--hi-color-border, #30363d);
@@ -146,7 +152,7 @@
146
152
 
147
153
  .hk-markdown img {
148
154
  max-width: 100%;
149
- border-radius: 4px;
155
+ border-radius: var(--radius-sm);
150
156
  }
151
157
 
152
158
  .hk-markdown-overlay {
@@ -155,7 +161,7 @@
155
161
  display: flex;
156
162
  align-items: center;
157
163
  justify-content: center;
158
- background: color-mix(in srgb, var(--hi-color-surface) 70%, transparent);
164
+ background: color-mix(in srgb, var(--hi-color-surface, #fff) 70%, transparent);
159
165
  backdrop-filter: blur(4px);
160
166
  z-index: 10;
161
167
  }
@@ -10,11 +10,9 @@
10
10
  }
11
11
 
12
12
  .hk-media-btn.hk-btn {
13
- min-width: 28px;
14
- height: 28px;
13
+ min-width: var(--space-28);
14
+ height: var(--space-28);
15
15
  padding: 0 var(--space-6);
16
- font-size: var(--text-xs);
17
- font-weight: 600;
18
16
  }
19
17
 
20
18
  .hk-media-play.hk-btn {
@@ -20,7 +20,6 @@
20
20
  .hk-media-slider-buffered {
21
21
  position: absolute;
22
22
  inset: 0 auto 0 0;
23
- height: 100%;
24
23
  border-radius: var(--radius-sm);
25
24
  background: rgb(var(--color-muted) / 40%);
26
25
  }
@@ -28,7 +27,6 @@
28
27
  .hk-media-slider-fill {
29
28
  position: absolute;
30
29
  inset: 0 auto 0 0;
31
- height: 100%;
32
30
  border-radius: var(--radius-sm);
33
31
  background: rgb(var(--color-primary));
34
32
  }
@@ -59,12 +59,6 @@
59
59
  min-width: 0;
60
60
  }
61
61
 
62
- @media (prefers-reduced-motion: reduce) {
63
- .hk-menu-row {
64
- transition: none;
65
- }
66
- }
67
-
68
62
  /* ── sidebar variant ────────────────────────────────────────────── */
69
63
  /* Inline vertical nav list — always rendered, no popover machinery.
70
64
  * Rows share the unified menu-item spec's grammar (metrics + states),
@@ -81,19 +75,11 @@
81
75
 
82
76
  .hk-menu-sidebar-row {
83
77
  @include mi.item;
84
-
85
- .hk-menu-label {
86
- flex: 1;
87
- min-width: 0;
88
- overflow: hidden;
89
- text-overflow: ellipsis;
90
- white-space: nowrap;
91
- }
92
78
  }
93
79
 
94
- .hk-menu-sidebar-row .hk-menu-item-icon {
95
- @include mi.icon;
96
- }
80
+ /* Label and icon grammar comes from the shared .hk-menu-label /
81
+ * .hk-menu-item-icon rules above — sidebar rows carry those classes, so
82
+ * no sidebar-scoped copies are needed. */
97
83
 
98
84
  .hk-menu-sidebar-group {
99
85
  display: flex;
@@ -109,6 +95,19 @@
109
95
  transform: rotate(90deg);
110
96
  }
111
97
 
98
+ /* RTL mirrors the expand chevron: the tsx always renders a right-pointing
99
+ * glyph, which reads backwards on the flipped axis (HkBreadcrumb
100
+ * precedent — scaleX mirrors paint only). An open group composes the
101
+ * same +90° turn after the mirror, so the open glyph points down in
102
+ * both directions. */
103
+ [dir="rtl"] .hk-menu-more {
104
+ transform: scaleX(-1);
105
+ }
106
+
107
+ [dir="rtl"] .hk-menu-sidebar-group[data-open] .hk-menu-sidebar-group-toggle .hk-menu-more {
108
+ transform: scaleX(-1) rotate(90deg);
109
+ }
110
+
112
111
  .hk-menu-sidebar-children {
113
112
  display: flex;
114
113
  flex-direction: column;
@@ -117,17 +116,30 @@
117
116
  }
118
117
 
119
118
  .hk-menu-sidebar-badge {
120
- margin-left: auto;
119
+ margin-inline-start: auto;
121
120
  display: inline-flex;
122
121
  align-items: center;
123
122
  justify-content: center;
124
123
  min-width: 18px;
125
124
  height: 18px;
126
125
  padding: 0 var(--space-4, 4px);
127
- border-radius: 999px;
128
- background: rgb(var(--color-error, 240 70 80));
126
+ border-radius: var(--radius-full, 9999px);
127
+ background: rgb(var(--color-error, 247 118 142));
129
128
  color: #fff;
130
129
  font-size: var(--text-2xs, 10px);
131
130
  font-weight: 700;
132
131
  line-height: 1;
133
132
  }
133
+
134
+ /* Reduced motion resets live AFTER the rules they guard so `transition: none`
135
+ * wins the cascade (the chevron's (0,2,0) transform transition used to be
136
+ * declared later in source order, leaving this guard dead for it). Sidebar
137
+ * rows carry the same mi.item color fades as .hk-menu-row, so they reset
138
+ * too. */
139
+ @media (prefers-reduced-motion: reduce) {
140
+ .hk-menu-row,
141
+ .hk-menu-sidebar-row,
142
+ .hk-menu-sidebar-group-toggle .hk-menu-more {
143
+ transition: none;
144
+ }
145
+ }
@@ -15,7 +15,7 @@
15
15
  .hk-menu-identity-item__avatar {
16
16
  width: 36px;
17
17
  height: 36px;
18
- border-radius: 9999px;
18
+ border-radius: var(--radius-full, 9999px);
19
19
  overflow: hidden;
20
20
  flex-shrink: 0;
21
21
  display: flex;
@@ -42,7 +42,7 @@
42
42
  display: flex;
43
43
  flex-direction: column;
44
44
  min-width: 0;
45
- gap: 2px;
45
+ gap: var(--space-2, 2px);
46
46
  }
47
47
 
48
48
  .hk-menu-identity-item__name {
@@ -66,5 +66,5 @@
66
66
  display: flex;
67
67
  flex-wrap: wrap;
68
68
  gap: var(--space-2, 2px);
69
- margin-top: 2px;
69
+ margin-top: var(--space-2, 2px);
70
70
  }
@@ -1,14 +1,19 @@
1
1
  .hk-minimap {
2
2
  position: absolute;
3
- bottom: 12px;
4
- right: 12px;
3
+ bottom: var(--space-12);
4
+ // Corner overlay anchor mirrors in RTL like the sibling HkZoomToolbar
5
+ // (inset-inline-end: 8px there).
6
+ inset-inline-end: var(--space-12);
5
7
  z-index: 50;
6
8
  width: 160px;
7
9
  background: rgb(var(--color-surface) / 0.82);
8
10
  border: 1px solid var(--border-faint);
9
11
  border-radius: var(--radius-sm);
10
12
  backdrop-filter: blur(var(--blur-md));
11
- cursor: pointer;
13
+ // The root is a drag-to-pan surface (no click action): grab cursor, and
14
+ // the drag state tints the border like hover escalates it (HkBoard's
15
+ // draggable grab/grabbing precedent).
16
+ cursor: grab;
12
17
  overflow: hidden;
13
18
  pointer-events: auto;
14
19
  /* The minimap owns its own drag gestures — the surrounding pannable
@@ -22,6 +27,7 @@
22
27
 
23
28
  &[data-dragging] {
24
29
  cursor: grabbing;
30
+ border-color: rgb(var(--color-primary) / 0.5);
25
31
  }
26
32
  }
27
33
 
@@ -38,7 +44,6 @@
38
44
  gap: 2px;
39
45
  padding: 3px 8px;
40
46
  border-top: 1px solid var(--border-faint);
41
- pointer-events: auto;
42
47
  }
43
48
 
44
49
  // Toolbar-only form (no overview map): shrink-wrap the card around the
@@ -62,21 +67,31 @@
62
67
  background: transparent;
63
68
  color: rgb(var(--color-text));
64
69
  cursor: pointer;
65
- transition: background 0.1s ease, color 0.1s ease;
70
+ transition:
71
+ background var(--hi-duration-fast, 0.15s) ease,
72
+ color var(--hi-duration-fast, 0.15s) ease;
66
73
 
67
74
  &:hover:not(:disabled) {
68
75
  background: rgb(var(--color-primary) / 0.1);
69
76
  color: rgb(var(--color-primary));
70
77
  }
71
78
 
79
+ &:active:not(:disabled) {
80
+ background: rgb(var(--color-primary) / 0.18);
81
+ }
82
+
72
83
  &:disabled {
73
84
  color: rgb(var(--color-muted) / 40%);
74
85
  cursor: not-allowed;
75
86
  }
76
- }
77
87
 
78
- .hk-mm-zoom-reset-btn svg {
79
- stroke-width: 2px;
88
+ // Keyboard focus ring drawn INSIDE the border box: the card clips
89
+ // (overflow: hidden) and the bar pads only 3px vertically, so an outer
90
+ // ring would be shaved per-side (HkSelectionGrid precedent).
91
+ &:focus-visible {
92
+ outline: 2px solid rgb(var(--color-primary));
93
+ outline-offset: -2px;
94
+ }
80
95
  }
81
96
 
82
97
  .hk-mm-zoom-label {
@@ -146,9 +146,9 @@
146
146
  }
147
147
 
148
148
  // Compact lead content (e.g. a context ring) rendered before the title.
149
- // The title's auto right margin overrides the space-between distribution,
150
- // so the lead + title cluster sits on the left and the close button stays
151
- // on the right edge.
149
+ // The title's auto inline-end margin overrides the space-between
150
+ // distribution, so the lead + title cluster sits at inline-start and the
151
+ // close button stays pinned at inline-end (mirrors correctly in RTL).
152
152
  .hk-modal-header-lead {
153
153
  display: flex;
154
154
  align-items: center;
@@ -159,7 +159,7 @@
159
159
  gap: var(--hk-modal-header-lead-gap, 0.75rem);
160
160
 
161
161
  .hk-modal-title {
162
- margin-right: auto;
162
+ margin-inline-end: auto;
163
163
  }
164
164
  }
165
165
 
@@ -250,22 +250,24 @@
250
250
  // .hk-scroll-container-autotag.
251
251
  .hk-modal-autofollow-tag {
252
252
  position: absolute;
253
- right: 0.75rem;
254
- bottom: 0.625rem;
253
+ /* Physical right on purpose: this tag and .hk-scroll-container-autotag
254
+ are visual twins pinned beside the physical corner FAB model — both
255
+ must anchor the same side in every direction. */
256
+ right: var(--space-12, 0.75rem);
257
+ bottom: var(--space-10);
255
258
  z-index: 6;
256
259
  pointer-events: none;
257
260
  user-select: none;
258
261
  -webkit-user-select: none;
259
- padding: 2px 8px;
260
- font-size: 0.625rem;
262
+ padding: var(--space-2) var(--space-8);
263
+ font-size: var(--text-2xs);
261
264
  letter-spacing: 0.04em;
262
- color: var(--hi-color-muted);
263
- background: color-mix(in srgb, var(--hi-color-surface) 78%, transparent);
264
- border: 1px solid color-mix(in srgb, var(--hi-color-border) 12%, transparent);
265
+ color: var(--hi-color-muted, #666);
266
+ background: color-mix(in srgb, var(--hi-color-surface, rgba(255, 255, 255, 0.95)) 78%, transparent);
267
+ border: 1px solid color-mix(in srgb, var(--hi-color-border, rgba(0, 0, 0, 0.08)) 12%, transparent);
265
268
  border-radius: var(--hi-radius-full, 9999px);
266
269
  backdrop-filter: blur(4px);
267
270
  opacity: 0.85;
268
- transition: opacity var(--hi-duration-fast, 0.15s) ease;
269
271
  }
270
272
 
271
273
  // Jump-back FAB (HkFab root) — floats above scroll content while follow
@@ -286,7 +288,7 @@
286
288
  var(--hk-modal-divider-color, var(--hi-color-border, rgba(0, 0, 0, 0.06)));
287
289
  display: flex;
288
290
  justify-content: flex-end;
289
- gap: 0.5rem;
291
+ gap: var(--space-8);
290
292
  flex-shrink: 0;
291
293
 
292
294
  // Conditional footer slots (phases without actions, close transitions)
@@ -314,8 +316,9 @@
314
316
  // ------
315
317
  @media (max-width: 767px) {
316
318
  .hk-modal-content {
319
+ // !important beats the inline maxWidth (width prop); base width: 100%
320
+ // already applies at every viewport, so only the cap is re-asserted.
317
321
  max-width: 100% !important;
318
- width: 100%;
319
322
  // Bottom-docked, content-hugging: `top: auto` lets the sheet size
320
323
  // itself from its content instead of stretching from the top inset
321
324
  // down to the bottom gap (2026-08-30 user report: the node-detail
@@ -371,12 +374,6 @@
371
374
  transform: translateY(100%);
372
375
  }
373
376
 
374
- // Keep children pinned (same reason as desktop) — height stays auto.
375
- .hk-modal-content-enter-active > *,
376
- .hk-modal-content-leave-active > * {
377
- flex: 0 0 auto;
378
- }
379
-
380
377
  .hk-modal-header {
381
378
  padding: 0.875rem 1rem;
382
379
  }
@@ -8,29 +8,32 @@
8
8
  z-index: var(--hk-breadcrumb-z, 2500);
9
9
  display: flex;
10
10
  align-items: center;
11
- gap: var(--hi-space-4, 0.5rem);
12
- padding: var(--hi-space-6, 0.75rem) var(--hi-space-16, 2rem);
11
+ // --space-N contract tokens are N px across the library (HkTable,
12
+ // HkAlert, HkDrawer); keep fallbacks on that scale so hosts defining the
13
+ // family don't collapse this strip (8px→4px gap, 32px→16px padding).
14
+ gap: var(--space-8, 0.5rem);
15
+ padding: var(--space-12, 0.75rem) var(--space-32, 2rem);
13
16
  background: var(--hi-color-surface, rgba(255, 255, 255, 0.95));
14
17
  border: 1px solid var(--hk-breadcrumb-border, rgba(0, 0, 0, 0.06));
15
18
  border-radius: var(--hi-radius-md, 0.5rem);
16
19
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.18);
17
- backdrop-filter: blur(16px);
20
+ backdrop-filter: blur(var(--blur-md));
18
21
  pointer-events: none;
19
22
  user-select: none;
20
- animation: hk-modal-breadcrumb-in 0.15s cubic-bezier(0.16, 1, 0.3, 1);
23
+ animation: hk-modal-breadcrumb-in var(--duration-fast, 0.15s) cubic-bezier(0.16, 1, 0.3, 1);
21
24
  }
22
25
 
23
26
  .hk-modal-breadcrumb-crumb {
24
27
  display: inline-flex;
25
28
  align-items: center;
26
- gap: var(--hi-space-4, 0.5rem);
29
+ gap: var(--space-8, 0.5rem);
27
30
  }
28
31
 
29
32
  .hk-modal-breadcrumb-item {
30
33
  display: inline-flex;
31
34
  align-items: center;
32
35
  line-height: 1.4;
33
- font-size: var(--hi-text-xs, 0.75rem);
36
+ font-size: var(--text-xs, 0.75rem);
34
37
  font-weight: 600;
35
38
  color: var(--hi-color-text-secondary, #666);
36
39
  white-space: nowrap;
@@ -46,6 +49,14 @@
46
49
  flex-shrink: 0;
47
50
  }
48
51
 
52
+ // RTL mirrors the chevron: the tsx always renders a right-pointing glyph,
53
+ // which reads backwards on the flipped axis (HkBreadcrumb.scss precedent —
54
+ // there the class wraps the svg, here the class IS the svg, so the mirror
55
+ // lands on the element itself; static transform, no motion to guard).
56
+ [dir="rtl"] .hk-modal-breadcrumb-sep {
57
+ transform: scaleX(-1);
58
+ }
59
+
49
60
  @keyframes hk-modal-breadcrumb-in {
50
61
  from {
51
62
  opacity: 0;
@@ -56,3 +67,11 @@
56
67
  transform: translate(-50%, -50%);
57
68
  }
58
69
  }
70
+
71
+ // House reduced-motion guard (HkExpansionPanel / HkTooltip pattern): the
72
+ // entrance is a transform slide — drop it, keep the strip visible instantly.
73
+ @media (prefers-reduced-motion: reduce) {
74
+ .hk-modal-breadcrumb {
75
+ animation: none;
76
+ }
77
+ }
@@ -13,21 +13,31 @@
13
13
  min-width: 0;
14
14
  }
15
15
 
16
- // Number segment: keeps its left rounding, square right edge at the seam.
16
+ // Number segment: keeps its inline-start rounding, square inline-end
17
+ // edge at the seam. Logical corners so the joined geometry survives an
18
+ // RTL flip (the flex row mirrors, and physical left/right radii would
19
+ // land on the wrong sides).
17
20
  // (The extra .hk-badge term out-specifies hikari's own
18
21
  // `.hk-badge[data-pill="false"]` radius so import order cannot flip it.)
19
22
  .s-model-tag-group .hk-badge.s-model-tag-num {
20
- border-radius: var(--radius-sm) 0 0 var(--radius-sm);
21
- border-right: none;
23
+ border-start-start-radius: var(--radius-sm, 4px);
24
+ border-end-start-radius: var(--radius-sm, 4px);
25
+ border-start-end-radius: 0;
26
+ border-end-end-radius: 0;
27
+ border-inline-end: none;
22
28
  flex-shrink: 0;
23
29
  }
24
30
 
25
- // Name segment: square left edge at the seam — its own left border IS the
26
- // divider line (darkened a notch so the seam reads clearly against both
27
- // badge fills). Must be allowed to shrink so the text can ellipsize.
31
+ // Name segment: square inline-start edge at the seam — its own
32
+ // inline-start border IS the divider line (darkened a notch so the seam
33
+ // reads clearly against both badge fills). Must be allowed to shrink so
34
+ // the text can ellipsize.
28
35
  .s-model-tag-group .hk-badge.s-model-tag-name {
29
- border-radius: 0 var(--radius-sm) var(--radius-sm) 0;
30
- border-left-color: rgb(var(--color-muted) / 35%);
36
+ border-start-start-radius: 0;
37
+ border-end-start-radius: 0;
38
+ border-start-end-radius: var(--radius-sm, 4px);
39
+ border-end-end-radius: var(--radius-sm, 4px);
40
+ border-inline-start-color: rgb(var(--color-muted) / 35%);
31
41
  min-width: 0;
32
42
  overflow: hidden;
33
43
  }
@@ -35,7 +45,7 @@
35
45
  // No `#tag` segment (bare model id): the name badge stands alone and
36
46
  // keeps the full badge radius — the divider/seam styling never shows.
37
47
  .s-model-tag-group .hk-badge.s-model-tag-name:only-child {
38
- border-radius: var(--radius-sm);
48
+ border-radius: var(--radius-sm, 4px);
39
49
  }
40
50
 
41
51
  .s-model-tag-name-text {
@@ -80,7 +90,7 @@
80
90
  .s-model-card-stats {
81
91
  display: grid;
82
92
  grid-template-columns: auto 1fr auto;
83
- gap: 2px var(--space-10, 0.625rem);
93
+ gap: var(--space-2, 0.125rem) var(--space-10, 0.625rem);
84
94
  align-items: baseline;
85
95
  }
86
96
 
@@ -90,7 +100,7 @@
90
100
  }
91
101
 
92
102
  .s-model-card-col2 {
93
- text-align: right;
103
+ text-align: end;
94
104
  font-family: var(--font-mono, vars.$hikari-font-family-mono);
95
105
  font-variant-numeric: tabular-nums;
96
106
  }
@@ -114,8 +124,8 @@
114
124
  .s-model-card-cap {
115
125
  display: inline-flex;
116
126
  align-items: center;
117
- gap: 4px;
118
- padding: 2px var(--space-6, 0.375rem);
127
+ gap: var(--space-4, 0.25rem);
128
+ padding: var(--space-2, 0.125rem) var(--space-6, 0.375rem);
119
129
  border-radius: var(--radius-sm, 4px);
120
130
  background: rgb(var(--color-primary) / 10%);
121
131
  color: rgb(var(--color-primary));
@@ -24,7 +24,7 @@
24
24
  background: none;
25
25
  border: 1px solid transparent;
26
26
  width: 100%;
27
- text-align: left;
27
+ text-align: start;
28
28
  cursor: pointer;
29
29
  transition:
30
30
  background-color var(--hi-duration-fast, 0.15s) ease,
@@ -57,21 +57,16 @@
57
57
  opacity: 0.4;
58
58
  pointer-events: none;
59
59
  }
60
- }
61
-
62
- .hk-nav-item-button {
63
- cursor: pointer;
64
60
 
61
+ /* Focus ring drawn inside the border box (offset -2px, the
62
+ HkSelectionGrid precedent): child rows sit inside the
63
+ overflow:hidden .hk-nav-item-children container, whose edges shave
64
+ the top/bottom legs of an outer ring. Every row — button and link
65
+ variants alike — carries .hk-nav-item, so one (0,2,0) rule covers
66
+ them all. */
65
67
  &:focus-visible {
66
68
  outline: 2px solid var(--hi-color-primary);
67
- outline-offset: 2px;
68
- }
69
- }
70
-
71
- .hk-nav-item-link {
72
- &:focus-visible {
73
- outline: 2px solid var(--hi-color-primary);
74
- outline-offset: 2px;
69
+ outline-offset: -2px;
75
70
  }
76
71
  }
77
72
 
@@ -85,6 +80,18 @@
85
80
  text-overflow: ellipsis;
86
81
  }
87
82
 
83
+ /* Child-row badge (tsx emits it bare): a small push-to-end pill so it
84
+ never competes with the ellipsizing label for space. Auto inline-start
85
+ margin is the house push-to-end pattern and survives the RTL flip. */
86
+ .hk-nav-item-badge {
87
+ flex-shrink: 0;
88
+ margin-inline-start: auto;
89
+ padding: 0 var(--space-6, 0.375rem);
90
+ border-radius: var(--radius-sm, 4px);
91
+ background: color-mix(in srgb, var(--hi-color-muted) 12%, transparent);
92
+ font-size: var(--text-2xs, 0.625rem);
93
+ }
94
+
88
95
  .hk-nav-item-arrow {
89
96
  transition: transform 0.2s;
90
97
  }
@@ -94,6 +101,12 @@
94
101
  }
95
102
 
96
103
  .hk-nav-item-children {
97
- padding-left: 1rem;
104
+ padding-inline-start: var(--space-16, 1rem);
98
105
  overflow: hidden;
99
106
  }
107
+
108
+ @media (prefers-reduced-motion: reduce) {
109
+ .hk-nav-item-arrow {
110
+ transition: none;
111
+ }
112
+ }