@hjmds/react 1.12.0 → 1.13.0

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 (356) hide show
  1. package/dist/actions.d.ts +4 -0
  2. package/dist/actions.d.ts.map +1 -1
  3. package/dist/actions.js +4 -1
  4. package/dist/actions.js.map +1 -1
  5. package/dist/activity-heatmap.d.ts +4 -1
  6. package/dist/activity-heatmap.d.ts.map +1 -1
  7. package/dist/activity-heatmap.js +1 -1
  8. package/dist/activity-heatmap.js.map +1 -1
  9. package/dist/advanced-display.d.ts +31 -3
  10. package/dist/advanced-display.d.ts.map +1 -1
  11. package/dist/advanced-display.js +26 -27
  12. package/dist/advanced-display.js.map +1 -1
  13. package/dist/advanced-forms.d.ts +27 -2
  14. package/dist/advanced-forms.d.ts.map +1 -1
  15. package/dist/advanced-forms.js +11 -7
  16. package/dist/advanced-forms.js.map +1 -1
  17. package/dist/affix.d.ts +4 -1
  18. package/dist/affix.d.ts.map +1 -1
  19. package/dist/affix.js +2 -2
  20. package/dist/affix.js.map +1 -1
  21. package/dist/agreement.d.ts +3 -0
  22. package/dist/agreement.d.ts.map +1 -1
  23. package/dist/agreement.js +14 -3
  24. package/dist/agreement.js.map +1 -1
  25. package/dist/anchor.d.ts +5 -0
  26. package/dist/anchor.d.ts.map +1 -1
  27. package/dist/anchor.js +2 -2
  28. package/dist/anchor.js.map +1 -1
  29. package/dist/asset.d.ts +8 -1
  30. package/dist/asset.d.ts.map +1 -1
  31. package/dist/asset.js +4 -4
  32. package/dist/asset.js.map +1 -1
  33. package/dist/auth-screen.d.ts +5 -0
  34. package/dist/auth-screen.d.ts.map +1 -1
  35. package/dist/auth-screen.js +2 -1
  36. package/dist/auth-screen.js.map +1 -1
  37. package/dist/bottom-cta.d.ts +5 -0
  38. package/dist/bottom-cta.d.ts.map +1 -1
  39. package/dist/bottom-cta.js +2 -2
  40. package/dist/bottom-cta.js.map +1 -1
  41. package/dist/bottom-info.d.ts +5 -0
  42. package/dist/bottom-info.d.ts.map +1 -1
  43. package/dist/bottom-info.js +2 -2
  44. package/dist/bottom-info.js.map +1 -1
  45. package/dist/bottom-navigation.d.ts +3 -0
  46. package/dist/bottom-navigation.d.ts.map +1 -1
  47. package/dist/bottom-navigation.js +2 -1
  48. package/dist/bottom-navigation.js.map +1 -1
  49. package/dist/breadcrumb.d.ts +3 -0
  50. package/dist/breadcrumb.d.ts.map +1 -1
  51. package/dist/breadcrumb.js +2 -2
  52. package/dist/breadcrumb.js.map +1 -1
  53. package/dist/calendar.d.ts +4 -1
  54. package/dist/calendar.d.ts.map +1 -1
  55. package/dist/calendar.js +2 -2
  56. package/dist/calendar.js.map +1 -1
  57. package/dist/carousel-motion.d.ts +3 -0
  58. package/dist/carousel-motion.d.ts.map +1 -1
  59. package/dist/carousel-motion.js +1 -1
  60. package/dist/carousel-motion.js.map +1 -1
  61. package/dist/carousel.d.ts +3 -0
  62. package/dist/carousel.d.ts.map +1 -1
  63. package/dist/carousel.js +2 -2
  64. package/dist/carousel.js.map +1 -1
  65. package/dist/celebration.d.ts.map +1 -1
  66. package/dist/celebration.js.map +1 -1
  67. package/dist/clipboard.d.ts.map +1 -1
  68. package/dist/clipboard.js +6 -2
  69. package/dist/clipboard.js.map +1 -1
  70. package/dist/code-block.d.ts +4 -1
  71. package/dist/code-block.d.ts.map +1 -1
  72. package/dist/code-block.js +1 -1
  73. package/dist/code-block.js.map +1 -1
  74. package/dist/collapsible.d.ts +3 -0
  75. package/dist/collapsible.d.ts.map +1 -1
  76. package/dist/collapsible.js +2 -2
  77. package/dist/collapsible.js.map +1 -1
  78. package/dist/color-picker.d.ts +4 -1
  79. package/dist/color-picker.d.ts.map +1 -1
  80. package/dist/color-picker.js +2 -2
  81. package/dist/color-picker.js.map +1 -1
  82. package/dist/command-palette.d.ts +6 -0
  83. package/dist/command-palette.d.ts.map +1 -1
  84. package/dist/command-palette.js +49 -15
  85. package/dist/command-palette.js.map +1 -1
  86. package/dist/composition-style.d.ts +14 -1
  87. package/dist/composition-style.d.ts.map +1 -1
  88. package/dist/composition-style.js.map +1 -1
  89. package/dist/content-transition.d.ts +6 -2
  90. package/dist/content-transition.d.ts.map +1 -1
  91. package/dist/content-transition.js +4 -4
  92. package/dist/content-transition.js.map +1 -1
  93. package/dist/context-menu.d.ts +4 -1
  94. package/dist/context-menu.d.ts.map +1 -1
  95. package/dist/context-menu.js +2 -2
  96. package/dist/context-menu.js.map +1 -1
  97. package/dist/data-table.d.ts +3 -0
  98. package/dist/data-table.d.ts.map +1 -1
  99. package/dist/data-table.js +31 -11
  100. package/dist/data-table.js.map +1 -1
  101. package/dist/date-picker.d.ts +4 -1
  102. package/dist/date-picker.d.ts.map +1 -1
  103. package/dist/date-picker.js +2 -2
  104. package/dist/date-picker.js.map +1 -1
  105. package/dist/date-range.d.ts +4 -1
  106. package/dist/date-range.d.ts.map +1 -1
  107. package/dist/date-range.js +2 -2
  108. package/dist/date-range.js.map +1 -1
  109. package/dist/display.d.ts +4 -0
  110. package/dist/display.d.ts.map +1 -1
  111. package/dist/display.js.map +1 -1
  112. package/dist/duration-field.d.ts +4 -2
  113. package/dist/duration-field.d.ts.map +1 -1
  114. package/dist/duration-field.js +2 -2
  115. package/dist/duration-field.js.map +1 -1
  116. package/dist/effect-surface.d.ts +4 -2
  117. package/dist/effect-surface.d.ts.map +1 -1
  118. package/dist/effect-surface.js +2 -2
  119. package/dist/effect-surface.js.map +1 -1
  120. package/dist/evidence.d.ts +1 -1
  121. package/dist/evidence.js +1 -1
  122. package/dist/evidence.js.map +1 -1
  123. package/dist/feedback.d.ts +24 -13
  124. package/dist/feedback.d.ts.map +1 -1
  125. package/dist/feedback.js +17 -15
  126. package/dist/feedback.js.map +1 -1
  127. package/dist/file-picker.d.ts +5 -0
  128. package/dist/file-picker.d.ts.map +1 -1
  129. package/dist/file-picker.js +2 -2
  130. package/dist/file-picker.js.map +1 -1
  131. package/dist/floating-action-button.d.ts.map +1 -1
  132. package/dist/floating-action-button.js.map +1 -1
  133. package/dist/folder-preview.d.ts +4 -1
  134. package/dist/folder-preview.d.ts.map +1 -1
  135. package/dist/folder-preview.js +2 -2
  136. package/dist/folder-preview.js.map +1 -1
  137. package/dist/forms.d.ts +35 -3
  138. package/dist/forms.d.ts.map +1 -1
  139. package/dist/forms.js +55 -36
  140. package/dist/forms.js.map +1 -1
  141. package/dist/gravity-letters.d.ts +4 -2
  142. package/dist/gravity-letters.d.ts.map +1 -1
  143. package/dist/gravity-letters.js +2 -2
  144. package/dist/gravity-letters.js.map +1 -1
  145. package/dist/grid-reveal.d.ts +4 -2
  146. package/dist/grid-reveal.d.ts.map +1 -1
  147. package/dist/grid-reveal.js +2 -2
  148. package/dist/grid-reveal.js.map +1 -1
  149. package/dist/heading.d.ts +5 -0
  150. package/dist/heading.d.ts.map +1 -1
  151. package/dist/heading.js +8 -1
  152. package/dist/heading.js.map +1 -1
  153. package/dist/inline-confirm.d.ts +3 -0
  154. package/dist/inline-confirm.d.ts.map +1 -1
  155. package/dist/inline-confirm.js +3 -3
  156. package/dist/inline-confirm.js.map +1 -1
  157. package/dist/internal/message-reactions.d.ts +16 -0
  158. package/dist/internal/message-reactions.d.ts.map +1 -0
  159. package/dist/internal/message-reactions.js +42 -0
  160. package/dist/internal/message-reactions.js.map +1 -0
  161. package/dist/internal/spinner.d.ts +18 -0
  162. package/dist/internal/spinner.d.ts.map +1 -0
  163. package/dist/internal/spinner.js +10 -0
  164. package/dist/internal/spinner.js.map +1 -0
  165. package/dist/layout.d.ts +12 -0
  166. package/dist/layout.d.ts.map +1 -1
  167. package/dist/layout.js +6 -6
  168. package/dist/layout.js.map +1 -1
  169. package/dist/masonry.d.ts +4 -1
  170. package/dist/masonry.d.ts.map +1 -1
  171. package/dist/masonry.js +5 -3
  172. package/dist/masonry.js.map +1 -1
  173. package/dist/mentions.d.ts.map +1 -1
  174. package/dist/mentions.js +12 -3
  175. package/dist/mentions.js.map +1 -1
  176. package/dist/menu-morph.d.ts +8 -1
  177. package/dist/menu-morph.d.ts.map +1 -1
  178. package/dist/menu-morph.js +3 -3
  179. package/dist/menu-morph.js.map +1 -1
  180. package/dist/menubar.d.ts +4 -1
  181. package/dist/menubar.d.ts.map +1 -1
  182. package/dist/menubar.js +4 -3
  183. package/dist/menubar.js.map +1 -1
  184. package/dist/modal.d.ts.map +1 -1
  185. package/dist/modal.js +4 -1
  186. package/dist/modal.js.map +1 -1
  187. package/dist/navigation-bar.d.ts +4 -1
  188. package/dist/navigation-bar.d.ts.map +1 -1
  189. package/dist/navigation-bar.js +2 -2
  190. package/dist/navigation-bar.js.map +1 -1
  191. package/dist/navigation.d.ts +5 -0
  192. package/dist/navigation.d.ts.map +1 -1
  193. package/dist/navigation.js +6 -6
  194. package/dist/navigation.js.map +1 -1
  195. package/dist/notification-bell.d.ts +4 -1
  196. package/dist/notification-bell.d.ts.map +1 -1
  197. package/dist/notification-bell.js +5 -3
  198. package/dist/notification-bell.js.map +1 -1
  199. package/dist/number-field.d.ts +11 -0
  200. package/dist/number-field.d.ts.map +1 -1
  201. package/dist/number-field.js +8 -3
  202. package/dist/number-field.js.map +1 -1
  203. package/dist/overlay-stack.d.ts.map +1 -1
  204. package/dist/overlay-stack.js.map +1 -1
  205. package/dist/overlays.d.ts +5 -0
  206. package/dist/overlays.d.ts.map +1 -1
  207. package/dist/overlays.js +35 -11
  208. package/dist/overlays.js.map +1 -1
  209. package/dist/pagination.d.ts +5 -0
  210. package/dist/pagination.d.ts.map +1 -1
  211. package/dist/pagination.js +2 -2
  212. package/dist/pagination.js.map +1 -1
  213. package/dist/popover.d.ts.map +1 -1
  214. package/dist/popover.js +5 -4
  215. package/dist/popover.js.map +1 -1
  216. package/dist/portal.d.ts.map +1 -1
  217. package/dist/portal.js +2 -1
  218. package/dist/portal.js.map +1 -1
  219. package/dist/provider-button.d.ts +5 -0
  220. package/dist/provider-button.d.ts.map +1 -1
  221. package/dist/provider-button.js +2 -2
  222. package/dist/provider-button.js.map +1 -1
  223. package/dist/provider.d.ts.map +1 -1
  224. package/dist/provider.js.map +1 -1
  225. package/dist/qr-code.d.ts +4 -1
  226. package/dist/qr-code.d.ts.map +1 -1
  227. package/dist/qr-code.js +2 -2
  228. package/dist/qr-code.js.map +1 -1
  229. package/dist/reaction-picker.d.ts +6 -2
  230. package/dist/reaction-picker.d.ts.map +1 -1
  231. package/dist/reaction-picker.js +20 -4
  232. package/dist/reaction-picker.js.map +1 -1
  233. package/dist/saved-items.d.ts +33 -0
  234. package/dist/saved-items.d.ts.map +1 -0
  235. package/dist/saved-items.js +19 -0
  236. package/dist/saved-items.js.map +1 -0
  237. package/dist/screen-flows.d.ts +323 -0
  238. package/dist/screen-flows.d.ts.map +1 -0
  239. package/dist/screen-flows.js +212 -0
  240. package/dist/screen-flows.js.map +1 -0
  241. package/dist/screens.d.ts +120 -0
  242. package/dist/screens.d.ts.map +1 -0
  243. package/dist/screens.js +66 -0
  244. package/dist/screens.js.map +1 -0
  245. package/dist/select.d.ts +6 -0
  246. package/dist/select.d.ts.map +1 -1
  247. package/dist/select.js +13 -3
  248. package/dist/select.js.map +1 -1
  249. package/dist/selection.d.ts +28 -1
  250. package/dist/selection.d.ts.map +1 -1
  251. package/dist/selection.js +12 -12
  252. package/dist/selection.js.map +1 -1
  253. package/dist/side-panel.d.ts.map +1 -1
  254. package/dist/side-panel.js.map +1 -1
  255. package/dist/sidebar.d.ts +3 -0
  256. package/dist/sidebar.d.ts.map +1 -1
  257. package/dist/sidebar.js +2 -2
  258. package/dist/sidebar.js.map +1 -1
  259. package/dist/skip-nav.d.ts.map +1 -1
  260. package/dist/skip-nav.js.map +1 -1
  261. package/dist/slider.d.ts +5 -0
  262. package/dist/slider.d.ts.map +1 -1
  263. package/dist/slider.js +2 -1
  264. package/dist/slider.js.map +1 -1
  265. package/dist/sortable.d.ts +3 -0
  266. package/dist/sortable.d.ts.map +1 -1
  267. package/dist/sortable.js +1 -1
  268. package/dist/sortable.js.map +1 -1
  269. package/dist/splitter.d.ts +5 -0
  270. package/dist/splitter.d.ts.map +1 -1
  271. package/dist/splitter.js +28 -3
  272. package/dist/splitter.js.map +1 -1
  273. package/dist/step-player.d.ts +4 -1
  274. package/dist/step-player.d.ts.map +1 -1
  275. package/dist/step-player.js +2 -2
  276. package/dist/step-player.js.map +1 -1
  277. package/dist/steps.d.ts +5 -0
  278. package/dist/steps.d.ts.map +1 -1
  279. package/dist/steps.js +2 -2
  280. package/dist/steps.js.map +1 -1
  281. package/dist/styles.css +245 -65
  282. package/dist/styles.layered.css +245 -65
  283. package/dist/supplemental-display.d.ts +4 -0
  284. package/dist/supplemental-display.d.ts.map +1 -1
  285. package/dist/supplemental-display.js +7 -4
  286. package/dist/supplemental-display.js.map +1 -1
  287. package/dist/supplemental-navigation.d.ts +5 -0
  288. package/dist/supplemental-navigation.d.ts.map +1 -1
  289. package/dist/supplemental-navigation.js +2 -2
  290. package/dist/supplemental-navigation.js.map +1 -1
  291. package/dist/swipe-actions.d.ts +4 -1
  292. package/dist/swipe-actions.d.ts.map +1 -1
  293. package/dist/swipe-actions.js +2 -2
  294. package/dist/swipe-actions.js.map +1 -1
  295. package/dist/tags-input.d.ts +5 -0
  296. package/dist/tags-input.d.ts.map +1 -1
  297. package/dist/tags-input.js +2 -2
  298. package/dist/tags-input.js.map +1 -1
  299. package/dist/task-list.d.ts +4 -1
  300. package/dist/task-list.d.ts.map +1 -1
  301. package/dist/task-list.js +3 -3
  302. package/dist/task-list.js.map +1 -1
  303. package/dist/text-formats.d.ts +5 -0
  304. package/dist/text-formats.d.ts.map +1 -1
  305. package/dist/text-formats.js +2 -1
  306. package/dist/text-formats.js.map +1 -1
  307. package/dist/theme.d.ts.map +1 -1
  308. package/dist/theme.js +22 -2
  309. package/dist/theme.js.map +1 -1
  310. package/dist/thinking-orb.d.ts +4 -1
  311. package/dist/thinking-orb.d.ts.map +1 -1
  312. package/dist/thinking-orb.js +2 -2
  313. package/dist/thinking-orb.js.map +1 -1
  314. package/dist/toast.d.ts.map +1 -1
  315. package/dist/toast.js +10 -4
  316. package/dist/toast.js.map +1 -1
  317. package/dist/toggle-group.d.ts +3 -0
  318. package/dist/toggle-group.d.ts.map +1 -1
  319. package/dist/toggle-group.js +2 -1
  320. package/dist/toggle-group.js.map +1 -1
  321. package/dist/top-bar.d.ts +5 -0
  322. package/dist/top-bar.d.ts.map +1 -1
  323. package/dist/top-bar.js +2 -2
  324. package/dist/top-bar.js.map +1 -1
  325. package/dist/top.d.ts +5 -0
  326. package/dist/top.d.ts.map +1 -1
  327. package/dist/top.js +2 -2
  328. package/dist/top.js.map +1 -1
  329. package/dist/tour.d.ts.map +1 -1
  330. package/dist/tour.js +3 -2
  331. package/dist/tour.js.map +1 -1
  332. package/dist/transfer-list.d.ts +3 -0
  333. package/dist/transfer-list.d.ts.map +1 -1
  334. package/dist/transfer-list.js +2 -2
  335. package/dist/transfer-list.js.map +1 -1
  336. package/dist/tree.d.ts +3 -0
  337. package/dist/tree.d.ts.map +1 -1
  338. package/dist/tree.js +17 -5
  339. package/dist/tree.js.map +1 -1
  340. package/dist/upload-item.d.ts +5 -0
  341. package/dist/upload-item.d.ts.map +1 -1
  342. package/dist/upload-item.js +2 -2
  343. package/dist/upload-item.js.map +1 -1
  344. package/dist/virtual-list.d.ts +4 -1
  345. package/dist/virtual-list.d.ts.map +1 -1
  346. package/dist/virtual-list.js +2 -2
  347. package/dist/virtual-list.js.map +1 -1
  348. package/dist/voice-note.d.ts +4 -1
  349. package/dist/voice-note.d.ts.map +1 -1
  350. package/dist/voice-note.js +2 -2
  351. package/dist/voice-note.js.map +1 -1
  352. package/dist/watermark.d.ts +4 -1
  353. package/dist/watermark.d.ts.map +1 -1
  354. package/dist/watermark.js +2 -2
  355. package/dist/watermark.js.map +1 -1
  356. package/package.json +18 -3
package/dist/styles.css CHANGED
@@ -76,7 +76,7 @@
76
76
  /* A child image would otherwise spill past the rounded corner. An elevated tone
77
77
  opts out because clipping cuts off its own shadow. */
78
78
  .hjm-surface[data-clips="true"] { overflow: hidden; }
79
- .hjm-surface[data-tone="raised"] { background: var(--hjm-color-bg); box-shadow: 0 4px 12px rgb(0 0 0 / 12%); }
79
+ .hjm-surface[data-tone="raised"] { background: var(--hjm-color-bg); box-shadow: var(--hjm-shadow-floating); }
80
80
  .hjm-surface[data-tone="accent"] { background: var(--hjm-color-bg); }
81
81
  .hjm-surface[data-tone="sunken"] { background: var(--hjm-color-bg); }
82
82
  .hjm-surface[data-tone="subtle"] { background: var(--hjm-color-bg); }
@@ -129,7 +129,8 @@
129
129
  }
130
130
  .hjm-layout__skip-link {
131
131
  position: fixed;
132
- z-index: 1400;
132
+ /* Focused skip links must remain reachable above transient notifications. */
133
+ z-index: calc(var(--hjm-layer-toast) + 1);
133
134
  inset-block-start: var(--hjm-space-sm);
134
135
  inset-inline-start: var(--hjm-space-sm);
135
136
  padding: var(--hjm-space-sm) var(--hjm-space-md);
@@ -314,7 +315,13 @@
314
315
  See issue #19. */
315
316
  .hjm-field[data-state="focused"] .hjm-field__control { border-color: var(--hjm-color-content-brand); box-shadow: 0 0 0 var(--hjm-field-focus-ring-width) var(--hjm-color-content-brand); }
316
317
  .hjm-field[data-state="invalid"] .hjm-field__control { border-color: var(--hjm-color-danger); }
317
- .hjm-field[data-state="disabled"] { opacity: var(--hjm-field-disabled-opacity); }
318
+ /* fieldRecipe.disabledScope (2026-10-06): disabled fades the label and the control, not
319
+ the hint or the error, which explain why the field is locked or what to fix. Fading the
320
+ whole frame (the rule before) took their contrast down with it. Every direct child except
321
+ the support text fades, so a custom Field control dims without needing a class. A component
322
+ recipe value (Select, NumberField, OtpField, SearchField, PasswordField) arrives as an
323
+ inline --hjm-field-disabled-opacity on the root. */
324
+ .hjm-field[data-state="disabled"] > :not(.hjm-field__description):not(.hjm-field__error) { opacity: var(--hjm-field-disabled-opacity); }
318
325
  .hjm-field__input {
319
326
  inline-size: 100%;
320
327
  min-inline-size: 0;
@@ -346,7 +353,15 @@
346
353
  .hjm-field__affix { display: inline-flex; align-items: center; color: var(--hjm-color-text-muted); }
347
354
  .hjm-field__description, .hjm-choice__description { color: var(--hjm-color-text-muted); font-size: var(--hjm-type-label-size); line-height: var(--hjm-type-label-line-height); }
348
355
  .hjm-field__error { color: var(--hjm-color-danger); font-size: var(--hjm-type-label-size); line-height: var(--hjm-type-label-line-height); }
349
- .hjm-search-field__clear { inline-size: var(--hjm-control-min-touch-target); block-size: var(--hjm-control-min-touch-target); display: inline-grid; place-items: center; border: 0; border-radius: 50%; color: inherit; background: transparent; font: inherit; cursor: pointer; }
356
+ /* searchFieldRecipe.sizes.* (emitted by theme.ts): medium padding 12 · gap 8 · clear 36 + slop 4, large 52 high ·
357
+ padding 16 · gap 12 · clear 44. Size is applied to the input by TextField; size the control from that public attribute. */
358
+ .hjm-search-field .hjm-field__control { padding-inline: var(--hjm-search-field-padding-medium, var(--hjm-space-sm)); gap: var(--hjm-search-field-gap-medium, var(--hjm-space-xs)); }
359
+ .hjm-search-field:has(.hjm-field__input[data-size="large"]) .hjm-field__control { min-block-size: var(--hjm-control-button-large); padding-inline: var(--hjm-search-field-padding-large, var(--hjm-space-md)); gap: var(--hjm-search-field-gap-large, var(--hjm-space-sm)); }
360
+ .hjm-search-field .hjm-field__input[data-size="large"] { min-block-size: calc(var(--hjm-control-button-large) - 2px); font-size: var(--hjm-type-body-large-size); line-height: var(--hjm-type-body-large-line-height); }
361
+ /* The visible circle is the recipe diameter; ::after extends the hit area by clearHitSlop so the target stays 44. */
362
+ .hjm-search-field__clear { --hjm-search-clear-slop: var(--hjm-search-field-clear-slop-medium, 4px); position: relative; flex: 0 0 auto; inline-size: var(--hjm-search-field-clear-medium, 36px); block-size: var(--hjm-search-field-clear-medium, 36px); display: inline-grid; place-items: center; border: 0; border-radius: 50%; color: inherit; background: transparent; font: inherit; cursor: pointer; }
363
+ .hjm-search-field__clear::after { content: ""; position: absolute; inset: calc(-1 * var(--hjm-search-clear-slop)); border-radius: 50%; }
364
+ .hjm-search-field:has(.hjm-field__input[data-size="large"]) .hjm-search-field__clear { --hjm-search-clear-slop: var(--hjm-search-field-clear-slop-large, 0px); inline-size: var(--hjm-search-field-clear-large, 44px); block-size: var(--hjm-search-field-clear-large, 44px); }
350
365
  .hjm-search-field__spinner { inline-size: 32px; block-size: 32px; display: inline-grid; place-items: center; color: var(--hjm-color-content-brand); }
351
366
  .hjm-search-field__spinner:empty::before { content: ""; inline-size: 1em; block-size: 1em; border: 2px solid currentColor; border-inline-end-color: transparent; border-radius: 50%; animation: hjm-spin 800ms linear infinite; }
352
367
  .hjm-password-field--large .hjm-field__control { min-block-size: var(--hjm-control-button-large); padding-inline: var(--hjm-space-lg); }
@@ -455,7 +470,7 @@
455
470
 
456
471
  .hjm-bottom-navigation {
457
472
  position: fixed;
458
- z-index: 700;
473
+ z-index: var(--hjm-layer-sticky);
459
474
  inset-inline: 0;
460
475
  inset-block-end: 0;
461
476
  padding-block-start: var(--hjm-bottom-navigation-outer-top);
@@ -478,7 +493,7 @@
478
493
  .hjm-bottom-navigation[data-presentation="floating"] .hjm-bottom-navigation__surface {
479
494
  border: 1px solid var(--hjm-color-border);
480
495
  border-radius: var(--hjm-radius-xl);
481
- box-shadow: 0 8px 24px rgb(0 0 0 / 18%);
496
+ box-shadow: var(--hjm-shadow-floating);
482
497
  }
483
498
  .hjm-bottom-navigation__list {
484
499
  display: grid;
@@ -786,10 +801,16 @@
786
801
  [dir="rtl"] .hjm-switch[data-state="checked"] .hjm-switch__thumb { transform: translateX(calc(-1 * var(--hjm-switch-track-offset))); }
787
802
 
788
803
  .hjm-segmented { min-inline-size: 0; padding: 0; border: 0; }
789
- .hjm-segmented__items { display: flex; min-inline-size: 0; gap: 2px; padding: 2px; border-radius: var(--hjm-radius-md); background: var(--hjm-color-bg); overflow-x: auto; }
790
- .hjm-segmented__item { position: relative; flex: 1 1 0; min-inline-size: max-content; min-block-size: var(--hjm-control-min-touch-target); display: grid; place-items: center; padding: var(--hjm-space-xs) var(--hjm-space-sm); border-radius: calc(var(--hjm-radius-md) - 2px); color: var(--hjm-color-text-muted); cursor: pointer; }
804
+ /* segmentedControlRecipe (2026-10-06 follow-up): track padding/gap spacing.xxs 4, radius lg, 1px border; item radius md,
805
+ medium 44 · padding md, small 36 · padding sm with a 4px vertical hit slop. Web had drawn a 2px track with radius md,
806
+ no small size, and a 1px selected ring; Native already read the recipe. */
807
+ .hjm-segmented__items { display: flex; min-inline-size: 0; gap: var(--hjm-space-xxs); padding: var(--hjm-space-xxs); border: 1px solid var(--hjm-color-border); border-radius: var(--hjm-radius-lg); background: var(--hjm-color-bg); overflow-x: auto; }
808
+ .hjm-segmented__item { position: relative; flex: 1 1 0; min-inline-size: max-content; min-block-size: var(--hjm-control-min-touch-target); display: grid; place-items: center; gap: var(--hjm-space-xxs); padding: 0 var(--hjm-space-md); border-radius: var(--hjm-radius-md); color: var(--hjm-color-text-muted); font-weight: var(--hjm-font-weight-semibold); cursor: pointer; }
809
+ .hjm-segmented[data-size="small"]:not([data-presentation="pills"]) .hjm-segmented__item { min-block-size: 36px; padding-inline: var(--hjm-space-sm); font-size: var(--hjm-type-label-size); line-height: var(--hjm-type-label-line-height); }
810
+ /* Vertical only: neighbours are 4px apart, so a horizontal slop would overlap the next option's target. */
811
+ .hjm-segmented[data-size="small"]:not([data-presentation="pills"]) .hjm-segmented__item::after { content: ""; position: absolute; inset: -4px 0; }
791
812
  .hjm-segmented__item input { position: absolute; opacity: 0; }
792
- .hjm-segmented__item[data-state="checked"] { box-shadow: inset 0 0 0 1px var(--hjm-color-content-brand); color: var(--hjm-color-text); background: var(--hjm-color-bg); font-weight: var(--hjm-font-weight-semibold); }
813
+ .hjm-segmented__item[data-state="checked"] { box-shadow: inset 0 0 0 2px var(--hjm-color-focus); color: var(--hjm-color-content-brand); background: var(--hjm-color-bg); font-weight: var(--hjm-font-weight-bold); }
793
814
  .hjm-segmented__item[data-disabled="true"] { opacity: 0.5; cursor: not-allowed; }
794
815
 
795
816
  /* segmentedControlRecipe.adaptive.largeTextLayout stacks oversized labels, matching RN.
@@ -824,7 +845,7 @@
824
845
 
825
846
  .hjm-badge, .hjm-tag { display: inline-flex; align-items: center; gap: var(--hjm-space-xxs); max-inline-size: 100%; overflow-wrap: anywhere; }
826
847
  .hjm-badge { min-block-size: 24px; padding: 2px var(--hjm-space-xs); border: 1px solid transparent; border-radius: var(--hjm-radius-full); color: var(--hjm-color-text-muted); background: var(--hjm-color-bg); font-size: var(--hjm-type-caption-size); line-height: var(--hjm-type-caption-line-height); font-weight: var(--hjm-font-weight-bold); }
827
- .hjm-badge[data-size="small"] { min-block-size: 20px; font-size: var(--hjm-type-caption-size); }
848
+ .hjm-badge[data-size="small"] { min-block-size: 20px; padding-inline: var(--hjm-space-xxs); font-size: var(--hjm-type-caption-size); } /* badgeRecipe.sizes.small.paddingHorizontal xxs 4 (2026-10-06; Web had kept medium's 8) */
828
849
  .hjm-badge[data-tone="strong"] { color: var(--hjm-color-bg); background: var(--hjm-color-text); }
829
850
  .hjm-badge[data-tone="brand"] { color: var(--hjm-color-content-brand); }
830
851
  .hjm-badge[data-tone="info"], .hjm-tag[data-tone="info"] { color: var(--hjm-accent-info); background: var(--hjm-color-bg); border-color: color-mix(in srgb, var(--hjm-accent-info) 30%, transparent); }
@@ -896,16 +917,22 @@ button.hjm-list-row, a.hjm-list-row { cursor: pointer; }
896
917
  .hjm-section { display: grid; gap: var(--hjm-space-xs); min-inline-size: 0; overflow-wrap: anywhere; }
897
918
  .hjm-section__header { display: flex; align-items: center; justify-content: space-between; gap: var(--hjm-space-sm); min-inline-size: 0; }
898
919
  .hjm-section__copy { display: grid; flex: 1 1 auto; gap: var(--hjm-space-xxs); min-inline-size: 0; }
899
- .hjm-section__title { margin: 0; color: var(--hjm-color-text-body); font: inherit; font-weight: var(--hjm-font-weight-bold); overflow-wrap: anywhere; }
900
- .hjm-section__description { color: var(--hjm-color-text-muted); overflow-wrap: anywhere; }
920
+ /* sectionRecipe.title is the `title` variant (18/26 bold) and description the `caption` variant (11/16), as Native draws them.
921
+ Until 2026-10-06 Web inherited body (14) for both, so the same Section header was smaller on Web. */
922
+ .hjm-section__title { margin: 0; color: var(--hjm-color-text-body); font-size: var(--hjm-type-title-size); line-height: var(--hjm-type-title-line-height); font-weight: var(--hjm-font-weight-bold); overflow-wrap: anywhere; }
923
+ .hjm-section__description { color: var(--hjm-color-text-muted); font-size: var(--hjm-type-caption-size); line-height: var(--hjm-type-caption-line-height); overflow-wrap: anywhere; }
901
924
  .hjm-section__action { flex: 0 0 auto; }
902
925
  .hjm-section__content { min-inline-size: 0; }
903
- @media (max-width: 640px) {
926
+ /* Stack below breakpoint.medium (600), the shared compact/medium edge; 640 had been a Web-only number. */
927
+ @media (max-width: 599.98px) {
904
928
  .hjm-section__header { align-items: stretch; flex-direction: column; }
905
929
  }
906
930
 
907
- .hjm-chip { min-block-size: var(--hjm-control-min-touch-target); display: inline-flex; align-items: center; gap: var(--hjm-space-xs); padding-inline: var(--hjm-space-sm); border: 1px solid var(--hjm-color-border); border-radius: 999px; background: var(--hjm-color-bg); color: var(--hjm-color-text-body); font: inherit; font-weight: var(--hjm-font-weight-medium); cursor: pointer; }
908
- .hjm-chip[data-size="small"] { min-block-size: 36px; padding-inline: var(--hjm-space-xs); }
931
+ /* chipRecipe.sizes (2026-10-06 follow-up): medium 44 · padding md 16 · gap xs 8, small 36 · padding sm 12 · gap xxs 4 with a
932
+ 4px vertical hit slop. Web had drawn padding 12/8 and gap 8 for both sizes. */
933
+ .hjm-chip { position: relative; min-block-size: var(--hjm-control-min-touch-target); display: inline-flex; align-items: center; gap: var(--hjm-space-xs); padding-inline: var(--hjm-space-md); border: 1px solid var(--hjm-color-border); border-radius: 999px; background: var(--hjm-color-bg); color: var(--hjm-color-text-body); font: inherit; font-weight: var(--hjm-font-weight-medium); cursor: pointer; }
934
+ .hjm-chip[data-size="small"] { min-block-size: 36px; padding-inline: var(--hjm-space-sm); gap: var(--hjm-space-xxs); }
935
+ .hjm-chip[data-size="small"]::after { content: ""; position: absolute; inset: -4px 0; }
909
936
  .hjm-chip[data-selected] { border-color: var(--hjm-color-content-brand); background: var(--hjm-color-bg); color: var(--hjm-color-content-brand); }
910
937
  .hjm-chip:disabled { opacity: 0.5; cursor: not-allowed; }
911
938
  .hjm-chip:focus-visible { outline: var(--hjm-focus-width) solid var(--hjm-color-focus); outline-offset: var(--hjm-focus-offset); }
@@ -919,21 +946,31 @@ button.hjm-list-row, a.hjm-list-row { cursor: pointer; }
919
946
  /* Indent only the divider: moving the row shifted every title after the first
920
947
  and narrowed its text column in the notification-settings composition. */
921
948
  .hjm-list[data-separator="indented"] > .hjm-list__item + .hjm-list__item { position: relative; }
922
- .hjm-list[data-separator="indented"] > .hjm-list__item + .hjm-list__item::before { content: ""; position: absolute; inset-block-start: 0; inset-inline: var(--hjm-space-xl) 0; border-block-start: 1px solid var(--hjm-color-border); pointer-events: none; }
949
+ .hjm-list[data-separator="indented"] > .hjm-list__item + .hjm-list__item::before { content: ""; position: absolute; inset-block-start: 0; inset-inline: calc(40px + var(--hjm-space-sm)) 0; border-block-start: 1px solid var(--hjm-color-border); pointer-events: none; } /* listRecipe.separators.indented.insetStart = leading 40 + sm 12 = 52, as Native (2026-10-06; Web had 24) */
923
950
 
924
- .hjm-statistic { display: grid; gap: var(--hjm-space-xxs); min-inline-size: 0; color: var(--hjm-color-text-body); }
951
+ /* statisticRecipe.density (2026-10-06 follow-up): line gap comfortable xs 8 · compact xxs 4, surface padding md 16 · sm 12,
952
+ group gap xs 8. Web had drawn 4/2, a fixed 16 and 12, Native read the recipe. */
953
+ .hjm-statistic { display: grid; gap: var(--hjm-space-xs); min-inline-size: 0; color: var(--hjm-color-text-body); }
925
954
  .hjm-statistic[data-presentation="surface"] { padding: var(--hjm-space-md); border: 1px solid var(--hjm-color-border); border-radius: var(--hjm-radius-md); background: var(--hjm-color-bg); }
926
- .hjm-statistic[data-density="compact"] { gap: 2px; }
927
- .hjm-statistic__label { color: var(--hjm-color-text-muted); font-weight: var(--hjm-font-weight-medium); overflow-wrap: anywhere; }
955
+ .hjm-statistic[data-density="compact"] { gap: var(--hjm-space-xxs); }
956
+ .hjm-statistic[data-density="compact"][data-presentation="surface"] { padding: var(--hjm-space-sm); }
957
+ /* Text variants follow statisticRecipe as Native does: label `label` (compact `caption`) semibold, value `heading`
958
+ (compact `title`) heavy, affix `body` semibold in content.body, hint and trend `caption` (trend bold). Until 2026-10-06
959
+ Web drew a body-size medium label, a title-size value at both densities (scaled twice by --hjm-text-scale, which the
960
+ --hjm-type-* sizes already include) and muted affixes. */
961
+ .hjm-statistic__label { color: var(--hjm-color-text-muted); font-size: var(--hjm-type-label-size); line-height: var(--hjm-type-label-line-height); font-weight: var(--hjm-font-weight-semibold); overflow-wrap: anywhere; }
962
+ .hjm-statistic[data-density="compact"] .hjm-statistic__label { font-size: var(--hjm-type-caption-size); line-height: var(--hjm-type-caption-line-height); }
928
963
  .hjm-statistic__value-row { display: flex; align-items: baseline; flex-wrap: wrap; gap: var(--hjm-space-xxs); min-inline-size: 0; }
929
- .hjm-statistic__value { color: var(--hjm-color-text); font-size: calc(var(--hjm-type-title-size) * var(--hjm-text-scale, 1)); font-variant-numeric: tabular-nums; overflow-wrap: anywhere; }
930
- .hjm-statistic__affix, .hjm-statistic__hint { color: var(--hjm-color-text-muted); }
931
- .hjm-statistic__trend { display: inline-flex; align-items: center; gap: var(--hjm-space-xxs); font-weight: var(--hjm-font-weight-medium); overflow-wrap: anywhere; }
964
+ .hjm-statistic__value { color: var(--hjm-color-text); font-size: var(--hjm-type-heading-size); line-height: var(--hjm-type-heading-line-height); font-weight: var(--hjm-font-weight-heavy); font-variant-numeric: tabular-nums; overflow-wrap: anywhere; }
965
+ .hjm-statistic[data-density="compact"] .hjm-statistic__value { font-size: var(--hjm-type-title-size); line-height: var(--hjm-type-title-line-height); }
966
+ .hjm-statistic__affix { color: var(--hjm-color-text-body); font-size: var(--hjm-type-body-size); line-height: var(--hjm-type-body-line-height); font-weight: var(--hjm-font-weight-semibold); }
967
+ .hjm-statistic__hint { color: var(--hjm-color-text-muted); font-size: var(--hjm-type-caption-size); line-height: var(--hjm-type-caption-line-height); }
968
+ .hjm-statistic__trend { display: inline-flex; align-items: center; gap: var(--hjm-space-xxs); font-size: var(--hjm-type-caption-size); line-height: var(--hjm-type-caption-line-height); font-weight: var(--hjm-font-weight-bold); overflow-wrap: anywhere; }
932
969
  .hjm-statistic__trend[data-tone="success"] { color: var(--hjm-accent-success); }
933
970
  .hjm-statistic__trend[data-tone="warning"] { color: var(--hjm-accent-warning); }
934
971
  .hjm-statistic__trend[data-tone="danger"] { color: var(--hjm-color-danger); }
935
- .hjm-statistic-group { display: grid; grid-template-columns: repeat(var(--hjm-statistic-columns), minmax(0, 1fr)); gap: var(--hjm-space-sm); min-inline-size: 0; }
936
- @media (max-width: 640px) {
972
+ .hjm-statistic-group { display: grid; grid-template-columns: repeat(var(--hjm-statistic-columns), minmax(0, 1fr)); gap: var(--hjm-space-xs); min-inline-size: 0; }
973
+ @media (max-width: 599.98px) {
937
974
  .hjm-statistic-group { grid-template-columns: minmax(0, 1fr); }
938
975
  }
939
976
 
@@ -948,7 +985,8 @@ button.hjm-list-row, a.hjm-list-row { cursor: pointer; }
948
985
  .hjm-notice__action { flex: 0 0 auto; max-inline-size: 100%; }
949
986
  .hjm-notice__title, .hjm-notice__description { overflow-wrap: anywhere; }
950
987
 
951
- .hjm-empty-state { display: grid; justify-items: center; gap: var(--hjm-space-xs); padding: var(--hjm-space-xxl) var(--hjm-space-xl); color: var(--hjm-color-text-muted); text-align: center; }
988
+ /* emptyStateRecipe.density.regular paddingVertical xxxl 40 (2026-10-06; Web had xxl 32, Native read the recipe). */
989
+ .hjm-empty-state { display: grid; justify-items: center; gap: var(--hjm-space-xs); padding: var(--hjm-space-xxxl) var(--hjm-space-xl); color: var(--hjm-color-text-muted); text-align: center; }
952
990
  .hjm-empty-state[data-density="compact"] { padding-block: var(--hjm-space-xl); }
953
991
  .hjm-empty-state__title { color: var(--hjm-color-text); }
954
992
  .hjm-result { display: grid; justify-items: center; gap: var(--hjm-space-sm); padding: var(--hjm-space-xxxl) var(--hjm-space-xl); text-align: center; }
@@ -975,7 +1013,9 @@ button.hjm-list-row, a.hjm-list-row { cursor: pointer; }
975
1013
  sweep. The element stays a <progress>, so the value, the indeterminate case
976
1014
  and the announcement are unchanged — only the paint differs.
977
1015
  */
978
- .hjm-progress[data-shape="circular"] { grid-template-columns: auto 1fr; align-items: center; }
1016
+ /* Copy row above the ring at the start edge, like the linear bar and Native (2026-10-06 follow-up). The ring used to sit
1017
+ beside the copy (grid auto 1fr), so the same Progress laid out differently per platform. */
1018
+ .hjm-progress[data-shape="circular"] { justify-items: start; }
979
1019
  .hjm-progress[data-shape="circular"] .hjm-progress__native { display: none; }
980
1020
  .hjm-progress__ring {
981
1021
  position: relative;
@@ -1053,7 +1093,7 @@ button.hjm-list-row, a.hjm-list-row { cursor: pointer; }
1053
1093
  border: 1px solid var(--hjm-color-border);
1054
1094
  border-radius: var(--hjm-radius-lg);
1055
1095
  background: var(--hjm-color-bg);
1056
- box-shadow: 0 16px 48px rgb(0 0 0 / 28%);
1096
+ box-shadow: var(--hjm-shadow-overlay);
1057
1097
  }
1058
1098
  .hjm-command-palette__search {
1059
1099
  flex: 0 0 auto;
@@ -1083,13 +1123,17 @@ button.hjm-list-row, a.hjm-list-row { cursor: pointer; }
1083
1123
  .hjm-command-palette__description { color: var(--hjm-color-text-muted); font-size: var(--hjm-type-label-size); }
1084
1124
  .hjm-command-palette__shortcut { color: var(--hjm-color-text-muted); font-size: var(--hjm-type-label-size); }
1085
1125
  .hjm-command-palette__state { margin: 0; padding: var(--hjm-space-md); color: var(--hjm-color-text-muted); }
1126
+ .hjm-command-palette__search-row { display: flex; border-block-end: 1px solid var(--hjm-color-border); }
1127
+ .hjm-command-palette__search-row > input { flex: 1; min-inline-size: 0; border: 0; }
1128
+ .hjm-command-palette__search-row > button { margin: 0; }
1086
1129
 
1087
1130
  /* DataTable --------------------------------------------------------------- */
1088
1131
  .hjm-data-table { display: flex; flex-direction: column; gap: var(--hjm-space-sm); min-inline-size: 0; }
1089
1132
  .hjm-data-table__table { inline-size: 100%; border-collapse: collapse; }
1090
1133
  .hjm-data-table__table th,
1091
1134
  .hjm-data-table__table td {
1092
- padding: var(--hjm-space-sm);
1135
+ /* dataTableRecipe.density.regular: sm 12 / md 16 (2026-10-06; Web had 12 on all sides). */
1136
+ padding: var(--hjm-space-sm) var(--hjm-space-md);
1093
1137
  border-block-end: 1px solid var(--hjm-color-border);
1094
1138
  vertical-align: top;
1095
1139
  overflow-wrap: anywhere;
@@ -1142,11 +1186,12 @@ button.hjm-list-row, a.hjm-list-row { cursor: pointer; }
1142
1186
  max-block-size: 14rem;
1143
1187
  overflow: auto;
1144
1188
  overscroll-behavior: contain;
1145
- padding: var(--hjm-space-xxs);
1189
+ /* comboboxRecipe.popover.padding 8, like the Combobox listbox it reuses (4 until 2026-10-06). */
1190
+ padding: var(--hjm-combobox-popover-padding, var(--hjm-space-xs));
1146
1191
  border: 1px solid var(--hjm-color-border);
1147
1192
  border-radius: var(--hjm-radius-md);
1148
1193
  background: var(--hjm-color-bg);
1149
- box-shadow: 0 12px 32px rgb(0 0 0 / 18%);
1194
+ box-shadow: var(--hjm-shadow-floating);
1150
1195
  pointer-events: auto;
1151
1196
  }
1152
1197
  .hjm-mentions__option {
@@ -1208,12 +1253,13 @@ button.hjm-list-row, a.hjm-list-row { cursor: pointer; }
1208
1253
  .hjm-transfer-list__mark[data-checked] { border-color: var(--hjm-color-primary); background: var(--hjm-color-primary); }
1209
1254
  .hjm-transfer-list__options { display: flex; flex-direction: column; padding: var(--hjm-space-xxs); }
1210
1255
  .hjm-transfer-list__option {
1256
+ /* transferListRecipe.item = collectionItemContract: padding/gap sm 12, radius md (2026-10-06; Web had 8 and radius sm, Native 12). */
1211
1257
  display: flex;
1212
1258
  align-items: center;
1213
- gap: var(--hjm-space-xs);
1259
+ gap: var(--hjm-space-sm);
1214
1260
  min-block-size: var(--hjm-control-min-touch-target);
1215
- padding-inline: var(--hjm-space-xs);
1216
- border-radius: var(--hjm-radius-sm);
1261
+ padding-inline: var(--hjm-space-sm);
1262
+ border-radius: var(--hjm-radius-md);
1217
1263
  overflow-wrap: anywhere;
1218
1264
  }
1219
1265
  /* The label is a flex item; reset its intrinsic min-width so long localized values wrap inside a narrow panel. */
@@ -1227,7 +1273,7 @@ button.hjm-list-row, a.hjm-list-row { cursor: pointer; }
1227
1273
  .hjm-transfer-list__empty:focus-visible,
1228
1274
  .hjm-transfer-list__select-all:focus-visible { outline: 2px solid var(--hjm-color-focus); outline-offset: -2px; }
1229
1275
  .hjm-transfer-list__empty { margin: 0; padding: var(--hjm-space-md) var(--hjm-space-sm); color: var(--hjm-color-text-muted); }
1230
- .hjm-transfer-list__actions { display: flex; flex-direction: column; gap: var(--hjm-space-xs); padding-block-start: var(--hjm-space-xl); }
1276
+ .hjm-transfer-list__actions { display: flex; flex-direction: column; gap: var(--hjm-space-sm); /* transferListRecipe.moveControls.gap sm 12, as Native */ padding-block-start: var(--hjm-space-xl); }
1231
1277
 
1232
1278
  /* AuthProviderButton ------------------------------------------------------ */
1233
1279
  /* Provider guideline colors cannot follow the theme without failing provider review.
@@ -1246,6 +1292,7 @@ button.hjm-list-row, a.hjm-list-row { cursor: pointer; }
1246
1292
  background: var(--hjm-provider-background);
1247
1293
  color: var(--hjm-provider-content);
1248
1294
  font: inherit;
1295
+ /* authProviderButtonRecipe.label = typography.body; see docs/provider-button.md (provider colour exception). */
1249
1296
  font-size: var(--hjm-type-body-size);
1250
1297
  line-height: var(--hjm-type-body-line-height);
1251
1298
  cursor: pointer;
@@ -1357,7 +1404,8 @@ button.hjm-list-row, a.hjm-list-row { cursor: pointer; }
1357
1404
  /* A localized skip label can be longer than a narrow viewport; keep the focused link on-screen. */
1358
1405
  box-sizing: border-box;
1359
1406
  max-inline-size: calc(100vw - var(--hjm-skip-nav-offset) * 2);
1360
- z-index: 1300;
1407
+ /* Focused skip links must remain reachable above transient notifications. */
1408
+ z-index: calc(var(--hjm-layer-toast) + 1);
1361
1409
  display: inline-flex;
1362
1410
  align-items: center;
1363
1411
  min-block-size: var(--hjm-skip-nav-min-height);
@@ -1615,7 +1663,10 @@ button.hjm-list-row, a.hjm-list-row { cursor: pointer; }
1615
1663
  .hjm-tags-input__suggestion[aria-selected="true"] { box-shadow: inset 0 0 0 1px var(--hjm-color-content-brand); background: var(--hjm-color-bg); }
1616
1664
  .hjm-tags-input__suggestion[aria-disabled="true"] { color: var(--hjm-color-text-weak); cursor: default; }
1617
1665
  .hjm-tags-input__description { margin: 0; color: var(--hjm-color-text-muted); font-size: var(--hjm-type-label-size); }
1618
- .hjm-tags-input[data-disabled] .hjm-tags-input__frame { opacity: 0.6; cursor: default; }
1666
+ /* fieldRecipe.disabledScope: the label fades with the frame (it stayed at full contrast before
1667
+ 2026-10-06); the description keeps its contrast. The amount is the field default, not a literal. */
1668
+ .hjm-tags-input[data-disabled] :is(.hjm-tags-input__label, .hjm-tags-input__frame) { opacity: var(--hjm-field-disabled-opacity); }
1669
+ .hjm-tags-input[data-disabled] .hjm-tags-input__frame { cursor: default; }
1619
1670
 
1620
1671
  /* Heading ----------------------------------------------------------------- */
1621
1672
  /*
@@ -1826,7 +1877,7 @@ button.hjm-list-row, a.hjm-list-row { cursor: pointer; }
1826
1877
  .hjm-portal[inert] { visibility: hidden; pointer-events: none; }
1827
1878
  .hjm-overlay {
1828
1879
  position: fixed;
1829
- z-index: 1000;
1880
+ z-index: var(--hjm-layer-modal);
1830
1881
  inset: 0;
1831
1882
  display: flex;
1832
1883
  align-items: center;
@@ -1957,9 +2008,16 @@ button.hjm-list-row, a.hjm-list-row { cursor: pointer; }
1957
2008
  display: flex;
1958
2009
  flex-direction: column;
1959
2010
  overflow: hidden;
2011
+ /* sheetRecipe.content/body/footer (2026-10-06 follow-up): padding top/bottom sm 12, sides lg 20, md 16 between
2012
+ header·body·footer and footer.paddingTop sm 12 more, as Native draws it. Web had used the Dialog's 20 on every
2013
+ side and between slots, so the same sheet was 16px taller on Web. */
2014
+ gap: var(--hjm-space-md);
2015
+ padding-block: var(--hjm-space-sm);
1960
2016
  }
1961
2017
  .hjm-sheet__header,
1962
2018
  .hjm-sheet__footer { flex: 0 0 auto; }
2019
+ .hjm-sheet > .hjm-sheet__header { min-block-size: var(--hjm-control-min-touch-target); gap: var(--hjm-space-sm); padding: 0 var(--hjm-space-lg); }
2020
+ .hjm-sheet > .hjm-sheet__footer { padding: var(--hjm-space-sm) var(--hjm-space-lg) 0; }
1963
2021
  .hjm-sheet__body {
1964
2022
  min-block-size: 0;
1965
2023
  flex: 1 1 auto;
@@ -1968,18 +2026,23 @@ button.hjm-list-row, a.hjm-list-row { cursor: pointer; }
1968
2026
  overflow: auto;
1969
2027
  overscroll-behavior: contain;
1970
2028
  }
2029
+ /* The scroll box keeps 4px inside so a child's focus ring is not clipped; the equal negative margin keeps the
2030
+ visible spacing at the recipe's values. */
2031
+ .hjm-sheet > .hjm-sheet__body { gap: var(--hjm-space-md); padding: var(--hjm-space-xxs) var(--hjm-space-lg); margin-block: calc(-1 * var(--hjm-space-xxs)); } /* body.gap between children too, as Native */
1971
2032
  .hjm-sheet[data-placement="bottom"] {
1972
2033
  inline-size: min(var(--hjm-sheet-max-width), 100%);
1973
2034
  max-block-size: var(--hjm-sheet-max-height);
1974
2035
  border-end-start-radius: 0;
1975
2036
  border-end-end-radius: 0;
1976
2037
  }
1977
- .hjm-sheet[data-placement="bottom"]:not([data-has-footer="true"]) > .hjm-sheet__body {
1978
- padding-block-end: calc(var(--hjm-space-lg) + env(safe-area-inset-bottom, 0px));
1979
- }
1980
- .hjm-sheet[data-placement="bottom"] > .hjm-sheet__footer {
1981
- padding-block-end: calc(var(--hjm-space-lg) + env(safe-area-inset-bottom, 0px));
2038
+ .hjm-sheet[data-placement="bottom"] {
2039
+ /* sheetRecipe.safeArea: additive bottom inset on top of content.paddingBottom. */
2040
+ padding-block-end: calc(var(--hjm-space-sm) + env(safe-area-inset-bottom, 0px));
1982
2041
  }
2042
+ /* sheetRecipe.sizes.full = 1: the whole height inside the top safe area. maxHeightRatio (0.9) caps only `auto`;
2043
+ until 2026-10-06 it also capped `full` at 90% on both platforms. */
2044
+ .hjm-sheet-positioner[data-placement="bottom"][data-detent="full"] { padding-block-start: env(safe-area-inset-top, 0px); }
2045
+ .hjm-sheet[data-placement="bottom"][data-detent="full"] { max-block-size: 100%; }
1983
2046
  /* Detent handle: a control, so it carries the shared minimum target. */
1984
2047
  .hjm-sheet__handle-row { display: flex; justify-content: center; flex: 0 0 auto; }
1985
2048
  .hjm-sheet__handle {
@@ -2017,7 +2080,7 @@ button.hjm-list-row, a.hjm-list-row { cursor: pointer; }
2017
2080
  border-radius: 0;
2018
2081
  color: var(--hjm-color-text);
2019
2082
  background: var(--hjm-color-bg);
2020
- box-shadow: 0 16px 48px rgb(0 0 0 / 28%);
2083
+ box-shadow: var(--hjm-shadow-overlay);
2021
2084
  }
2022
2085
  .hjm-side-panel[data-modal="false"] {
2023
2086
  position: fixed;
@@ -2090,7 +2153,7 @@ button.hjm-list-row, a.hjm-list-row { cursor: pointer; }
2090
2153
  border-radius: var(--hjm-radius-md);
2091
2154
  color: var(--hjm-color-text);
2092
2155
  background: var(--hjm-color-bg);
2093
- box-shadow: 0 16px 48px rgb(0 0 0 / 28%);
2156
+ box-shadow: var(--hjm-shadow-overlay);
2094
2157
  pointer-events: auto;
2095
2158
  }
2096
2159
  .hjm-tour__counter { margin: 0; color: var(--hjm-color-text-muted); font-size: var(--hjm-type-label-size); }
@@ -2102,10 +2165,14 @@ button.hjm-list-row, a.hjm-list-row { cursor: pointer; }
2102
2165
  .hjm-tooltip { position: relative; display: inline-flex; }
2103
2166
  .hjm-tooltip__content {
2104
2167
  position: fixed;
2105
- z-index: 1100;
2168
+ z-index: var(--hjm-layer-tooltip);
2106
2169
  inline-size: max-content;
2107
- max-inline-size: min(20rem, 80vw);
2108
- padding: var(--hjm-space-xs) var(--hjm-space-sm);
2170
+ /* tooltipRecipe.content.maxWidth 280 (theme.ts), never wider than the viewport minus collisionPadding 12 each side.
2171
+ Until 2026-10-06 Web used min(20rem, 80vw), wider than the recipe. */
2172
+ max-inline-size: min(var(--hjm-tooltip-max-width, 280px), calc(100vw - 2 * var(--hjm-tooltip-collision-padding, 12px)));
2173
+ /* tooltipRecipe.surface.padding is spacing.xs (8) on every side. Until 2026-10-06 Web drew 8/12; the recipe has no
2174
+ separate inline value and Native has no Tooltip that could justify one, so the recipe wins. */
2175
+ padding: var(--hjm-tooltip-padding, var(--hjm-space-xs));
2109
2176
  border-radius: var(--hjm-radius-sm);
2110
2177
  color: var(--hjm-color-bg);
2111
2178
  background: var(--hjm-color-text);
@@ -2117,16 +2184,18 @@ button.hjm-list-row, a.hjm-list-row { cursor: pointer; }
2117
2184
  .hjm-menu { position: relative; display: inline-flex; }
2118
2185
  .hjm-menu__content {
2119
2186
  position: fixed;
2120
- z-index: 900;
2187
+ z-index: var(--hjm-layer-dropdown);
2121
2188
  min-inline-size: 13.75rem;
2122
2189
  max-inline-size: min(24rem, 90vw);
2123
2190
  max-block-size: calc(100dvh - (2 * var(--hjm-space-md)));
2124
2191
  overflow: auto;
2125
- padding: var(--hjm-space-xxs);
2192
+ /* menuRecipe.surface (floatingSurfaceContract) padding spacing.xs 8. Until 2026-10-06 Web drew 4 here and in the
2193
+ Select/Combobox/ContextMenu popups that share the same surface contract. */
2194
+ padding: var(--hjm-menu-padding, var(--hjm-space-xs));
2126
2195
  border: 1px solid var(--hjm-color-border);
2127
2196
  border-radius: var(--hjm-radius-md);
2128
2197
  background: var(--hjm-color-bg);
2129
- box-shadow: 0 8px 24px rgb(0 0 0 / 18%);
2198
+ box-shadow: var(--hjm-shadow-floating);
2130
2199
  }
2131
2200
  .hjm-menu__item {
2132
2201
  inline-size: 100%;
@@ -2136,7 +2205,7 @@ button.hjm-list-row, a.hjm-list-row { cursor: pointer; }
2136
2205
  gap: var(--hjm-space-sm);
2137
2206
  padding: var(--hjm-space-xs) var(--hjm-space-sm);
2138
2207
  border: 0;
2139
- border-radius: var(--hjm-radius-sm);
2208
+ border-radius: var(--hjm-radius-md); /* menuRecipe.density.* = collectionItemContract.radius md (2026-10-06; was sm) */
2140
2209
  color: var(--hjm-color-text-body);
2141
2210
  background: transparent;
2142
2211
  font: inherit;
@@ -2173,7 +2242,7 @@ button.hjm-list-row, a.hjm-list-row { cursor: pointer; }
2173
2242
  .hjm-select__indicator { flex: 0 0 auto; color: var(--hjm-color-text-muted); pointer-events: none; }
2174
2243
  .hjm-select__busy-indicator { flex: 0 0 auto; inline-size: 1em; block-size: 1em; border: 2px solid var(--hjm-color-content-brand); border-inline-end-color: transparent; border-radius: 50%; animation: hjm-spin 800ms linear infinite; }
2175
2244
  .hjm-select__native + .hjm-select__indicator { margin-inline-start: calc(-1 * var(--hjm-space-lg)); }
2176
- .hjm-select__listbox { position: fixed; z-index: 800; max-inline-size: min(26.25rem, calc(100vw - (2 * var(--hjm-space-md)))); max-block-size: 22.5rem; overflow: auto; padding: var(--hjm-space-xxs); border: 1px solid var(--hjm-color-border); border-radius: var(--hjm-radius-md); background: var(--hjm-color-bg); box-shadow: 0 8px 24px rgb(0 0 0 / 18%); }
2245
+ .hjm-select__listbox { position: fixed; z-index: var(--hjm-layer-dropdown); max-inline-size: min(26.25rem, calc(100vw - (2 * var(--hjm-space-md)))); max-block-size: 22.5rem; overflow: auto; padding: var(--hjm-select-popover-padding, var(--hjm-space-xs)); /* selectRecipe.popover.padding 8 (was 4 until 2026-10-06) */ border: 1px solid var(--hjm-color-border); border-radius: var(--hjm-radius-md); background: var(--hjm-color-bg); box-shadow: var(--hjm-shadow-floating); }
2177
2246
  .hjm-select__section-label { padding: var(--hjm-space-xs) var(--hjm-space-sm); color: var(--hjm-color-text-muted); font-size: var(--hjm-type-label-size); font-weight: var(--hjm-font-weight-semibold); }
2178
2247
  .hjm-select__option, .hjm-select__message { min-block-size: var(--hjm-control-min-touch-target); display: flex; align-items: center; gap: var(--hjm-space-sm); padding: var(--hjm-space-xs) var(--hjm-space-sm); border-radius: var(--hjm-radius-sm); overflow-wrap: anywhere; }
2179
2248
  .hjm-select[data-density="comfortable"] .hjm-select__option,
@@ -2199,14 +2268,14 @@ button.hjm-list-row, a.hjm-list-row { cursor: pointer; }
2199
2268
  }
2200
2269
  .hjm-combobox__listbox {
2201
2270
  position: fixed;
2202
- z-index: 800;
2271
+ z-index: var(--hjm-layer-dropdown);
2203
2272
  max-block-size: 22.5rem;
2204
2273
  overflow: auto;
2205
- padding: var(--hjm-space-xxs);
2274
+ padding: var(--hjm-combobox-popover-padding, var(--hjm-space-xs)); /* comboboxRecipe.popover = selectRecipe.popover, 8 (was 4 until 2026-10-06) */
2206
2275
  border: 1px solid var(--hjm-color-border);
2207
2276
  border-radius: var(--hjm-radius-md);
2208
2277
  background: var(--hjm-color-bg);
2209
- box-shadow: 0 8px 24px rgb(0 0 0 / 18%);
2278
+ box-shadow: var(--hjm-shadow-floating);
2210
2279
  }
2211
2280
  .hjm-combobox__option,
2212
2281
  .hjm-combobox__message {
@@ -2366,7 +2435,8 @@ button.hjm-list-row, a.hjm-list-row { cursor: pointer; }
2366
2435
  .hjm-file-picker__hint { color: var(--hjm-color-text-muted); }
2367
2436
  .hjm-file-picker__error { color: var(--hjm-color-danger); }
2368
2437
 
2369
- .hjm-upload-item { min-block-size: 4rem; display: flex; flex-wrap: wrap; align-items: center; gap: var(--hjm-space-sm); padding: var(--hjm-space-sm) var(--hjm-space-md); border: 1px solid var(--hjm-color-border); border-radius: var(--hjm-radius-md); }
2438
+ /* uploadItemRecipe.row: min 68 (layout.rowHeight.twoLine), padding xs 8 / md 16, gap sm (2026-10-06; Web had 64 and 12). */
2439
+ .hjm-upload-item { min-block-size: 68px; display: flex; flex-wrap: wrap; align-items: center; gap: var(--hjm-space-sm); padding: var(--hjm-space-xs) var(--hjm-space-md); border: 1px solid var(--hjm-color-border); border-radius: var(--hjm-radius-md); }
2370
2440
  .hjm-upload-item__leading { flex: 0 0 auto; }
2371
2441
  .hjm-upload-item__body { min-inline-size: 0; flex: 1 1 14rem; display: grid; gap: var(--hjm-space-xxs); }
2372
2442
  .hjm-upload-item__name { color: var(--hjm-color-text-body); overflow-wrap: anywhere; unicode-bidi: plaintext; }
@@ -2384,16 +2454,20 @@ button.hjm-list-row, a.hjm-list-row { cursor: pointer; }
2384
2454
  .hjm-date-picker__label { color: var(--hjm-color-text); font-weight: var(--hjm-font-weight-semibold); }
2385
2455
  .hjm-date-picker__anchor { position: relative; display: flex; align-items: center; }
2386
2456
  .hjm-date-picker__trigger { inline-size: 100%; min-block-size: var(--hjm-control-min-touch-target); display: flex; align-items: center; gap: var(--hjm-space-sm); padding-inline: var(--hjm-space-md) 3rem; border: 1px solid var(--hjm-color-border); border-radius: var(--hjm-radius-md); color: var(--hjm-color-text-body); background: var(--hjm-color-bg); font: inherit; text-align: start; cursor: pointer; }
2387
- .hjm-date-picker[data-size="large"] .hjm-date-picker__trigger { min-block-size: 3.5rem; padding-inline-start: var(--hjm-space-lg); }
2457
+ /* datePickerRecipe.sizes.large.minHeight is control.buttonHeight.large (52), as Select/NumberField large. Web drew 56 until 2026-10-06. */
2458
+ .hjm-date-picker[data-size="large"] .hjm-date-picker__trigger { min-block-size: var(--hjm-control-button-large); padding-inline-start: var(--hjm-space-lg); }
2388
2459
  .hjm-date-picker[data-invalid] .hjm-date-picker__trigger { border-color: var(--hjm-color-danger); }
2460
+ /* Same scope as .hjm-field (fieldRecipe.disabledScope); before 2026-10-06 a disabled DatePicker
2461
+ looked enabled on both platforms. datePickerRecipe has no amount, so the field default applies. */
2462
+ .hjm-date-picker[data-disabled] :is(.hjm-date-picker__label, .hjm-date-picker__anchor) { opacity: var(--hjm-field-disabled-opacity); }
2389
2463
  .hjm-date-picker__trigger [data-placeholder] { color: var(--hjm-color-text-muted); }
2390
2464
  .hjm-date-picker__clear { position: absolute; inset-inline-end: 0; inline-size: var(--hjm-control-min-touch-target); block-size: var(--hjm-control-min-touch-target); border: 0; color: var(--hjm-color-text-muted); background: transparent; font: inherit; cursor: pointer; }
2391
- .hjm-date-picker__popover { position: absolute; z-index: 800; inset-block-start: calc(100% + var(--hjm-space-xs)); inset-inline-start: 0; inline-size: min(22.5rem, calc(100vw - 2rem)); padding: var(--hjm-space-sm); border: 1px solid var(--hjm-color-border); border-radius: var(--hjm-radius-lg); color: var(--hjm-color-text); background: var(--hjm-color-bg); box-shadow: 0 8px 24px rgb(0 0 0 / 18%); }
2465
+ .hjm-date-picker__popover { position: absolute; z-index: var(--hjm-layer-dropdown); inset-block-start: calc(100% + var(--hjm-space-xs)); inset-inline-start: 0; inline-size: min(22.5rem, calc(100vw - 2rem)); padding: var(--hjm-space-sm); border: 1px solid var(--hjm-color-border); border-radius: var(--hjm-radius-lg); color: var(--hjm-color-text); background: var(--hjm-color-bg); box-shadow: var(--hjm-shadow-floating); }
2392
2466
  .hjm-date-picker__description { color: var(--hjm-color-text-muted); }
2393
2467
  .hjm-date-picker__error { color: var(--hjm-color-danger); }
2394
2468
 
2395
2469
  /* Toast ------------------------------------------------------------------ */
2396
- .hjm-toast-viewport { position: fixed; z-index: 1200; inset-inline: max(var(--hjm-space-md), env(safe-area-inset-left)) max(var(--hjm-space-md), env(safe-area-inset-right)); display: flex; flex-direction: column; gap: var(--hjm-space-sm); max-inline-size: min(26.25rem, calc(100vw - (2 * var(--hjm-space-md)))); margin-inline: auto; pointer-events: none; }
2470
+ .hjm-toast-viewport { position: fixed; z-index: var(--hjm-layer-toast); inset-inline: max(var(--hjm-space-md), env(safe-area-inset-left)) max(var(--hjm-space-md), env(safe-area-inset-right)); display: flex; flex-direction: column; gap: var(--hjm-space-sm); max-inline-size: min(26.25rem, calc(100vw - (2 * var(--hjm-space-md)))); margin-inline: auto; pointer-events: none; }
2397
2471
  .hjm-toast-viewport[data-placement^="top"] { inset-block-start: max(var(--hjm-space-md), env(safe-area-inset-top)); }
2398
2472
  .hjm-toast-viewport[data-placement^="bottom"] { inset-block-end: calc(max(var(--hjm-space-md), env(safe-area-inset-bottom)) + var(--hjm-toast-bottom-offset, 0px)); flex-direction: column-reverse; }
2399
2473
  .hjm-toast-viewport[data-placement$="-start"] { margin-inline-start: 0; }
@@ -2491,7 +2565,7 @@ button.hjm-list-row, a.hjm-list-row { cursor: pointer; }
2491
2565
  .hjm-top-bar[data-large-text="true"] .hjm-top-bar__title { grid-column: 1 / -1; grid-row: 2; padding-block: var(--hjm-space-xs); text-align: start; }
2492
2566
  .hjm-top-bar[data-large-text="true"] .hjm-top-bar__trailing { grid-column: 2; grid-row: 1; }
2493
2567
  .hjm-bottom-cta { display: grid; gap: var(--hjm-bottom-cta-gap); min-block-size: var(--hjm-bottom-cta-min-height); padding: var(--hjm-bottom-cta-padding-top) var(--hjm-bottom-cta-padding-inline) max(var(--hjm-bottom-cta-padding-bottom), env(safe-area-inset-bottom, 0px), var(--hjm-bottom-cta-safe-area)); border-block-start: 1px solid var(--hjm-color-border); background: var(--hjm-color-bg); }
2494
- .hjm-bottom-cta[data-position="sticky"] { position: sticky; inset-block-end: 0; z-index: 1; }
2568
+ .hjm-bottom-cta[data-position="sticky"] { position: sticky; inset-block-end: 0; z-index: var(--hjm-layer-sticky); }
2495
2569
  .hjm-bottom-cta__description { margin: 0; font-size: var(--hjm-type-caption-size); line-height: var(--hjm-type-caption-line-height); color: var(--hjm-color-text-muted); overflow-wrap: anywhere; }
2496
2570
  .hjm-bottom-cta__actions { display: flex; flex-wrap: wrap; gap: var(--hjm-bottom-cta-gap); }
2497
2571
  .hjm-bottom-cta__actions > div { flex: 1 1 calc(var(--hjm-control-min-touch-target) * 3); min-inline-size: 0; }
@@ -2517,7 +2591,7 @@ button.hjm-list-row, a.hjm-list-row { cursor: pointer; }
2517
2591
 
2518
2592
  /* The viewport action follows the content in DOM order. Its measured clearance
2519
2593
  belongs on the scroll content, not on the fixed button (docs/floating-action-button.md). */
2520
- .hjm-fab { position: fixed; z-index: 500; inset-inline-end: max(var(--hjm-fab-margin), env(safe-area-inset-right, 0px)); inset-block-end: calc(var(--hjm-fab-margin) + max(var(--hjm-fab-safe-area), env(safe-area-inset-bottom, 0px))); max-inline-size: calc(100% - var(--hjm-fab-margin) * 2); min-block-size: var(--hjm-fab-diameter); }
2594
+ .hjm-fab { position: fixed; z-index: var(--hjm-layer-sticky); inset-inline-end: max(var(--hjm-fab-margin), env(safe-area-inset-right, 0px)); inset-block-end: calc(var(--hjm-fab-margin) + max(var(--hjm-fab-safe-area), env(safe-area-inset-bottom, 0px))); max-inline-size: calc(100% - var(--hjm-fab-margin) * 2); min-block-size: var(--hjm-fab-diameter); }
2521
2595
  .hjm-fab__icon { display: flex; flex: 0 0 auto; align-items: center; justify-content: center; }
2522
2596
  .hjm-fab[data-direction="rtl"] { inset-inline-end: max(var(--hjm-fab-margin), env(safe-area-inset-left, 0px)); }
2523
2597
  .hjm-fab[data-mode="collapsed"] { inline-size: var(--hjm-fab-diameter); padding-inline: 0; gap: 0; }
@@ -2591,7 +2665,7 @@ button.hjm-list-row, a.hjm-list-row { cursor: pointer; }
2591
2665
  /* Both surfaces reuse the menu's floating look; only the anchor differs. */
2592
2666
  .hjm-context-menu-host { min-inline-size: 0; }
2593
2667
  .hjm-context-menu-host:focus-visible { outline: 2px solid var(--hjm-color-focus); outline-offset: 2px; }
2594
- .hjm-context-menu { position: fixed; max-inline-size: min(24rem, 90vw); max-block-size: calc(100dvh - (2 * var(--hjm-space-md))); overflow: auto; padding: var(--hjm-space-xxs); border: 1px solid var(--hjm-color-border); border-radius: var(--hjm-radius-md); background: var(--hjm-color-bg); box-shadow: 0 8px 24px rgb(0 0 0 / 18%); }
2668
+ .hjm-context-menu { position: fixed; max-inline-size: min(24rem, 90vw); max-block-size: calc(100dvh - (2 * var(--hjm-space-md))); overflow: auto; padding: var(--hjm-menu-padding, var(--hjm-space-xs)); /* ContextMenu reads menuRecipe like Menu (was 4 until 2026-10-06) */ border: 1px solid var(--hjm-color-border); border-radius: var(--hjm-radius-md); background: var(--hjm-color-bg); box-shadow: var(--hjm-shadow-floating); }
2595
2669
  .hjm-context-menu__item { min-block-size: var(--hjm-control-min-touch-target); display: flex; align-items: center; justify-content: space-between; gap: var(--hjm-space-sm); padding: var(--hjm-space-xs) var(--hjm-space-sm); border-radius: var(--hjm-radius-sm); color: var(--hjm-color-text-body); cursor: pointer; }
2596
2670
  /* Wrap long labels so commands stay readable inside the viewport-bounded menu; truncation was rejected because it hides command meaning. */
2597
2671
  .hjm-context-menu__item > span { min-inline-size: 0; overflow-wrap: anywhere; }
@@ -2606,7 +2680,7 @@ button.hjm-list-row, a.hjm-list-row { cursor: pointer; }
2606
2680
  .hjm-menubar__label[data-open] { background: var(--hjm-color-bg); box-shadow: inset 0 0 0 1px var(--hjm-color-content-brand); }
2607
2681
  .hjm-menubar__label:disabled { opacity: 0.5; cursor: not-allowed; }
2608
2682
  .hjm-menubar__label:focus-visible { outline: 2px solid var(--hjm-color-focus); outline-offset: 2px; }
2609
- .hjm-menubar__panel { position: absolute; inset-block-start: 100%; inset-inline-start: 0; z-index: 900; min-inline-size: 13.75rem; max-inline-size: min(24rem, 90vw); padding: var(--hjm-space-xxs); border: 1px solid var(--hjm-color-border); border-radius: var(--hjm-radius-md); background: var(--hjm-color-bg); box-shadow: 0 8px 24px rgb(0 0 0 / 18%); }
2683
+ .hjm-menubar__panel { position: absolute; inset-block-start: 100%; inset-inline-start: 0; z-index: var(--hjm-layer-dropdown); min-inline-size: 13.75rem; max-inline-size: min(24rem, 90vw); padding: var(--hjm-space-xxs); border: 1px solid var(--hjm-color-border); border-radius: var(--hjm-radius-md); background: var(--hjm-color-bg); box-shadow: var(--hjm-shadow-floating); }
2610
2684
  .hjm-menubar__item { min-block-size: var(--hjm-control-min-touch-target); display: flex; align-items: center; justify-content: space-between; gap: var(--hjm-space-sm); padding: var(--hjm-space-xs) var(--hjm-space-sm); border-radius: var(--hjm-radius-sm); color: var(--hjm-color-text-body); cursor: pointer; }
2611
2685
  .hjm-menubar__item[data-active] { background: var(--hjm-color-bg); box-shadow: inset 0 0 0 1px var(--hjm-color-content-brand); }
2612
2686
  .hjm-menubar__item[data-tone="danger"] { color: var(--hjm-color-danger); }
@@ -2689,7 +2763,7 @@ button.hjm-list-row, a.hjm-list-row { cursor: pointer; }
2689
2763
  .hjm-bottom-navigation[data-presentation="capsule"] .hjm-bottom-navigation__list {
2690
2764
  display: flex; flex: 1; min-inline-size: 0; padding: var(--hjm-space-xxs);
2691
2765
  background: var(--hjm-color-surface); border: 1px solid var(--hjm-color-border);
2692
- border-radius: var(--hjm-radius-full); box-shadow: 0 8px 24px rgb(0 0 0 / 12%);
2766
+ border-radius: var(--hjm-radius-full); box-shadow: var(--hjm-shadow-floating);
2693
2767
  }
2694
2768
  .hjm-bottom-navigation[data-presentation="capsule"] li { flex: 1; min-inline-size: 44px; }
2695
2769
  .hjm-bottom-navigation[data-presentation="capsule"][data-expanded-labels="false"] li[data-selected="true"] { flex: 2; }
@@ -2709,7 +2783,7 @@ button.hjm-list-row, a.hjm-list-row { cursor: pointer; }
2709
2783
  display: flex; flex-wrap: wrap; align-items: center; gap: var(--hjm-space-md);
2710
2784
  padding: var(--hjm-space-sm); border: 1px solid var(--hjm-color-border);
2711
2785
  border-radius: var(--hjm-radius-xl); background: var(--hjm-color-surface);
2712
- color: var(--hjm-color-text); box-shadow: 0 8px 24px rgb(0 0 0 / 12%);
2786
+ color: var(--hjm-color-text); box-shadow: var(--hjm-shadow-floating);
2713
2787
  }
2714
2788
  @supports (backdrop-filter: blur(20px)) {
2715
2789
  .hjm-navigation-bar { background: color-mix(in srgb, var(--hjm-color-surface) 92%, transparent); backdrop-filter: blur(20px); -webkit-backdrop-filter: blur(20px); }
@@ -2722,3 +2796,109 @@ button.hjm-list-row, a.hjm-list-row { cursor: pointer; }
2722
2796
  @media (prefers-reduced-transparency: reduce), (forced-colors: active) { .hjm-navigation-bar { background: var(--hjm-color-surface); backdrop-filter: none; } }
2723
2797
 
2724
2798
  [data-motion="reduced"] .hjm-bottom-navigation[data-presentation="capsule"] .hjm-bottom-navigation__item { transition: none; }
2799
+
2800
+ /* Screen bodies own remaining height so full-screen states center below the real header.
2801
+ Auto margins (not unsafe center alignment) keep oversized translations scrollable. */
2802
+ .hjm-screen { display: flex; flex-direction: column; block-size: 100%; min-block-size: 0; inline-size: 100%; max-inline-size: var(--hjm-screen-width); margin-inline: auto; background: var(--hjm-color-bg); color: var(--hjm-color-text); }
2803
+ /* Header items sit screenPatternRecipe.itemGap (sm 12) apart and the state block stateGap (md 16), as Native. Until 2026-10-06
2804
+ Web reused the content inset (16) for both, which also collapsed them to 0 with contentInset="none". */
2805
+ .hjm-screen__header { display: flex; flex-wrap: wrap; align-items: center; gap: var(--hjm-screen-item-gap, var(--hjm-space-sm)); padding: var(--hjm-screen-padding); flex: 0 0 auto; }
2806
+ .hjm-screen__heading { flex: 1 1 calc(var(--hjm-screen-header-min) * var(--hjm-text-scale, 1)); min-inline-size: 0; overflow-wrap: anywhere; }
2807
+ .hjm-screen__heading > * { margin: 0; }
2808
+ .hjm-screen__notice { padding-inline: var(--hjm-screen-padding); flex: 0 0 auto; }
2809
+ .hjm-screen__body { flex: 1 1 0%; min-block-size: 0; min-inline-size: 0; padding: var(--hjm-screen-padding); overflow-wrap: anywhere; }
2810
+ .hjm-screen__body[data-scroll="screen"] { overflow-y: auto; }
2811
+ .hjm-screen__body[data-scroll="content"] { display: flex; flex-direction: column; overflow: hidden; }
2812
+ .hjm-screen__body[data-replacement="true"] { display: flex; flex-direction: column; }
2813
+ .hjm-screen__state { margin-block: auto; flex-shrink: 0; display: flex; flex-direction: column; align-items: center; gap: var(--hjm-screen-state-gap, var(--hjm-space-md)); padding-block: var(--hjm-screen-gap); text-align: center; }
2814
+ .hjm-screen__footer { flex: 0 0 auto; padding: var(--hjm-screen-padding); padding-block-end: max(var(--hjm-screen-padding), env(safe-area-inset-bottom)); border-block-start: 1px solid var(--hjm-color-border); }
2815
+ /* SearchScreen filtersOverflow=scroll; why: screen-flows.tsx. Block padding keeps focus rings unclipped. */
2816
+ .hjm-search-screen__filters { --f: calc(var(--hjm-focus-width) + var(--hjm-focus-offset)); overflow-x: auto; margin: calc(-1 * var(--f)) calc(-1 * var(--hjm-screen-padding)); padding: var(--f) var(--hjm-screen-padding); scroll-padding-inline: var(--hjm-screen-padding); scrollbar-width: none; }
2817
+ .hjm-search-screen__filters > * { inline-size: max-content; }
2818
+
2819
+ /* Settings use spacing and rules, not shaded cards, per the 2026-10-05 product direction. */
2820
+ .hjm-settings-section > .hjm-section__content { background: transparent; border-block-start: 1px solid var(--hjm-color-border); }
2821
+ .hjm-settings-section .hjm-list-row { background: transparent; }
2822
+ .hjm-notification-item { border-radius: 0; }
2823
+ .hjm-notification-item[data-unread="true"] { background: transparent; }
2824
+ /* screenPatternRecipe.itemGap (sm 12) between the context/reply/attachment rows and between the editor and send, as Native.
2825
+ Web drew xs 8 until 2026-10-06. */
2826
+ .hjm-message-composer { display: flex; flex-direction: column; gap: var(--hjm-message-composer-gap, var(--hjm-space-sm)); }
2827
+ .hjm-message-composer__row { display: flex; gap: var(--hjm-message-composer-gap, var(--hjm-space-sm)); align-items: flex-end; }
2828
+ .hjm-message-composer__row > .hjm-field { flex: 1; min-inline-size: 0; }
2829
+ .hjm-message-composer__row > .hjm-button { flex-shrink: 0; }
2830
+ .hjm-chat-message { display: flex; align-items: flex-start; gap: var(--hjm-space-xs); }
2831
+ .hjm-chat-message[data-direction="outgoing"] { flex-direction: row-reverse; }
2832
+ /* A visible opposite edge distinguishes authorship even without color; long copy still wraps. */
2833
+ .hjm-chat-message__content { max-inline-size: var(--hjm-message-max-width); min-inline-size: 0; display: flex; flex-direction: column; align-items: flex-start; gap: var(--hjm-space-xxs); }
2834
+ .hjm-chat-message[data-direction="outgoing"] .hjm-chat-message__content { align-items: flex-end; }
2835
+ .hjm-chat-message__bubble { border: var(--hjm-stroke-default) solid var(--hjm-color-border); border-radius: var(--hjm-radius-lg); background: var(--hjm-color-bg); padding: var(--hjm-space-sm); overflow-wrap: anywhere; white-space: pre-wrap; }
2836
+ .hjm-chat-message[data-direction="outgoing"] .hjm-chat-message__bubble { background: var(--hjm-color-surface-accent); }
2837
+ .hjm-chat-message__meta { display: flex; align-items: center; gap: var(--hjm-space-xs); }
2838
+ .hjm-chat-message__reply { border-inline-start: 2px solid var(--hjm-color-content-brand); padding-inline-start: var(--hjm-space-xs); margin-block-end: var(--hjm-space-xs); }
2839
+
2840
+ /* A composer starts at one control row rather than the document editor minimum;
2841
+ content sizing grows up to the shared line cap without stealing the timeline. */
2842
+ .hjm-message-composer__row > .hjm-field { --hjm-field-multiline-min-height: var(--hjm-control-field-height); }
2843
+ .hjm-message-composer textarea { field-sizing: content; resize: none; }
2844
+
2845
+ /* Social composition: one field boundary and no permanent attachment toolbar. */
2846
+ .hjm-field__control--multiline > .hjm-field__trailing { align-self: flex-end; }
2847
+ /* TextArea leadingAction: an action, so no muted .hjm-field__affix color; centred on the growing text. */
2848
+ .hjm-field__control--multiline > .hjm-field__leading { display: flex; align-self: center; }
2849
+ .hjm-message-composer__attachments { display: flex; gap: var(--hjm-space-sm); align-items: center; overflow-x: auto; }
2850
+ .hjm-message-composer__attachment { position: relative; flex: 0 0 var(--hjm-attachment-size); inline-size: var(--hjm-attachment-size); block-size: var(--hjm-attachment-size); }
2851
+ .hjm-message-composer__preview { inline-size: 100%; block-size: 100%; border-radius: var(--hjm-radius-md); overflow: hidden; }
2852
+ .hjm-message-composer__preview > img { inline-size: 100%; block-size: 100%; object-fit: cover; }
2853
+ /* Clip only the photo: its rounded mask must not cut the remove button or focus ring. */
2854
+ .hjm-message-composer__remove { position: absolute; inset-block-start: 0; inset-inline-end: 0; }
2855
+ .hjm-message-composer__remove-glyph { display: grid; place-items: center; flex: 0 0 auto; inline-size: var(--hjm-attachment-remove-size); block-size: var(--hjm-attachment-remove-size); font-size: calc(var(--hjm-attachment-remove-size) * .75); line-height: 1; background: var(--hjm-color-bg); border-radius: var(--hjm-radius-full); }
2856
+ .hjm-message-reactions { border-radius: var(--hjm-radius-full); padding: var(--hjm-space-xs); max-inline-size: calc(100vw - 24px); inline-size: max-content; }
2857
+ /* Keep Popover's localized heading/close action available to assistive technology. */
2858
+ .hjm-message-reactions > .hjm-popover__header { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
2859
+ /* The close button stays a Tab stop (Escape is not discoverable for every keyboard user), so
2860
+ reveal the header while it holds focus instead of leaving a 1px focus target. Removing the
2861
+ button from the tab order was rejected: it would leave the dialog without a visible exit. */
2862
+ .hjm-message-reactions > .hjm-popover__header:focus-within { position: static; width: auto; height: auto; margin: 0 0 var(--hjm-space-xs); overflow: visible; clip-path: none; white-space: normal; }
2863
+
2864
+ /* The expanded reaction catalog needs a bounded panel rather than the quick-row pill. */
2865
+ .hjm-message-reactions:has([data-expanded="true"]) { border-radius: var(--hjm-radius-lg); inline-size: min(20rem, calc(100vw - 24px)); }
2866
+
2867
+ /* ReactionPicker. 20rem is screenPatternRecipe.reactionMenuWidth (320) and 15rem matches Native's
2868
+ 240pt catalog height at the default root size; rem keeps both proportional to large text.
2869
+ Copied here because importing screen-patterns would add a module edge to the ./reaction-picker
2870
+ entry (budget: 3 modules). Remove the copies when the reactions contract exports these sizes. */
2871
+ .hjm-reaction-picker { display: flex; flex-direction: row; min-inline-size: 0; }
2872
+ .hjm-reaction-picker[data-expanded] { flex-direction: column; }
2873
+ .hjm-reaction-picker__options { display: flex; flex: 1; flex-wrap: wrap; gap: var(--hjm-space-xs); min-inline-size: 0; }
2874
+ .hjm-reaction-picker[data-layout="strip"]:not([data-expanded]) > .hjm-reaction-picker__options { flex-wrap: nowrap; overflow-x: auto; }
2875
+ .hjm-reaction-picker[data-expanded] > .hjm-reaction-picker__options { overflow-y: auto; max-block-size: 15rem; inline-size: min(20rem, 100%); }
2876
+ .hjm-reaction-picker > :last-child { flex-shrink: 0; }
2877
+ /* Only the chat strip enlarges glyphs, to the title type step Native's strip uses. The default
2878
+ wrap layout keeps the button's own size, as published before the strip existed. */
2879
+ .hjm-reaction-picker[data-layout="strip"] .hjm-reaction-picker__glyph { font-size: var(--hjm-type-title-size); line-height: var(--hjm-type-title-line-height); }
2880
+
2881
+ /* The embedded circle uses the small 36px recipe; centre it in the field rather than on the text baseline.
2882
+ Reduce only its trailing inset to 8px, preserving the text's 16px leading padding. */
2883
+ .hjm-message-composer[data-send-presentation="circle"] .hjm-field__trailing { display: flex; align-self: center; margin-inline-end: calc(var(--hjm-space-xs) - var(--hjm-space-md)); margin-inline-start: var(--hjm-space-sm); }
2884
+
2885
+ /* Saved collections use a two-column cover grid, then a dense three-column media grid.
2886
+ Product thumbnails are slots; colors and spacing stay on HJM semantic tokens. */
2887
+ .hjm-saved-collection,.hjm-saved-post { min-width:0; margin:0; padding:0; border:0; background:transparent; color:inherit; font:inherit; text-align:start; cursor:pointer; }
2888
+ .hjm-saved-collection { display:flex; flex-direction:column; gap:var(--hjm-space-sm); }
2889
+ .hjm-saved-collection__cover { display:grid; grid-template-columns:repeat(2,minmax(0,1fr)); width:100%; aspect-ratio:1; gap:var(--hjm-space-xxs); overflow:hidden; border-radius:var(--hjm-radius-md); background:var(--hjm-color-surface-alt); }
2890
+ .hjm-saved-collection__cover > span { min-width:0; min-height:0; overflow:hidden; }
2891
+ .hjm-saved-post { aspect-ratio:1; overflow:hidden; background:var(--hjm-color-surface-alt); }
2892
+ .hjm-saved-collection__cover img,.hjm-saved-post img { width:100%; height:100%; object-fit:cover; border-radius:0; display:block; }
2893
+ .hjm-saved-collection:focus-visible,.hjm-saved-post:focus-visible { outline:2px solid var(--hjm-color-focus); outline-offset:2px; }
2894
+
2895
+ /* Filter pills keep the same native radio semantics and 44px hit target. The inner
2896
+ surface is compact; the group wraps at large type instead of clipping labels. */
2897
+ .hjm-segmented[data-presentation="pills"] { background:transparent; border:0; padding:0; }
2898
+ .hjm-segmented[data-presentation="pills"] .hjm-segmented__items { flex-wrap:wrap; gap:var(--hjm-space-xs); overflow:visible; padding:0; border:0; border-radius:0; background:transparent; }
2899
+ .hjm-segmented[data-presentation="pills"] .hjm-segmented__item { position:relative; flex:0 1 auto; min-inline-size:0; min-block-size:var(--hjm-control-min-touch-target); border:0; border-radius:var(--hjm-radius-full); background:transparent; box-shadow:none; padding-inline:var(--hjm-space-md); color:var(--hjm-color-text-muted); }
2900
+ .hjm-segmented[data-presentation="pills"] .hjm-segmented__item::before { content:""; position:absolute; inset:var(--hjm-space-xs) 0; border-radius:var(--hjm-radius-full); background:var(--hjm-color-surface-alt); }
2901
+ .hjm-segmented[data-presentation="pills"] .hjm-segmented__item > span { position:relative; overflow-wrap:anywhere; }
2902
+ .hjm-segmented[data-presentation="pills"] .hjm-segmented__item[data-state="checked"] { color:var(--hjm-color-bg); font-weight:var(--hjm-font-weight-bold); }
2903
+ .hjm-segmented[data-presentation="pills"] .hjm-segmented__item[data-state="checked"]::before { background:var(--hjm-color-text-body); }
2904
+ .hjm-segmented[data-presentation="pills"] .hjm-segmented__item:focus-within { outline:2px solid var(--hjm-color-focus); outline-offset:2px; }