@panphora/bevel 0.1.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 (539) hide show
  1. package/LICENSE +16 -0
  2. package/README.md +226 -0
  3. package/bevel-fonts.css +16 -0
  4. package/bevel.css +3075 -0
  5. package/bevel.js +2126 -0
  6. package/dist/react/components/activity-feed.d.ts +89 -0
  7. package/dist/react/components/activity-feed.js +54 -0
  8. package/dist/react/components/alert-dialog.d.ts +14 -0
  9. package/dist/react/components/alert-dialog.js +19 -0
  10. package/dist/react/components/app-shell.d.ts +98 -0
  11. package/dist/react/components/app-shell.js +86 -0
  12. package/dist/react/components/app-toolbar.d.ts +19 -0
  13. package/dist/react/components/app-toolbar.js +22 -0
  14. package/dist/react/components/avatar-group.d.ts +67 -0
  15. package/dist/react/components/avatar-group.js +49 -0
  16. package/dist/react/components/badge-and-pill.d.ts +34 -0
  17. package/dist/react/components/badge-and-pill.js +12 -0
  18. package/dist/react/components/breadcrumbs.d.ts +56 -0
  19. package/dist/react/components/breadcrumbs.js +44 -0
  20. package/dist/react/components/bulk-bar.d.ts +22 -0
  21. package/dist/react/components/bulk-bar.js +59 -0
  22. package/dist/react/components/button.d.ts +15 -0
  23. package/dist/react/components/button.js +20 -0
  24. package/dist/react/components/callout-and-hint.d.ts +17 -0
  25. package/dist/react/components/callout-and-hint.js +8 -0
  26. package/dist/react/components/checkbox.d.ts +5 -0
  27. package/dist/react/components/checkbox.js +13 -0
  28. package/dist/react/components/chip.d.ts +149 -0
  29. package/dist/react/components/chip.js +29 -0
  30. package/dist/react/components/code-block.d.ts +50 -0
  31. package/dist/react/components/code-block.js +77 -0
  32. package/dist/react/components/code-editor.d.ts +122 -0
  33. package/dist/react/components/code-editor.js +695 -0
  34. package/dist/react/components/column-manager.d.ts +28 -0
  35. package/dist/react/components/column-manager.js +85 -0
  36. package/dist/react/components/combobox.d.ts +32 -0
  37. package/dist/react/components/combobox.js +37 -0
  38. package/dist/react/components/data-grid.d.ts +108 -0
  39. package/dist/react/components/data-grid.js +159 -0
  40. package/dist/react/components/data-table.d.ts +2 -0
  41. package/dist/react/components/data-table.js +6 -0
  42. package/dist/react/components/date.d.ts +23 -0
  43. package/dist/react/components/date.js +11 -0
  44. package/dist/react/components/details.d.ts +13 -0
  45. package/dist/react/components/details.js +20 -0
  46. package/dist/react/components/dialog.d.ts +74 -0
  47. package/dist/react/components/dialog.js +31 -0
  48. package/dist/react/components/diff-view.d.ts +73 -0
  49. package/dist/react/components/diff-view.js +68 -0
  50. package/dist/react/components/documents.d.ts +70 -0
  51. package/dist/react/components/documents.js +10 -0
  52. package/dist/react/components/drawer.d.ts +45 -0
  53. package/dist/react/components/drawer.js +35 -0
  54. package/dist/react/components/editable-grid-cells.d.ts +32 -0
  55. package/dist/react/components/editable-grid-cells.js +116 -0
  56. package/dist/react/components/eyebrow-kicker-lede-pull-quote.d.ts +39 -0
  57. package/dist/react/components/eyebrow-kicker-lede-pull-quote.js +12 -0
  58. package/dist/react/components/field.d.ts +32 -0
  59. package/dist/react/components/field.js +27 -0
  60. package/dist/react/components/file-tree.d.ts +75 -0
  61. package/dist/react/components/file-tree.js +247 -0
  62. package/dist/react/components/file.d.ts +43 -0
  63. package/dist/react/components/file.js +73 -0
  64. package/dist/react/components/files-table.d.ts +174 -0
  65. package/dist/react/components/files-table.js +237 -0
  66. package/dist/react/components/filter-builder.d.ts +37 -0
  67. package/dist/react/components/filter-builder.js +109 -0
  68. package/dist/react/components/form-error-summary.d.ts +16 -0
  69. package/dist/react/components/form-error-summary.js +49 -0
  70. package/dist/react/components/icon-button.d.ts +8 -0
  71. package/dist/react/components/icon-button.js +14 -0
  72. package/dist/react/components/icon.d.ts +7 -0
  73. package/dist/react/components/icon.js +15 -0
  74. package/dist/react/components/image.d.ts +72 -0
  75. package/dist/react/components/image.js +24 -0
  76. package/dist/react/components/inline-edit.d.ts +70 -0
  77. package/dist/react/components/inline-edit.js +149 -0
  78. package/dist/react/components/input.d.ts +29 -0
  79. package/dist/react/components/input.js +20 -0
  80. package/dist/react/components/kanban-board.d.ts +140 -0
  81. package/dist/react/components/kanban-board.js +374 -0
  82. package/dist/react/components/layout.d.ts +51 -0
  83. package/dist/react/components/layout.js +28 -0
  84. package/dist/react/components/list.d.ts +28 -0
  85. package/dist/react/components/list.js +6 -0
  86. package/dist/react/components/masthead-and-verdict.d.ts +60 -0
  87. package/dist/react/components/masthead-and-verdict.js +8 -0
  88. package/dist/react/components/menu.d.ts +26 -0
  89. package/dist/react/components/menu.js +31 -0
  90. package/dist/react/components/multi-select-picker.d.ts +49 -0
  91. package/dist/react/components/multi-select-picker.js +20 -0
  92. package/dist/react/components/note.d.ts +33 -0
  93. package/dist/react/components/note.js +8 -0
  94. package/dist/react/components/number-field.d.ts +16 -0
  95. package/dist/react/components/number-field.js +17 -0
  96. package/dist/react/components/pagination.d.ts +45 -0
  97. package/dist/react/components/pagination.js +87 -0
  98. package/dist/react/components/persistent-action-banner.d.ts +71 -0
  99. package/dist/react/components/persistent-action-banner.js +39 -0
  100. package/dist/react/components/popconfirm.d.ts +42 -0
  101. package/dist/react/components/popconfirm.js +59 -0
  102. package/dist/react/components/popover.d.ts +16 -0
  103. package/dist/react/components/popover.js +21 -0
  104. package/dist/react/components/progress-and-gauge.d.ts +44 -0
  105. package/dist/react/components/progress-and-gauge.js +19 -0
  106. package/dist/react/components/radio.d.ts +7 -0
  107. package/dist/react/components/radio.js +13 -0
  108. package/dist/react/components/rich-text-toolbar.d.ts +26 -0
  109. package/dist/react/components/rich-text-toolbar.js +64 -0
  110. package/dist/react/components/rows-and-card.d.ts +88 -0
  111. package/dist/react/components/rows-and-card.js +10 -0
  112. package/dist/react/components/save-status-indicator.d.ts +11 -0
  113. package/dist/react/components/save-status-indicator.js +33 -0
  114. package/dist/react/components/segmented-control.d.ts +21 -0
  115. package/dist/react/components/segmented-control.js +15 -0
  116. package/dist/react/components/select.d.ts +29 -0
  117. package/dist/react/components/select.js +29 -0
  118. package/dist/react/components/selectable-cards.d.ts +30 -0
  119. package/dist/react/components/selectable-cards.js +29 -0
  120. package/dist/react/components/settings-rows.d.ts +51 -0
  121. package/dist/react/components/settings-rows.js +8 -0
  122. package/dist/react/components/sidebar-nav.d.ts +77 -0
  123. package/dist/react/components/sidebar-nav.js +41 -0
  124. package/dist/react/components/skeleton-and-empty.d.ts +51 -0
  125. package/dist/react/components/skeleton-and-empty.js +14 -0
  126. package/dist/react/components/slider.d.ts +19 -0
  127. package/dist/react/components/slider.js +17 -0
  128. package/dist/react/components/small-charts.d.ts +60 -0
  129. package/dist/react/components/small-charts.js +76 -0
  130. package/dist/react/components/sortable.d.ts +30 -0
  131. package/dist/react/components/sortable.js +85 -0
  132. package/dist/react/components/split-button.d.ts +38 -0
  133. package/dist/react/components/split-button.js +43 -0
  134. package/dist/react/components/split-panes.d.ts +35 -0
  135. package/dist/react/components/split-panes.js +102 -0
  136. package/dist/react/components/stat-tiles.d.ts +54 -0
  137. package/dist/react/components/stat-tiles.js +8 -0
  138. package/dist/react/components/steps.d.ts +11 -0
  139. package/dist/react/components/steps.js +13 -0
  140. package/dist/react/components/switch.d.ts +6 -0
  141. package/dist/react/components/switch.js +13 -0
  142. package/dist/react/components/table.d.ts +61 -0
  143. package/dist/react/components/table.js +6 -0
  144. package/dist/react/components/tabs.d.ts +7 -0
  145. package/dist/react/components/tabs.js +13 -0
  146. package/dist/react/components/tags.d.ts +33 -0
  147. package/dist/react/components/tags.js +83 -0
  148. package/dist/react/components/textarea.d.ts +10 -0
  149. package/dist/react/components/textarea.js +6 -0
  150. package/dist/react/components/toast.d.ts +35 -0
  151. package/dist/react/components/toast.js +90 -0
  152. package/dist/react/components/tooltip-and-key.d.ts +20 -0
  153. package/dist/react/components/tooltip-and-key.js +20 -0
  154. package/dist/react/components/tree-view.d.ts +34 -0
  155. package/dist/react/components/tree-view.js +118 -0
  156. package/dist/react/components/upload-dropzone.d.ts +92 -0
  157. package/dist/react/components/upload-dropzone.js +116 -0
  158. package/dist/react/components/wizard-shell.d.ts +78 -0
  159. package/dist/react/components/wizard-shell.js +176 -0
  160. package/dist/react/fonts.css.d.ts +1 -0
  161. package/dist/react/index.d.ts +76 -0
  162. package/dist/react/index.js +77 -0
  163. package/dist/react/integrations/quickcrop.d.ts +58 -0
  164. package/dist/react/integrations/quickcrop.js +137 -0
  165. package/dist/react/integrations/richclay.d.ts +43 -0
  166. package/dist/react/integrations/richclay.js +129 -0
  167. package/dist/react/internal/classes.d.ts +3 -0
  168. package/dist/react/internal/classes.js +10 -0
  169. package/dist/react/internal/close-mark.d.ts +1 -0
  170. package/dist/react/internal/close-mark.js +10 -0
  171. package/dist/react/internal/controllable-state.d.ts +9 -0
  172. package/dist/react/internal/controllable-state.js +22 -0
  173. package/dist/react/internal/drop-effect.d.ts +28 -0
  174. package/dist/react/internal/drop-effect.js +8 -0
  175. package/dist/react/internal/form-reset.d.ts +2 -0
  176. package/dist/react/internal/form-reset.js +22 -0
  177. package/dist/react/internal/format.d.ts +1 -0
  178. package/dist/react/internal/format.js +14 -0
  179. package/dist/react/internal/link.d.ts +2 -0
  180. package/dist/react/internal/link.js +8 -0
  181. package/dist/react/internal/part.d.ts +20 -0
  182. package/dist/react/internal/part.js +47 -0
  183. package/dist/react/internal/pointer-session.d.ts +8 -0
  184. package/dist/react/internal/pointer-session.js +60 -0
  185. package/dist/react/internal/refs.d.ts +2 -0
  186. package/dist/react/internal/refs.js +22 -0
  187. package/dist/react/internal/rich-text.d.ts +28 -0
  188. package/dist/react/internal/rich-text.js +4 -0
  189. package/dist/react/internal/table-context.d.ts +39 -0
  190. package/dist/react/internal/table-context.js +12 -0
  191. package/dist/react/internal/use-object-url.d.ts +1 -0
  192. package/dist/react/internal/use-object-url.js +15 -0
  193. package/dist/react/layout.css +274 -0
  194. package/dist/react/layout.css.d.ts +1 -0
  195. package/dist/react/models/filter.d.ts +31 -0
  196. package/dist/react/models/filter.js +79 -0
  197. package/dist/react/models/kanban.d.ts +51 -0
  198. package/dist/react/models/kanban.js +35 -0
  199. package/dist/react/models/reorder.d.ts +9 -0
  200. package/dist/react/models/reorder.js +23 -0
  201. package/dist/react/models/table.d.ts +85 -0
  202. package/dist/react/models/table.js +144 -0
  203. package/dist/react/models/tree.d.ts +16 -0
  204. package/dist/react/models/tree.js +26 -0
  205. package/dist/react/provider.d.ts +18 -0
  206. package/dist/react/provider.js +31 -0
  207. package/dist/react/recipes/context-hypercms.d.ts +17 -0
  208. package/dist/react/recipes/context-hypercms.js +71 -0
  209. package/dist/react/recipes/context-quickcrop.d.ts +8 -0
  210. package/dist/react/recipes/context-quickcrop.js +49 -0
  211. package/dist/react/theme.css +8004 -0
  212. package/dist/react/theme.css.d.ts +1 -0
  213. package/examples/README.md +34 -0
  214. package/examples/components/activity-feed.html +28 -0
  215. package/examples/components/app-shell.html +12 -0
  216. package/examples/components/app-toolbar.html +38 -0
  217. package/examples/components/avatar-group.html +27 -0
  218. package/examples/components/breadcrumbs.html +26 -0
  219. package/examples/components/bulk-bar.html +22 -0
  220. package/examples/components/code-block.html +12 -0
  221. package/examples/components/code-editor.html +25 -0
  222. package/examples/components/column-manager.html +9 -0
  223. package/examples/components/combobox.html +13 -0
  224. package/examples/components/context-hypercms.css +41 -0
  225. package/examples/components/context-hypercms.html +40 -0
  226. package/examples/components/context-hypercms.js +62 -0
  227. package/examples/components/context-quickcrop.html +137 -0
  228. package/examples/components/diff-view.html +9 -0
  229. package/examples/components/drawer.html +11 -0
  230. package/examples/components/editable-grid-cells.html +9 -0
  231. package/examples/components/file-browser.html +53 -0
  232. package/examples/components/file-tree.html +34 -0
  233. package/examples/components/files-table.html +80 -0
  234. package/examples/components/filter-builder.html +11 -0
  235. package/examples/components/form-error-summary.html +11 -0
  236. package/examples/components/index.html +51 -0
  237. package/examples/components/inline-edit.html +42 -0
  238. package/examples/components/kanban-board.html +42 -0
  239. package/examples/components/manifest.json +3279 -0
  240. package/examples/components/modal.html +11 -0
  241. package/examples/components/multi-select-picker.html +13 -0
  242. package/examples/components/pagination.html +32 -0
  243. package/examples/components/persistent-action-banner.html +23 -0
  244. package/examples/components/popconfirm.html +13 -0
  245. package/examples/components/popover-menu.html +13 -0
  246. package/examples/components/reference/baseline/DECISIONS.md +85 -0
  247. package/examples/components/reference/baseline/README.md +58 -0
  248. package/examples/components/reference/baseline/bevel-fonts.css +16 -0
  249. package/examples/components/reference/baseline/bevel.css +1339 -0
  250. package/examples/components/reference/baseline/bevel.js +496 -0
  251. package/examples/components/reference/baseline/fonts/LICENSE-ibm-plex-mono.txt +93 -0
  252. package/examples/components/reference/baseline/fonts/LICENSE-ibm-plex-sans.txt +93 -0
  253. package/examples/components/reference/baseline/fonts/LICENSE-newsreader.txt +93 -0
  254. package/examples/components/reference/baseline/fonts/ibm-plex-mono-latin-400-normal.woff2 +0 -0
  255. package/examples/components/reference/baseline/fonts/ibm-plex-mono-latin-500-normal.woff2 +0 -0
  256. package/examples/components/reference/baseline/fonts/ibm-plex-mono-latin-600-normal.woff2 +0 -0
  257. package/examples/components/reference/baseline/fonts/ibm-plex-sans-latin-400-italic.woff2 +0 -0
  258. package/examples/components/reference/baseline/fonts/ibm-plex-sans-latin-400-normal.woff2 +0 -0
  259. package/examples/components/reference/baseline/fonts/ibm-plex-sans-latin-500-normal.woff2 +0 -0
  260. package/examples/components/reference/baseline/fonts/ibm-plex-sans-latin-600-normal.woff2 +0 -0
  261. package/examples/components/reference/baseline/fonts/newsreader-latin-opsz-italic.woff2 +0 -0
  262. package/examples/components/reference/baseline/fonts/newsreader-latin-opsz-normal.woff2 +0 -0
  263. package/examples/components/reference/fable/IMPROVEMENTS.md +106 -0
  264. package/examples/components/reference/fable/PARENT-REPAIRS.md +17 -0
  265. package/examples/components/reference/fable/__pycache__/build_repairs.cpython-311.pyc +0 -0
  266. package/examples/components/reference/fable/__pycache__/kanban.cpython-311.pyc +0 -0
  267. package/examples/components/reference/fable/as-authored/IMPROVEMENTS-completed.md +106 -0
  268. package/examples/components/reference/fable/as-authored/base-astra.css +17 -0
  269. package/examples/components/reference/fable/as-authored/base-parent.css +416 -0
  270. package/examples/components/reference/fable/as-authored/build.py +858 -0
  271. package/examples/components/reference/fable/as-authored/fable.css +823 -0
  272. package/examples/components/reference/fable/as-authored/kanban-completed.css +235 -0
  273. package/examples/components/reference/fable/as-authored/kanban-completed.html +53 -0
  274. package/examples/components/reference/fable/as-authored/kanban-completed.py +212 -0
  275. package/examples/components/reference/fable/as-authored/kanban.py +207 -0
  276. package/examples/components/reference/fable/base-astra.css +17 -0
  277. package/examples/components/reference/fable/base-parent.css +416 -0
  278. package/examples/components/reference/fable/build.py +858 -0
  279. package/examples/components/reference/fable/build_repairs.py +25 -0
  280. package/examples/components/reference/fable/components/activity-feed.html +3 -0
  281. package/examples/components/reference/fable/components/app-toolbar.html +3 -0
  282. package/examples/components/reference/fable/components/avatar-group.html +4 -0
  283. package/examples/components/reference/fable/components/breadcrumbs.html +3 -0
  284. package/examples/components/reference/fable/components/code-block.html +9 -0
  285. package/examples/components/reference/fable/components/column-manager.html +3 -0
  286. package/examples/components/reference/fable/components/combobox.html +6 -0
  287. package/examples/components/reference/fable/components/context-hypercms.html +3 -0
  288. package/examples/components/reference/fable/components/context-quickcrop.html +4 -0
  289. package/examples/components/reference/fable/components/diff-view.html +13 -0
  290. package/examples/components/reference/fable/components/drawer.html +3 -0
  291. package/examples/components/reference/fable/components/editable-grid-cells.html +3 -0
  292. package/examples/components/reference/fable/components/filter-builder.html +3 -0
  293. package/examples/components/reference/fable/components/form-error-summary.html +4 -0
  294. package/examples/components/reference/fable/components/inline-edit.html +3 -0
  295. package/examples/components/reference/fable/components/kanban-board.html +53 -0
  296. package/examples/components/reference/fable/components/modal.html +3 -0
  297. package/examples/components/reference/fable/components/multi-select-picker.html +5 -0
  298. package/examples/components/reference/fable/components/pagination.html +3 -0
  299. package/examples/components/reference/fable/components/persistent-action-banner.html +4 -0
  300. package/examples/components/reference/fable/components/popconfirm.html +5 -0
  301. package/examples/components/reference/fable/components/popover-menu.html +3 -0
  302. package/examples/components/reference/fable/components/rich-text-toolbar.html +3 -0
  303. package/examples/components/reference/fable/components/save-status-indicator.html +2 -0
  304. package/examples/components/reference/fable/components/selectable-cards.html +3 -0
  305. package/examples/components/reference/fable/components/settings-rows.html +3 -0
  306. package/examples/components/reference/fable/components/sidebar-nav.html +4 -0
  307. package/examples/components/reference/fable/components/small-charts.html +5 -0
  308. package/examples/components/reference/fable/components/split-button.html +4 -0
  309. package/examples/components/reference/fable/components/split-panes.html +8 -0
  310. package/examples/components/reference/fable/components/stat-tiles.html +3 -0
  311. package/examples/components/reference/fable/components/toast-stack.html +5 -0
  312. package/examples/components/reference/fable/components/tree-view.html +4 -0
  313. package/examples/components/reference/fable/components/upload-dropzone.html +6 -0
  314. package/examples/components/reference/fable/components/wizard-shell.html +3 -0
  315. package/examples/components/reference/fable/coverage.json +414 -0
  316. package/examples/components/reference/fable/fable.css +823 -0
  317. package/examples/components/reference/fable/index.html +5 -0
  318. package/examples/components/reference/fable/kanban.css +237 -0
  319. package/examples/components/reference/fable/kanban.py +212 -0
  320. package/examples/components/reference/fable/parent-repairs.css +9 -0
  321. package/examples/components/reference/fixtures/data.json +102 -0
  322. package/examples/components/reference/fixtures/host.js +47 -0
  323. package/examples/components/reference/fixtures/static-host.js +39 -0
  324. package/examples/components/reference/fixtures/workspace.jpg +0 -0
  325. package/examples/components/reference/parent/CHANGES.md +179 -0
  326. package/examples/components/reference/parent/__pycache__/kanban.cpython-311.pyc +0 -0
  327. package/examples/components/reference/parent/base-astra.css +17 -0
  328. package/examples/components/reference/parent/base-parent.css +416 -0
  329. package/examples/components/reference/parent/build.py +148 -0
  330. package/examples/components/reference/parent/components/activity-feed.html +2 -0
  331. package/examples/components/reference/parent/components/app-toolbar.html +2 -0
  332. package/examples/components/reference/parent/components/avatar-group.html +4 -0
  333. package/examples/components/reference/parent/components/breadcrumbs.html +2 -0
  334. package/examples/components/reference/parent/components/code-block.html +8 -0
  335. package/examples/components/reference/parent/components/column-manager.html +2 -0
  336. package/examples/components/reference/parent/components/combobox.html +6 -0
  337. package/examples/components/reference/parent/components/context-hypercms.html +2 -0
  338. package/examples/components/reference/parent/components/context-quickcrop.html +4 -0
  339. package/examples/components/reference/parent/components/diff-view.html +4 -0
  340. package/examples/components/reference/parent/components/drawer.html +2 -0
  341. package/examples/components/reference/parent/components/editable-grid-cells.html +2 -0
  342. package/examples/components/reference/parent/components/filter-builder.html +2 -0
  343. package/examples/components/reference/parent/components/form-error-summary.html +2 -0
  344. package/examples/components/reference/parent/components/inline-edit.html +2 -0
  345. package/examples/components/reference/parent/components/kanban-board.html +84 -0
  346. package/examples/components/reference/parent/components/modal.html +2 -0
  347. package/examples/components/reference/parent/components/multi-select-picker.html +5 -0
  348. package/examples/components/reference/parent/components/pagination.html +2 -0
  349. package/examples/components/reference/parent/components/persistent-action-banner.html +4 -0
  350. package/examples/components/reference/parent/components/popconfirm.html +5 -0
  351. package/examples/components/reference/parent/components/popover-menu.html +2 -0
  352. package/examples/components/reference/parent/components/rich-text-toolbar.html +2 -0
  353. package/examples/components/reference/parent/components/save-status-indicator.html +2 -0
  354. package/examples/components/reference/parent/components/selectable-cards.html +2 -0
  355. package/examples/components/reference/parent/components/settings-rows.html +2 -0
  356. package/examples/components/reference/parent/components/sidebar-nav.html +4 -0
  357. package/examples/components/reference/parent/components/small-charts.html +2 -0
  358. package/examples/components/reference/parent/components/split-button.html +5 -0
  359. package/examples/components/reference/parent/components/split-panes.html +8 -0
  360. package/examples/components/reference/parent/components/stat-tiles.html +2 -0
  361. package/examples/components/reference/parent/components/toast-stack.html +5 -0
  362. package/examples/components/reference/parent/components/tree-view.html +4 -0
  363. package/examples/components/reference/parent/components/upload-dropzone.html +6 -0
  364. package/examples/components/reference/parent/components/wizard-shell.html +2 -0
  365. package/examples/components/reference/parent/coverage.json +414 -0
  366. package/examples/components/reference/parent/index.html +1 -0
  367. package/examples/components/reference/parent/kanban.css +114 -0
  368. package/examples/components/reference/parent/kanban.py +55 -0
  369. package/examples/components/reference/parent/refinement.css +53 -0
  370. package/examples/components/reference/selected/build.py +70 -0
  371. package/examples/components/reference/selected/components/activity-feed.html +3 -0
  372. package/examples/components/reference/selected/components/app-toolbar.html +3 -0
  373. package/examples/components/reference/selected/components/avatar-group.html +4 -0
  374. package/examples/components/reference/selected/components/breadcrumbs.html +3 -0
  375. package/examples/components/reference/selected/components/code-block.html +9 -0
  376. package/examples/components/reference/selected/components/column-manager.html +3 -0
  377. package/examples/components/reference/selected/components/combobox.html +6 -0
  378. package/examples/components/reference/selected/components/context-hypercms.html +3 -0
  379. package/examples/components/reference/selected/components/context-quickcrop.html +4 -0
  380. package/examples/components/reference/selected/components/diff-view.html +13 -0
  381. package/examples/components/reference/selected/components/drawer.html +3 -0
  382. package/examples/components/reference/selected/components/editable-grid-cells.html +3 -0
  383. package/examples/components/reference/selected/components/filter-builder.html +3 -0
  384. package/examples/components/reference/selected/components/form-error-summary.html +4 -0
  385. package/examples/components/reference/selected/components/inline-edit.html +3 -0
  386. package/examples/components/reference/selected/components/kanban-board.html +53 -0
  387. package/examples/components/reference/selected/components/modal.html +2 -0
  388. package/examples/components/reference/selected/components/multi-select-picker.html +5 -0
  389. package/examples/components/reference/selected/components/pagination.html +3 -0
  390. package/examples/components/reference/selected/components/persistent-action-banner.html +4 -0
  391. package/examples/components/reference/selected/components/popconfirm.html +5 -0
  392. package/examples/components/reference/selected/components/popover-menu.html +3 -0
  393. package/examples/components/reference/selected/components/rich-text-toolbar.html +3 -0
  394. package/examples/components/reference/selected/components/save-status-indicator.html +2 -0
  395. package/examples/components/reference/selected/components/selectable-cards.html +3 -0
  396. package/examples/components/reference/selected/components/settings-rows.html +3 -0
  397. package/examples/components/reference/selected/components/sidebar-nav.html +4 -0
  398. package/examples/components/reference/selected/components/small-charts.html +5 -0
  399. package/examples/components/reference/selected/components/split-button.html +4 -0
  400. package/examples/components/reference/selected/components/split-panes.html +8 -0
  401. package/examples/components/reference/selected/components/stat-tiles.html +3 -0
  402. package/examples/components/reference/selected/components/toast-stack.html +5 -0
  403. package/examples/components/reference/selected/components/tree-view.html +4 -0
  404. package/examples/components/reference/selected/components/upload-dropzone.html +6 -0
  405. package/examples/components/reference/selected/components/wizard-shell.html +3 -0
  406. package/examples/components/reference/selected/corrections.css +11 -0
  407. package/examples/components/reference/selected/coverage.json +413 -0
  408. package/examples/components/reference/selected/gallery-build.mjs +49 -0
  409. package/examples/components/reference/selected/gallery-spec.json +12 -0
  410. package/examples/components/reference/selected/index.html +1 -0
  411. package/examples/components/reference/selected/kanban-comparison.json +6 -0
  412. package/examples/components/reference/selected/manifest.json +476 -0
  413. package/examples/components/reference/sha256.json +142 -0
  414. package/examples/components/reference/sources/diagonal-close.svg +1 -0
  415. package/examples/components/reference/sources/hyperclay/public-assets/css/hyperclay-app-source.css +614 -0
  416. package/examples/components/reference/sources/hyperclay/public-assets/js/app.js +94 -0
  417. package/examples/components/reference/sources/hyperclayjs/src/ui/theModal.js +897 -0
  418. package/examples/components/reference/sources/hypercms/scripts/build-theme.js +203 -0
  419. package/examples/components/reference/sources/hypercms/src/anchor.js +24 -0
  420. package/examples/components/reference/sources/hypercms/src/apply-loop.js +167 -0
  421. package/examples/components/reference/sources/hypercms/src/diagnostics.js +44 -0
  422. package/examples/components/reference/sources/hypercms/src/enhance.js +173 -0
  423. package/examples/components/reference/sources/hypercms/src/events.js +955 -0
  424. package/examples/components/reference/sources/hypercms/src/form-builder.js +518 -0
  425. package/examples/components/reference/sources/hypercms/src/form-rules.js +208 -0
  426. package/examples/components/reference/sources/hypercms/src/hooks.js +100 -0
  427. package/examples/components/reference/sources/hypercms/src/hypercms-bundle.js +10 -0
  428. package/examples/components/reference/sources/hypercms/src/hypercms.js +347 -0
  429. package/examples/components/reference/sources/hypercms/src/morph.js +10 -0
  430. package/examples/components/reference/sources/hypercms/src/path.js +61 -0
  431. package/examples/components/reference/sources/hypercms/src/place.js +131 -0
  432. package/examples/components/reference/sources/hypercms/src/platform.js +131 -0
  433. package/examples/components/reference/sources/hypercms/src/refresh.js +87 -0
  434. package/examples/components/reference/sources/hypercms/src/richclay-bridge.js +140 -0
  435. package/examples/components/reference/sources/hypercms/src/row-identity.js +111 -0
  436. package/examples/components/reference/sources/hypercms/src/scaffold.js +10 -0
  437. package/examples/components/reference/sources/hypercms/src/session.js +303 -0
  438. package/examples/components/reference/sources/hypercms/src/shell.js +248 -0
  439. package/examples/components/reference/sources/hypercms/src/styles.css +298 -0
  440. package/examples/components/reference/sources/hypercms/src/targets.js +144 -0
  441. package/examples/components/reference/sources/hypercms/src/templates.js +656 -0
  442. package/examples/components/reference/sources/hypercms/src/theme/pixel-quiet.overrides.css +761 -0
  443. package/examples/components/reference/sources/hypercms/src/theme.generated.css +1772 -0
  444. package/examples/components/reference/sources/hypercms/src/toggle.js +666 -0
  445. package/examples/components/reference/sources/hypercms/src/unresolved.js +211 -0
  446. package/examples/components/reference/sources/hypercms/src/vendor/mirk.vendor.js +212 -0
  447. package/examples/components/reference/sources/hypercms/src/views/inline-layer.js +421 -0
  448. package/examples/components/reference/sources/hypercms/src/views/inline.js +1072 -0
  449. package/examples/components/reference/sources/hypercms/src/views/sidebar.js +97 -0
  450. package/examples/components/reference/sources/modal-reference.html +301 -0
  451. package/examples/components/reference/sources/quickcrop/quickcrop.css +124 -0
  452. package/examples/components/reference/sources/quickcrop/quickcrop.js +400 -0
  453. package/examples/components/reference/sources/richclay/richclay.css +416 -0
  454. package/examples/components/reference/sources/richclay/richclay.js +2962 -0
  455. package/examples/components/reference/sources/richclay/src/a11y.js +67 -0
  456. package/examples/components/reference/sources/richclay/src/browser-global.js +7 -0
  457. package/examples/components/reference/sources/richclay/src/buttons.js +254 -0
  458. package/examples/components/reference/sources/richclay/src/hyperclay.js +470 -0
  459. package/examples/components/reference/sources/richclay/src/normalize.js +380 -0
  460. package/examples/components/reference/sources/richclay/src/richclay.js +1356 -0
  461. package/examples/components/reference/sources/richclay/src/sanitize.js +189 -0
  462. package/examples/components/reference/sources/richclay/src/styles.js +23 -0
  463. package/examples/components/reference/sources/richclay/src/toolbar-float.js +175 -0
  464. package/examples/components/reference/sources/richclay/src/toolbar.js +394 -0
  465. package/examples/components/reference/sources/richclay/src/vendor-bundle.js +15 -0
  466. package/examples/components/reference/sources/richclay/vendor/DOMPURIFY-LICENSE +202 -0
  467. package/examples/components/reference/sources/richclay/vendor/DOMPURIFY-LICENSE-MPL +373 -0
  468. package/examples/components/reference/sources/richclay/vendor/SQUIRE-LICENSE +21 -0
  469. package/examples/components/reference/sources/richclay/vendor/purify.es.mjs +2249 -0
  470. package/examples/components/reference/sources/richclay/vendor/purify.min.js +3 -0
  471. package/examples/components/reference/sources/richclay/vendor/squire.js +22 -0
  472. package/examples/components/reference/sources/richclay/vendor/squire.mjs +22 -0
  473. package/examples/components/reference/sources/richclay/vendor/squire.provenance.json +19 -0
  474. package/examples/components/rich-text-toolbar.html +43 -0
  475. package/examples/components/save-status-indicator.html +11 -0
  476. package/examples/components/selectable-cards.html +9 -0
  477. package/examples/components/settings-rows.html +10 -0
  478. package/examples/components/sidebar-nav.html +9 -0
  479. package/examples/components/small-charts.html +21 -0
  480. package/examples/components/split-button.html +13 -0
  481. package/examples/components/split-panes-editor.html +6 -0
  482. package/examples/components/split-panes.html +9 -0
  483. package/examples/components/stat-tiles.html +23 -0
  484. package/examples/components/toast-stack.html +21 -0
  485. package/examples/components/tree-view.html +9 -0
  486. package/examples/components/upload-dropzone.html +88 -0
  487. package/examples/components/wizard-shell.html +50 -0
  488. package/examples/datastar/index.html +38 -0
  489. package/examples/datastar/server.mjs +31 -0
  490. package/examples/fixtures/field-guide.pdf +14 -0
  491. package/examples/fixtures/workspace.jpg +0 -0
  492. package/examples/setup-peers.mjs +35 -0
  493. package/fonts/LICENSE-ibm-plex-mono.txt +93 -0
  494. package/fonts/LICENSE-ibm-plex-sans.txt +93 -0
  495. package/fonts/LICENSE-newsreader.txt +93 -0
  496. package/fonts/ibm-plex-mono-latin-400-normal.woff2 +0 -0
  497. package/fonts/ibm-plex-mono-latin-500-normal.woff2 +0 -0
  498. package/fonts/ibm-plex-mono-latin-600-normal.woff2 +0 -0
  499. package/fonts/ibm-plex-sans-latin-400-italic.woff2 +0 -0
  500. package/fonts/ibm-plex-sans-latin-400-normal.woff2 +0 -0
  501. package/fonts/ibm-plex-sans-latin-500-normal.woff2 +0 -0
  502. package/fonts/ibm-plex-sans-latin-600-normal.woff2 +0 -0
  503. package/fonts/newsreader-latin-opsz-italic.woff2 +0 -0
  504. package/fonts/newsreader-latin-opsz-normal.woff2 +0 -0
  505. package/icons/LICENSE +21 -0
  506. package/icons/house.json +71 -0
  507. package/icons/icons.d.ts +17 -0
  508. package/icons/icons.js +648 -0
  509. package/icons/icons.svg +126 -0
  510. package/icons/marks/build-tray.source.mjs +45 -0
  511. package/icons/marks/hyperclay-local.svg +11 -0
  512. package/icons/phosphor.json +53 -0
  513. package/icons/round.json +8 -0
  514. package/integrations/datastar.js +202 -0
  515. package/integrations/quickcrop.css +26 -0
  516. package/integrations/quickcrop.js +56 -0
  517. package/integrations/richclay.css +100 -0
  518. package/integrations/richclay.js +131 -0
  519. package/package.json +630 -0
  520. package/react/README.md +244 -0
  521. package/src/README.md +83 -0
  522. package/vendor/datastar/datastar-1.0.3.js +10 -0
  523. package/vendor/datastar/provenance.json +6 -0
  524. package/vendor/floating-ui/LICENSE-core +20 -0
  525. package/vendor/floating-ui/LICENSE-dom +20 -0
  526. package/vendor/floating-ui/floating-ui.core.umd.min.js +1 -0
  527. package/vendor/floating-ui/floating-ui.dom.umd.min.js +1 -0
  528. package/vendor/floating-ui/provenance.json +17 -0
  529. package/vendor/richclay/LICENSE +16 -0
  530. package/vendor/richclay/THIRD-PARTY-NOTICES.md +45 -0
  531. package/vendor/richclay/provenance.json +17 -0
  532. package/vendor/richclay/richclay.css +404 -0
  533. package/vendor/richclay/richclay.js +2940 -0
  534. package/vendor/richclay/vendor/DOMPURIFY-LICENSE +202 -0
  535. package/vendor/richclay/vendor/DOMPURIFY-LICENSE-MPL +373 -0
  536. package/vendor/richclay/vendor/SQUIRE-LICENSE +21 -0
  537. package/vendor/richclay/vendor/purify.min.js +3 -0
  538. package/vendor/richclay/vendor/squire.js +22 -0
  539. package/vendor/richclay/vendor/squire.provenance.json +30 -0
@@ -0,0 +1,1339 @@
1
+ /*
2
+ * bevel.css — the bevel UI kit, 0.1.0.
3
+ * Hand-written, no build. Beveled controls in an editorial page: IBM Plex Sans
4
+ * body, Newsreader headings, IBM Plex Mono for anything with a digit. Every
5
+ * component is a semantic BEM class in @layer components, so utilities and
6
+ * unlayered consumer rules always win with zero !important.
7
+ *
8
+ * Two hinges (inherited from mirk-interface):
9
+ * 1. Components live in @layer components → utilities win.
10
+ * 2. State serializes into the DOM (native attrs, :has(), inline --bevel-value)
11
+ * so document.documentElement.outerHTML round-trips every visible state.
12
+ *
13
+ * Fonts are declared by family name only; bevel-fonts.css loads the files.
14
+ * Without it the fallbacks are Georgia, system-ui and ui-monospace.
15
+ */
16
+ @layer base, components;
17
+
18
+ @layer base {
19
+ *, ::before, ::after { box-sizing: border-box; }
20
+ button, input, optgroup, select, textarea { margin: 0; font: inherit; color: inherit; }
21
+ html { -webkit-text-size-adjust: 100%; }
22
+
23
+ /* 27 colour tokens, one light-dark() each: cream by day, navy by night (mirk's
24
+ Pixel Quiet palette), plus the three that draw the bevel, the three that
25
+ draw a pressed-in control, the two that draw the switch knob and the four
26
+ that draw the danger button. Every in-between state on the page is a
27
+ color-mix() of two of these. */
28
+ :root {
29
+ color-scheme: light dark;
30
+
31
+ --bevel-ground: light-dark(#FDF8F0, #0B0C13);
32
+ --bevel-surface: light-dark(#FFFCF6, #11131E);
33
+ --bevel-sunk: light-dark(#F4ECDF, #1A1D2C);
34
+ --bevel-ink: light-dark(#2B241B, #ECEAF2);
35
+ --bevel-ink-2: light-dark(#4A4033, #C9CDE0);
36
+ --bevel-muted: light-dark(#6B5942, #8A90AB);
37
+ --bevel-faint: light-dark(#9A8A70, #6A7090);
38
+ --bevel-line: light-dark(#E8DCC6, #262B42);
39
+ --bevel-line-2: light-dark(#D8C8AF, #353B52);
40
+ --bevel-brass: light-dark(#8F6310, #D9A445);
41
+ --bevel-brass-soft: light-dark(#F0E4CC, #3A2F17);
42
+ --bevel-ox: light-dark(#A83A2C, #FF5566);
43
+ --bevel-ox-soft: light-dark(#F6DED6, #3A2226);
44
+ --bevel-teal: light-dark(#256056, #63AE9E);
45
+ --bevel-teal-soft: light-dark(#DCEBE7, #17332E);
46
+
47
+ /* The raised face is a material of its own, a step off the page in both
48
+ modes (bone on cream, slate on navy), so a resting control reads as a
49
+ closed shape on the ground and on a card. The shadow wall clears the
50
+ navy ground at night while staying darker than the raised face. */
51
+ --bevel-face: light-dark(#F1E7D4, #22273E);
52
+ --bevel-edge-hi: light-dark(#FFF9ED, #3C4260);
53
+ --bevel-edge-lo: light-dark(#D6C3A5, #1B2033);
54
+
55
+ /* A pressed-in control is a body, not a lip: a floor, the wall the light
56
+ misses (top, left) and the wall it reaches (bottom, right). In light all
57
+ three sit below the cream; in dark all three sit above the navy, so no
58
+ side of the perimeter can vanish into the ground. Literal stops, never a
59
+ mix: a mix between a navy face and a near-black edge lands on gray. */
60
+ --bevel-face-in: light-dark(#E3D0B3, #28304D);
61
+ --bevel-edge-in: light-dark(#B89F7B, #1F2339);
62
+ --bevel-edge-in-hi: light-dark(#F0E1C9, #4D587A);
63
+
64
+ /* The switch knob is lighter than its on channel in both modes, so an on
65
+ switch never reads as a hole. In light it sits a step above the face,
66
+ so it also clears its own channel. */
67
+ --bevel-knob: light-dark(#FCF8F1, #4A5275);
68
+ --bevel-knob-hi: light-dark(#FFF9ED, #6C759A);
69
+
70
+ /* The danger button is a solid block like the primary, so it carries its
71
+ own face, its own two edges and the cream that sits on it. A dark red
72
+ nearing brown, brighter by a step at night so it still reads as red on
73
+ navy. Literal stops: no neutral token is dark in both modes. */
74
+ --bevel-ox-face: light-dark(#7A2A1F, #842E22);
75
+ --bevel-ox-edge-hi: light-dark(#AE4F3E, #B85A47);
76
+ --bevel-ox-edge-lo: light-dark(#451510, #3E1410);
77
+ --bevel-ox-ink: light-dark(#FBEEE8, #FBEEE8);
78
+
79
+ --bevel-font-sans: "IBM Plex Sans", system-ui, -apple-system, sans-serif;
80
+ --bevel-font-serif: Newsreader, Georgia, "Times New Roman", serif;
81
+ --bevel-font-mono: "IBM Plex Mono", ui-monospace, Menlo, monospace;
82
+
83
+ --bevel-shadow: 0 1px 2px rgba(23, 28, 36, .05), 0 8px 24px -12px rgba(23, 28, 36, .14);
84
+
85
+ background: var(--bevel-ground);
86
+ color: var(--bevel-ink);
87
+ }
88
+
89
+ /* The one non-colour token, so it cannot ride light-dark(): a media default
90
+ for the OS, then explicit forced-mode overrides. */
91
+ @media (prefers-color-scheme: dark) {
92
+ :root { --bevel-shadow: 0 1px 2px rgba(0, 0, 0, .4), 0 10px 28px -14px rgba(0, 0, 0, .6); }
93
+ }
94
+ [data-theme="light"], .light {
95
+ color-scheme: light;
96
+ --bevel-shadow: 0 1px 2px rgba(23, 28, 36, .05), 0 8px 24px -12px rgba(23, 28, 36, .14);
97
+ background: var(--bevel-ground); color: var(--bevel-ink);
98
+ }
99
+ [data-theme="dark"], .dark {
100
+ color-scheme: dark;
101
+ --bevel-shadow: 0 1px 2px rgba(0, 0, 0, .4), 0 10px 28px -14px rgba(0, 0, 0, .6);
102
+ background: var(--bevel-ground); color: var(--bevel-ink);
103
+ }
104
+
105
+ body {
106
+ margin: 0;
107
+ font-family: var(--bevel-font-sans);
108
+ font-size: 17px; line-height: 1.6;
109
+ -webkit-font-smoothing: antialiased; text-rendering: optimizeLegibility;
110
+ font-variant-numeric: tabular-nums;
111
+ accent-color: var(--bevel-brass);
112
+ }
113
+ ::selection { background: var(--bevel-brass-soft); color: var(--bevel-ink); }
114
+ :focus-visible { outline: 2px solid var(--bevel-brass); outline-offset: 2px; }
115
+ }
116
+
117
+ @layer components {
118
+ /* Visually hidden, still focusable and announced. The hidden native input
119
+ behind every drawn control relies on it. */
120
+ .bevel-sr-only {
121
+ position: absolute; width: 1px; height: 1px;
122
+ padding: 0; margin: -1px; overflow: hidden;
123
+ clip: rect(0, 0, 0, 0); white-space: nowrap; border-width: 0;
124
+ }
125
+
126
+ /* ============================ BUTTON ============================ */
127
+ /* The raised bevel: light top+left, dark right+bottom, real borders so the
128
+ corners mitre. Press it and the edges swap and the label sinks 1px. */
129
+ .bevel-button {
130
+ display: inline-flex; align-items: center; justify-content: center; gap: .5rem;
131
+ font-family: var(--bevel-font-sans); font-size: 17px; font-weight: 500; line-height: 1.5;
132
+ cursor: pointer; user-select: none; text-align: center; text-decoration: none;
133
+ color: var(--bevel-ink);
134
+ background: var(--bevel-face);
135
+ border: 2px solid;
136
+ border-color: var(--bevel-edge-hi) var(--bevel-edge-lo) var(--bevel-edge-lo) var(--bevel-edge-hi);
137
+ border-radius: 0;
138
+ padding: 6px 15px;
139
+ outline: none;
140
+ }
141
+ .bevel-button__label { white-space: nowrap; user-select: none; display: inline-block; }
142
+ .bevel-button:hover { background: color-mix(in srgb, var(--bevel-face), var(--bevel-edge-hi) 45%); }
143
+ .bevel-button:active {
144
+ border-color: var(--bevel-edge-lo) var(--bevel-edge-hi) var(--bevel-edge-hi) var(--bevel-edge-lo);
145
+ }
146
+ .bevel-button:active .bevel-button__label { translate: 1px 1px; }
147
+ .bevel-button:focus-visible,
148
+ .bevel-button:has(:focus-visible) { outline: 2px solid var(--bevel-brass); outline-offset: 2px; }
149
+ .bevel-button:disabled, .bevel-button[aria-disabled="true"] { opacity: .5; cursor: not-allowed; }
150
+ .bevel-button:disabled .bevel-button__label { translate: none; }
151
+
152
+ .bevel-button--small { font-size: 14px; padding: 3px 11px; }
153
+
154
+ /* Primary: ink acts. The bevel is derived from the ink so it embosses in
155
+ both modes. Exactly one per view. */
156
+ .bevel-button--primary {
157
+ --bevel-face: var(--bevel-ink);
158
+ --bevel-edge-hi: color-mix(in srgb, var(--bevel-ink), white 24%);
159
+ --bevel-edge-lo: color-mix(in srgb, var(--bevel-ink), black 32%);
160
+ color: var(--bevel-ground);
161
+ }
162
+ .bevel-button--primary:hover { background: color-mix(in srgb, var(--bevel-ink), var(--bevel-ground) 12%); }
163
+
164
+ /* Danger: ox destroys. A solid dark-red block with its own three stops, so
165
+ the base rules for hover and press work unchanged on it. */
166
+ .bevel-button--danger {
167
+ --bevel-face: var(--bevel-ox-face);
168
+ --bevel-edge-hi: var(--bevel-ox-edge-hi);
169
+ --bevel-edge-lo: var(--bevel-ox-edge-lo);
170
+ color: var(--bevel-ox-ink);
171
+ }
172
+
173
+ /* Quiet: a link wearing padding. Transparent border keeps the hit area and
174
+ the baseline aligned with neighbouring bevel buttons. */
175
+ .bevel-button--quiet {
176
+ background: none; border-color: transparent; color: var(--bevel-brass);
177
+ }
178
+ .bevel-button--quiet:hover { background: var(--bevel-sunk); color: color-mix(in srgb, var(--bevel-brass) 80%, var(--bevel-ink)); }
179
+ .bevel-button--quiet:active { border-color: transparent; }
180
+
181
+ /* ============================ TEXT INPUT ============================ */
182
+ /* Flat and recessed: a hairline on the surface. Typed text is sans because
183
+ most of it is language; --mono for a figure, a hex, an id. */
184
+ .bevel-input {
185
+ width: 100%; display: block;
186
+ font-family: var(--bevel-font-sans); font-size: 17px; line-height: 1.5;
187
+ color: var(--bevel-ink); background: var(--bevel-surface);
188
+ border: 1px solid var(--bevel-line-2); border-radius: 0;
189
+ padding: 7px 12px; outline: none;
190
+ transition: border-color .14s, background-color .14s;
191
+ }
192
+ .bevel-input::placeholder { color: var(--bevel-faint); }
193
+ .bevel-input:hover:not(:disabled) { border-color: var(--bevel-faint); }
194
+ .bevel-input:focus-visible { outline: 2px solid var(--bevel-brass); outline-offset: 1px; border-color: var(--bevel-brass); }
195
+ .bevel-input:disabled { background: var(--bevel-sunk); color: var(--bevel-faint); border-color: var(--bevel-line); cursor: not-allowed; }
196
+ .bevel-input--mono { font-family: var(--bevel-font-mono); font-size: 15px; }
197
+ .bevel-input--small { font-size: 14px; padding: 4px 10px; }
198
+ input[type="search"].bevel-input { -webkit-appearance: none; appearance: none; }
199
+ input[type="search"].bevel-input::-webkit-search-cancel-button { -webkit-appearance: none; }
200
+
201
+ /* ============================ TEXTAREA ============================ */
202
+ .bevel-textarea {
203
+ width: 100%; display: block; min-height: 104px; resize: vertical;
204
+ font-family: var(--bevel-font-sans); font-size: 17px; line-height: 1.55;
205
+ color: var(--bevel-ink); background: var(--bevel-surface);
206
+ border: 1px solid var(--bevel-line-2); border-radius: 0;
207
+ padding: 8px 12px; outline: none;
208
+ transition: border-color .14s, background-color .14s;
209
+ }
210
+ .bevel-textarea::placeholder { color: var(--bevel-faint); }
211
+ .bevel-textarea:hover:not(:disabled) { border-color: var(--bevel-faint); }
212
+ .bevel-textarea:focus-visible { outline: 2px solid var(--bevel-brass); outline-offset: 1px; border-color: var(--bevel-brass); }
213
+ .bevel-textarea:disabled { background: var(--bevel-sunk); color: var(--bevel-faint); border-color: var(--bevel-line); cursor: not-allowed; }
214
+ .bevel-textarea--small { font-size: 14px; padding: 5px 10px; min-height: 80px; }
215
+
216
+ /* ============================ NUMBER ============================ */
217
+ /* A flat field with two beveled steps stacked at its right edge. */
218
+ .bevel-number {
219
+ display: flex; align-items: stretch; width: 100%;
220
+ background: var(--bevel-surface);
221
+ border: 1px solid var(--bevel-line-2); border-radius: 0;
222
+ transition: border-color .14s;
223
+ }
224
+ .bevel-number:hover { border-color: var(--bevel-faint); }
225
+ .bevel-number:has(:focus-visible) { outline: 2px solid var(--bevel-brass); outline-offset: 1px; border-color: var(--bevel-brass); }
226
+ .bevel-number__input {
227
+ flex: 1; min-width: 0; background: transparent; color: var(--bevel-ink);
228
+ font-family: var(--bevel-font-mono); font-size: 15px; line-height: 1.5;
229
+ padding: 7px 10px 7px 12px; border: 0; outline: none;
230
+ appearance: textfield; -webkit-appearance: textfield;
231
+ }
232
+ .bevel-number__input::-webkit-outer-spin-button,
233
+ .bevel-number__input::-webkit-inner-spin-button { -webkit-appearance: none; appearance: none; }
234
+ .bevel-number__steps { display: flex; flex-direction: column; padding: 2px; gap: 2px; }
235
+ .bevel-number__step {
236
+ flex: 1; position: relative; width: 26px; cursor: pointer; padding: 0; line-height: 0;
237
+ background: var(--bevel-face); outline: none; color: var(--bevel-ink-2);
238
+ border: 2px solid;
239
+ border-color: var(--bevel-edge-hi) var(--bevel-edge-lo) var(--bevel-edge-lo) var(--bevel-edge-hi);
240
+ border-radius: 0; font-size: 0;
241
+ }
242
+ /* The step glyph is a hairline chevron drawn from two borders. */
243
+ .bevel-number__step::before {
244
+ content: ""; position: absolute; left: 50%; top: 50%; width: 6px; height: 6px;
245
+ border-right: 1.5px solid currentColor; border-bottom: 1.5px solid currentColor;
246
+ }
247
+ .bevel-number__step[data-step="up"]::before { transform: translate(-50%, -25%) rotate(-135deg); }
248
+ .bevel-number__step[data-step="down"]::before { transform: translate(-50%, -75%) rotate(45deg); }
249
+ .bevel-number__step:hover { background: color-mix(in srgb, var(--bevel-face), var(--bevel-edge-hi) 45%); color: var(--bevel-ink); }
250
+ .bevel-number__step:active {
251
+ border-color: var(--bevel-edge-lo) var(--bevel-edge-hi) var(--bevel-edge-hi) var(--bevel-edge-lo);
252
+ }
253
+ .bevel-number__step:focus-visible { outline: 2px solid var(--bevel-brass); outline-offset: 1px; }
254
+ .bevel-number--small .bevel-number__input { font-size: 13px; padding: 4px 8px 4px 10px; }
255
+ .bevel-number--small .bevel-number__step { width: 22px; }
256
+
257
+ /* ============================ SELECT ============================ */
258
+ /* Native <select>, OS arrow hidden, a hairline chevron drawn on the wrapper
259
+ and kept out of the click path. */
260
+ .bevel-select { position: relative; display: block; }
261
+ .bevel-select__field {
262
+ width: 100%; appearance: none; -webkit-appearance: none; cursor: pointer;
263
+ font-family: var(--bevel-font-sans); font-size: 17px; line-height: 1.5;
264
+ color: var(--bevel-ink); background: var(--bevel-surface);
265
+ border: 1px solid var(--bevel-line-2); border-radius: 0;
266
+ padding: 7px 36px 7px 12px; outline: none;
267
+ transition: border-color .14s;
268
+ }
269
+ .bevel-select__field:hover:not(:disabled) { border-color: var(--bevel-faint); }
270
+ .bevel-select__field:focus-visible { outline: 2px solid var(--bevel-brass); outline-offset: 1px; border-color: var(--bevel-brass); }
271
+ .bevel-select__field:disabled { background: var(--bevel-sunk); color: var(--bevel-faint); cursor: not-allowed; }
272
+ .bevel-select::after {
273
+ content: ""; position: absolute; right: 14px; top: 50%; width: 7px; height: 7px;
274
+ border-right: 1.5px solid var(--bevel-muted); border-bottom: 1.5px solid var(--bevel-muted);
275
+ transform: translateY(-65%) rotate(45deg); pointer-events: none;
276
+ }
277
+ .bevel-select--small .bevel-select__field { font-size: 14px; padding: 4px 30px 4px 10px; }
278
+ .bevel-select--small::after { right: 11px; width: 6px; height: 6px; }
279
+
280
+ /* ============================ CHECKBOX ============================ */
281
+ /* Hidden native input, a beveled box, a mark drawn from two borders.
282
+ Checked is the PROVISIONAL shallow recess (DECISIONS 0001): the edges swap
283
+ but the dark one sits at half depth and the face keeps its colour. */
284
+ .bevel-checkbox {
285
+ display: inline-flex; align-items: flex-start; gap: 10px; cursor: pointer; width: fit-content;
286
+ position: relative; font-size: 17px; line-height: 1.5; user-select: none;
287
+ }
288
+ .bevel-checkbox__box {
289
+ position: relative; flex-shrink: 0; width: 20px; height: 20px; margin-top: 3px;
290
+ background: var(--bevel-face); border-radius: 0;
291
+ border: 2px solid;
292
+ border-color: var(--bevel-edge-hi) var(--bevel-edge-lo) var(--bevel-edge-lo) var(--bevel-edge-hi);
293
+ }
294
+ .bevel-checkbox__box::after {
295
+ content: ""; position: absolute; left: 5px; top: 1px; width: 5px; height: 10px;
296
+ border-right: 2px solid var(--bevel-ink); border-bottom: 2px solid var(--bevel-ink);
297
+ transform: rotate(42deg); opacity: 0;
298
+ }
299
+ .bevel-checkbox__label { color: var(--bevel-ink); }
300
+ .bevel-checkbox:hover .bevel-checkbox__box { background: color-mix(in srgb, var(--bevel-face), var(--bevel-edge-hi) 45%); }
301
+ .bevel-checkbox:has(:checked) .bevel-checkbox__box {
302
+ background: var(--bevel-face-in);
303
+ border-color: var(--bevel-edge-in) var(--bevel-edge-in-hi) var(--bevel-edge-in-hi) var(--bevel-edge-in);
304
+ }
305
+ .bevel-checkbox:has(:checked) .bevel-checkbox__box::after { opacity: 1; translate: 1px 1px; }
306
+ .bevel-checkbox:has(:focus-visible) .bevel-checkbox__box { outline: 2px solid var(--bevel-brass); outline-offset: 2px; }
307
+ .bevel-checkbox:has(:disabled) { color: var(--bevel-faint); cursor: not-allowed; }
308
+ .bevel-checkbox:has(:disabled) .bevel-checkbox__box { opacity: .5; }
309
+ .bevel-checkbox--small { font-size: 14px; gap: 8px; }
310
+ .bevel-checkbox--small .bevel-checkbox__box { width: 16px; height: 16px; margin-top: 2px; }
311
+ .bevel-checkbox--small .bevel-checkbox__box::after { left: 3.5px; top: 0; width: 4px; height: 8px; border-width: 1.5px; }
312
+ /* Mixed (the JS indeterminate flag, which a grid's select-all derives from
313
+ its rows): the same recess, the mark a sunk dash instead of a tick. */
314
+ .bevel-checkbox:has(:indeterminate) .bevel-checkbox__box {
315
+ background: var(--bevel-face-in);
316
+ border-color: var(--bevel-edge-in) var(--bevel-edge-in-hi) var(--bevel-edge-in-hi) var(--bevel-edge-in);
317
+ }
318
+ .bevel-checkbox:has(:indeterminate) .bevel-checkbox__box::after {
319
+ opacity: 1; transform: none; translate: 1px 1px;
320
+ left: 4px; top: 7px; width: 8px; height: 0; border-right: 0;
321
+ }
322
+ .bevel-checkbox--small:has(:indeterminate) .bevel-checkbox__box::after { left: 3px; top: 5px; width: 6px; }
323
+
324
+ /* ============================ RADIO ============================ */
325
+ /* Round, so the two edge colours come as inset shadows: a lit rim on a
326
+ circle. Checked is the recess body with only its shadow wall: on a circle
327
+ the lit lower lip read as a highlight, not an edge, so it is left off.
328
+ The dot does not sink: with one wall the well is already off centre, and
329
+ a 1px sink on top of it read as a misplaced dot. It is centred in the
330
+ ring, wall included. */
331
+ .bevel-radio {
332
+ display: inline-flex; align-items: flex-start; gap: 10px; cursor: pointer; width: fit-content;
333
+ position: relative; font-size: 17px; line-height: 1.5; user-select: none;
334
+ }
335
+ .bevel-radio__ring {
336
+ position: relative; flex-shrink: 0; width: 22px; height: 22px; margin-top: 2px;
337
+ border-radius: 50%; background: var(--bevel-face);
338
+ box-shadow: inset 2px 2px 0 var(--bevel-edge-hi), inset -2px -2px 0 var(--bevel-edge-lo);
339
+ }
340
+ .bevel-radio__ring::after {
341
+ content: ""; position: absolute; inset: 7px; border-radius: 50%;
342
+ background: var(--bevel-ink); opacity: 0;
343
+ }
344
+ .bevel-radio__label { color: var(--bevel-ink); }
345
+ .bevel-radio:hover .bevel-radio__ring { background: color-mix(in srgb, var(--bevel-face), var(--bevel-edge-hi) 45%); }
346
+ .bevel-radio:has(:checked) .bevel-radio__ring {
347
+ background: var(--bevel-face-in);
348
+ box-shadow: inset 2px 2px 0 var(--bevel-edge-in);
349
+ }
350
+ .bevel-radio:has(:checked) .bevel-radio__ring::after { opacity: 1; }
351
+ .bevel-radio:has(:focus-visible) .bevel-radio__ring { outline: 2px solid var(--bevel-brass); outline-offset: 2px; }
352
+ .bevel-radio:has(:disabled) { color: var(--bevel-faint); cursor: not-allowed; }
353
+ .bevel-radio:has(:disabled) .bevel-radio__ring { opacity: .5; }
354
+ .bevel-radio--small { font-size: 14px; gap: 8px; }
355
+ .bevel-radio--small .bevel-radio__ring { width: 18px; height: 18px; margin-top: 1px; }
356
+ .bevel-radio--small .bevel-radio__ring::after { inset: 6px; }
357
+
358
+ /* ============================ TOGGLE ============================ */
359
+ /* A recessed channel and a beveled thumb. On is a lighter track, never an
360
+ accent. Switches are for settings that apply immediately. The thumb has
361
+ its own two tokens so it stays lighter than the on channel in dark. */
362
+ .bevel-toggle {
363
+ display: inline-flex; align-items: center; gap: 10px; cursor: pointer; width: fit-content;
364
+ position: relative; font-size: 17px; line-height: 1.5; user-select: none;
365
+ }
366
+ .bevel-toggle__track {
367
+ position: relative; flex-shrink: 0; width: 44px; height: 24px; border-radius: 0;
368
+ background: var(--bevel-sunk); border: 1px solid var(--bevel-line-2);
369
+ transition: background-color .14s, border-color .14s;
370
+ }
371
+ .bevel-toggle__thumb {
372
+ position: absolute; top: 2px; left: 2px; width: 18px; height: 18px;
373
+ background: var(--bevel-knob);
374
+ border: 2px solid;
375
+ border-color: var(--bevel-knob-hi) var(--bevel-edge-lo) var(--bevel-edge-lo) var(--bevel-knob-hi);
376
+ transition: translate .15s cubic-bezier(.4, 0, .2, 1);
377
+ }
378
+ .bevel-toggle__label { color: var(--bevel-ink); }
379
+ .bevel-toggle:hover .bevel-toggle__track { border-color: var(--bevel-faint); }
380
+ .bevel-toggle:has(:checked) .bevel-toggle__track { background: var(--bevel-line-2); border-color: var(--bevel-faint); }
381
+ .bevel-toggle:has(:checked) .bevel-toggle__thumb { translate: 20px 0; }
382
+ .bevel-toggle:has(:focus-visible) .bevel-toggle__track { outline: 2px solid var(--bevel-brass); outline-offset: 2px; }
383
+ .bevel-toggle:has(:disabled) { color: var(--bevel-faint); cursor: not-allowed; }
384
+ .bevel-toggle:has(:disabled) .bevel-toggle__track { opacity: .5; }
385
+ .bevel-toggle--small { font-size: 14px; gap: 8px; }
386
+ .bevel-toggle--small .bevel-toggle__track { width: 38px; height: 20px; }
387
+ .bevel-toggle--small .bevel-toggle__thumb { width: 14px; height: 14px; }
388
+ .bevel-toggle--small:has(:checked) .bevel-toggle__thumb { translate: 18px 0; }
389
+
390
+ /* ============================ SLIDER ============================ */
391
+ /* Hidden native range over a drawn track, fill and nub. The wrapper's
392
+ inline --bevel-value matches value= so the fill is right before any script. */
393
+ .bevel-slider { position: relative; height: 32px; width: 100%; --bevel-value: 0%; }
394
+ .bevel-slider__input {
395
+ position: absolute; inset: 0; width: 100%; height: 100%; margin: 0;
396
+ opacity: 0; cursor: pointer; z-index: 10;
397
+ }
398
+ .bevel-slider__track {
399
+ position: absolute; left: 0; right: 0; top: 50%; translate: 0 -50%; height: 8px;
400
+ background: var(--bevel-sunk); border: 1px solid var(--bevel-line-2); overflow: hidden;
401
+ }
402
+ .bevel-slider__fill { height: 100%; width: var(--bevel-value); background: var(--bevel-line-2); }
403
+ .bevel-slider__nub {
404
+ position: absolute; top: 50%; left: var(--bevel-value); translate: -50% -50%;
405
+ width: 20px; height: 20px; pointer-events: none;
406
+ background: var(--bevel-face);
407
+ border: 2px solid;
408
+ border-color: var(--bevel-edge-hi) var(--bevel-edge-lo) var(--bevel-edge-lo) var(--bevel-edge-hi);
409
+ }
410
+ .bevel-slider__input:active ~ .bevel-slider__nub {
411
+ border-color: var(--bevel-edge-lo) var(--bevel-edge-hi) var(--bevel-edge-hi) var(--bevel-edge-lo);
412
+ }
413
+ .bevel-slider__input:focus-visible ~ .bevel-slider__nub { outline: 2px solid var(--bevel-brass); outline-offset: 2px; }
414
+ .bevel-slider__input:disabled { cursor: not-allowed; }
415
+ .bevel-slider__input:disabled ~ .bevel-slider__nub { opacity: .5; }
416
+ .bevel-slider--small { height: 24px; }
417
+ .bevel-slider--small .bevel-slider__track { height: 6px; }
418
+ .bevel-slider--small .bevel-slider__nub { width: 16px; height: 16px; }
419
+ /* A slider beside its readout: <output> in mono, kept honest by bevel.js. */
420
+ .bevel-sliderrow { display: flex; align-items: center; gap: 14px; }
421
+ .bevel-sliderrow .bevel-slider { flex: 1; }
422
+ .bevel-sliderrow__value {
423
+ font-family: var(--bevel-font-mono); font-size: 13.5px; font-weight: 600;
424
+ min-width: 44px; text-align: right; color: var(--bevel-ink);
425
+ }
426
+
427
+ /* ============================ DATE ============================ */
428
+ .bevel-date { position: relative; display: block; }
429
+ .bevel-date__field {
430
+ width: 100%;
431
+ font-family: var(--bevel-font-mono); font-size: 15px; line-height: 1.5;
432
+ color: var(--bevel-ink); background: var(--bevel-surface);
433
+ border: 1px solid var(--bevel-line-2); border-radius: 0;
434
+ padding: 7px 44px 7px 12px; outline: none;
435
+ transition: border-color .14s;
436
+ }
437
+ .bevel-date__field:hover:not(:disabled) { border-color: var(--bevel-faint); }
438
+ .bevel-date__field:focus-visible { outline: 2px solid var(--bevel-brass); outline-offset: 1px; border-color: var(--bevel-brass); }
439
+ .bevel-date__field:disabled { background: var(--bevel-sunk); color: var(--bevel-faint); cursor: not-allowed; }
440
+ .bevel-date__field::-webkit-calendar-picker-indicator {
441
+ opacity: 0; position: absolute; right: 0; top: 0; bottom: 0; width: 44px; margin: 0; cursor: pointer;
442
+ }
443
+ .bevel-date__field::-webkit-inner-spin-button,
444
+ .bevel-date__field::-webkit-clear-button { -webkit-appearance: none; appearance: none; }
445
+ .bevel-date__icon {
446
+ pointer-events: none; position: absolute; right: 13px; top: 50%; translate: 0 -50%;
447
+ width: 18px; height: 18px; color: var(--bevel-muted); line-height: 0;
448
+ }
449
+ .bevel-date__icon svg { width: 100%; height: 100%; display: block; }
450
+ .bevel-date--small .bevel-date__field { font-size: 13px; padding: 4px 36px 4px 10px; }
451
+ .bevel-date--small .bevel-date__field::-webkit-calendar-picker-indicator { width: 36px; }
452
+ .bevel-date--small .bevel-date__icon { right: 10px; width: 16px; height: 16px; }
453
+
454
+ /* The native file and image inputs are visually hidden; their styled label
455
+ drives them, and the focus ring rides :has(:focus-visible) on the button. */
456
+ .bevel-file__input, .bevel-image__input {
457
+ position: absolute; width: 1px; height: 1px;
458
+ padding: 0; margin: -1px; overflow: hidden;
459
+ clip: rect(0, 0, 0, 0); white-space: nowrap; border-width: 0;
460
+ }
461
+
462
+ /* ============================ FILE ============================ */
463
+ .bevel-file { display: flex; align-items: center; gap: 12px; width: 100%; }
464
+ .bevel-file__name {
465
+ font-family: var(--bevel-font-mono); font-size: 14px; line-height: 1.5;
466
+ color: var(--bevel-muted);
467
+ min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
468
+ }
469
+ .bevel-file__name[data-filled] { color: var(--bevel-ink); }
470
+ a.bevel-file__name { text-decoration: underline; text-underline-offset: 2px; }
471
+ .bevel-file--compact {
472
+ padding: 4px 8px 4px 4px; background: var(--bevel-surface);
473
+ border: 1px solid var(--bevel-line-2); border-radius: 0;
474
+ }
475
+ .bevel-file--compact:has(:focus-visible) { outline: 2px solid var(--bevel-brass); outline-offset: 1px; }
476
+ .bevel-file--compact .bevel-button:focus-visible,
477
+ .bevel-file--compact .bevel-button:has(:focus-visible) { outline: none; }
478
+ .bevel-file__remove {
479
+ appearance: none; -webkit-appearance: none; flex-shrink: 0;
480
+ width: 18px; height: 18px; border-radius: 50%;
481
+ display: inline-flex; align-items: center; justify-content: center;
482
+ margin: 0; padding: 0; cursor: pointer; line-height: 0;
483
+ color: var(--bevel-ink); background: var(--bevel-face);
484
+ box-shadow: inset 1px 1px 0 var(--bevel-edge-hi), inset -1px -1px 0 var(--bevel-edge-lo);
485
+ border: 0;
486
+ }
487
+ .bevel-file__remove svg { display: block; width: 60%; height: 60%; }
488
+ .bevel-file__remove:hover { color: var(--bevel-ox); }
489
+ .bevel-file--small { gap: 8px; }
490
+ .bevel-file--small .bevel-file__name { font-size: 12.5px; }
491
+
492
+ /* ============================ IMAGE ============================ */
493
+ .bevel-image { display: flex; flex-direction: column; gap: 8px; }
494
+ .bevel-image__frame {
495
+ position: relative; width: 120px; height: 120px; overflow: hidden; border-radius: 0;
496
+ display: flex; align-items: center; justify-content: center;
497
+ background: var(--bevel-sunk); border: 1px solid var(--bevel-line-2);
498
+ color: var(--bevel-faint); font-size: 13.5px; line-height: 1.5;
499
+ }
500
+ .bevel-image__preview { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
501
+ .bevel-image__placeholder { padding: 0 8px; text-align: center; }
502
+ .bevel-image .bevel-button { width: fit-content; }
503
+ .bevel-image--compact { flex-direction: row; align-items: center; gap: 0; }
504
+ .bevel-image__thumb { position: relative; display: inline-block; width: fit-content; margin: 0; line-height: 0; }
505
+ .bevel-image--compact .bevel-image__frame { width: 56px; height: 56px; }
506
+ .bevel-image--compact .bevel-image__preview { position: static; inset: auto; display: block; }
507
+ .bevel-image__remove {
508
+ position: absolute; top: -7px; right: -7px;
509
+ width: 18px; height: 18px; border-radius: 50%; padding: 0; border: 0;
510
+ display: inline-flex; align-items: center; justify-content: center;
511
+ appearance: none; -webkit-appearance: none; cursor: pointer; line-height: 0;
512
+ color: var(--bevel-ink); background: var(--bevel-face);
513
+ box-shadow: inset 1px 1px 0 var(--bevel-edge-hi), inset -1px -1px 0 var(--bevel-edge-lo);
514
+ }
515
+ .bevel-image__remove svg { display: block; width: 10px; height: 10px; }
516
+ .bevel-image__remove:hover { color: var(--bevel-ox); }
517
+
518
+ /* ============================ TAGS ============================ */
519
+ /* A flat field holding beveled chips. Chips are real DOM with a hidden
520
+ input each, so the tag set round-trips. */
521
+ .bevel-tags {
522
+ display: flex; flex-wrap: wrap; align-items: center; gap: 6px; padding: 6px 8px;
523
+ background: var(--bevel-surface); border: 1px solid var(--bevel-line-2);
524
+ border-radius: 0; cursor: text; transition: border-color .14s;
525
+ }
526
+ .bevel-tags:hover { border-color: var(--bevel-faint); }
527
+ .bevel-tags:has(:focus-visible) { outline: 2px solid var(--bevel-brass); outline-offset: 1px; border-color: var(--bevel-brass); }
528
+ .bevel-tags__chip {
529
+ display: inline-flex; align-items: center; gap: 6px;
530
+ padding: 1px 6px 1px 9px; font-size: 14px; line-height: 1.5; font-weight: 500;
531
+ color: var(--bevel-ink); background: var(--bevel-face);
532
+ border: 2px solid;
533
+ border-color: var(--bevel-edge-hi) var(--bevel-edge-lo) var(--bevel-edge-lo) var(--bevel-edge-hi);
534
+ }
535
+ .bevel-tags__remove {
536
+ appearance: none; -webkit-appearance: none;
537
+ margin: 0; padding: 0 2px; border: 0; background: none; color: var(--bevel-muted);
538
+ cursor: pointer; font-size: 15px; line-height: 1;
539
+ }
540
+ .bevel-tags__remove:hover { color: var(--bevel-ox); }
541
+ .bevel-tags__input {
542
+ appearance: none; -webkit-appearance: none; border: 0; padding: 4px 4px;
543
+ flex: 1; min-width: 120px; background: transparent; color: var(--bevel-ink);
544
+ outline: none; font-size: 17px; line-height: 1.5;
545
+ }
546
+ .bevel-tags__input::placeholder { color: var(--bevel-faint); }
547
+ .bevel-tags--small { gap: 4px; padding: 4px 6px; }
548
+ .bevel-tags--small .bevel-tags__chip { font-size: 12.5px; padding: 0 5px 0 8px; }
549
+ .bevel-tags--small .bevel-tags__input { font-size: 14px; min-width: 90px; padding: 2px 4px; }
550
+
551
+ /* ============================ SORTABLE ============================ */
552
+ .bevel-sortable { display: flex; flex-direction: column; gap: 8px; }
553
+ .bevel-sortable__item {
554
+ display: flex; flex-direction: row; width: 100%;
555
+ background: var(--bevel-surface); border: 1px solid var(--bevel-line-2);
556
+ }
557
+ .bevel-sortable__grip {
558
+ width: 28px; flex-shrink: 0; display: flex; align-items: center; justify-content: center;
559
+ cursor: grab; touch-action: none; border-right: 1px solid var(--bevel-line-2); background: var(--bevel-sunk);
560
+ }
561
+ .bevel-sortable__grip:active { cursor: grabbing; }
562
+ .bevel-sortable__item.is-dragging { position: relative; z-index: 1; border-color: var(--bevel-faint); box-shadow: var(--bevel-shadow); }
563
+ .bevel-sortable__dots { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 3px; }
564
+ .bevel-sortable__dot {
565
+ display: block; width: 4px; height: 4px; background: var(--bevel-line-2);
566
+ box-shadow: 1px 1px 0 0 var(--bevel-edge-lo);
567
+ }
568
+ .bevel-sortable__body { display: flex; flex-direction: column; flex: 1; min-width: 0; }
569
+ .bevel-sortable__row { padding: 8px 14px 9px; }
570
+ .bevel-sortable__row:not(:last-child) { border-bottom: 1px solid var(--bevel-line); }
571
+ .bevel-sortable__label {
572
+ display: block; margin-bottom: 2px;
573
+ font-family: var(--bevel-font-mono); font-size: 10.5px; font-weight: 500;
574
+ letter-spacing: .13em; text-transform: uppercase; color: var(--bevel-muted);
575
+ }
576
+ .bevel-sortable__field {
577
+ width: 100%; background: transparent; color: var(--bevel-ink); border: 0; padding: 0;
578
+ font-family: var(--bevel-font-sans); font-size: 17px; line-height: 1.5; outline: none;
579
+ }
580
+ .bevel-sortable__field::placeholder { color: var(--bevel-faint); }
581
+ .bevel-sortable__field:focus-visible { outline: 2px solid var(--bevel-brass); outline-offset: 3px; }
582
+ .bevel-sortable--small { gap: 6px; }
583
+ .bevel-sortable--small .bevel-sortable__grip { width: 24px; }
584
+ .bevel-sortable--small .bevel-sortable__row { padding: 5px 11px 6px; }
585
+ .bevel-sortable--small .bevel-sortable__label { font-size: 10px; margin-bottom: 1px; }
586
+ .bevel-sortable--small .bevel-sortable__field { font-size: 14px; }
587
+
588
+ /* ============================ CHIP ============================ */
589
+ /* A collapsible recovery prompt: a small bevel button that expands into the
590
+ kit's one raised panel. State lives in classes so it round-trips. In a
591
+ Hyperclay app, mark the block save-remove. */
592
+ .bevel-chip { display: inline-flex; flex-direction: column; align-items: flex-start; }
593
+ .bevel-chip__panel { display: none; }
594
+ .bevel-chip--open .bevel-chip__trigger { display: none; }
595
+ .bevel-chip--open .bevel-chip__panel { display: flex; }
596
+ .bevel-chip__trigger .bevel-button__label { display: inline-flex; align-items: center; gap: 6px; }
597
+ .bevel-chip__trigger { box-shadow: var(--bevel-shadow); }
598
+ .bevel-chip__warn { color: var(--bevel-ox); fill: currentColor; }
599
+ .bevel-chip__trigger .bevel-chip__warn { vertical-align: -2px; }
600
+ .bevel-chip__panel {
601
+ width: 320px; max-width: calc(100vw - 44px);
602
+ background: var(--bevel-surface); color: var(--bevel-ink);
603
+ border: 1px solid var(--bevel-line-2); border-radius: 0;
604
+ box-shadow: var(--bevel-shadow);
605
+ padding: 14px 16px 14px; flex-direction: column; gap: 12px;
606
+ }
607
+ .bevel-chip__head { display: flex; gap: 10px; align-items: flex-start; }
608
+ .bevel-chip__icon { flex-shrink: 0; line-height: 0; margin-top: 1px; }
609
+ .bevel-chip__headtext { min-width: 0; }
610
+ .bevel-chip__eyebrow {
611
+ font-family: var(--bevel-font-mono); font-size: 10.5px; font-weight: 500;
612
+ text-transform: uppercase; letter-spacing: .14em; color: var(--bevel-muted); margin-bottom: 3px;
613
+ }
614
+ .bevel-chip__title { margin: 0; font-family: var(--bevel-font-sans); font-size: 15px; font-weight: 600; line-height: 1.3; color: var(--bevel-ink); }
615
+ .bevel-chip__collapse {
616
+ margin-left: auto; flex-shrink: 0; width: 24px; height: 24px;
617
+ display: inline-flex; align-items: center; justify-content: center;
618
+ background: none; border: 0; cursor: pointer; padding: 0; color: var(--bevel-muted);
619
+ }
620
+ .bevel-chip__collapse:hover { color: var(--bevel-ink); }
621
+ .bevel-chip__collapse svg { display: block; }
622
+ .bevel-chip__meta { font-family: var(--bevel-font-mono); font-size: 12px; color: var(--bevel-muted); }
623
+ .bevel-chip__changes-toggle {
624
+ background: none; border: 0; cursor: pointer; font: inherit; padding: 0 0 0 4px;
625
+ color: var(--bevel-brass); text-decoration: underline; text-underline-offset: 2px;
626
+ }
627
+ .bevel-chip__changes-toggle:hover { color: var(--bevel-ink); }
628
+ .bevel-chip__preview {
629
+ display: none; flex-direction: column; gap: 10px;
630
+ background: var(--bevel-sunk); border: 1px solid var(--bevel-line);
631
+ padding: 10px 11px;
632
+ }
633
+ .bevel-chip__panel.is-changes .bevel-chip__preview { display: flex; }
634
+ .bevel-chip__row { display: flex; flex-direction: column; gap: 2px; }
635
+ .bevel-chip__key {
636
+ font-family: var(--bevel-font-mono); font-size: 10.5px; font-weight: 500;
637
+ text-transform: uppercase; letter-spacing: .1em; color: var(--bevel-muted);
638
+ }
639
+ .bevel-chip__old, .bevel-chip__new { max-width: 100%; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; font-size: 13.5px; }
640
+ .bevel-chip__old { color: var(--bevel-ox); text-decoration: line-through; opacity: .85; }
641
+ .bevel-chip__new { color: var(--bevel-ink); }
642
+ .bevel-chip__actions { display: flex; flex-direction: column; gap: 8px; margin-top: 1px; }
643
+ .bevel-chip__actions .bevel-button { width: 100%; }
644
+
645
+ /* ============================ FIELD ============================ */
646
+ /* Label, control, one line of small print. The label is mono caps like every
647
+ other label on the page, and it follows the control's state. */
648
+ .bevel-field { display: flex; flex-direction: column; gap: 6px; }
649
+ .bevel-field__label, .bevel-fieldset > legend {
650
+ font-family: var(--bevel-font-mono); font-size: 11px; font-weight: 500;
651
+ letter-spacing: .13em; text-transform: uppercase; color: var(--bevel-muted);
652
+ }
653
+ .bevel-field + .bevel-field { margin-block-start: 18px; }
654
+ .bevel-field:has(:user-invalid) .bevel-field__label,
655
+ .bevel-field:has([aria-invalid="true"]) .bevel-field__label { color: var(--bevel-ox); }
656
+ .bevel-field:has(:disabled) .bevel-field__label { color: var(--bevel-faint); }
657
+ .bevel-field .bevel-hint--alert { display: none; }
658
+ .bevel-field:has(:user-invalid) .bevel-hint--alert,
659
+ .bevel-field:has([aria-invalid="true"]) .bevel-hint--alert { display: block; }
660
+ .bevel-fieldset { border: 1px solid var(--bevel-line); border-radius: 0; padding: 16px 20px 18px; margin: 0; min-width: 0; }
661
+ .bevel-fieldset > legend { padding: 0 8px; margin-left: -8px; }
662
+ .bevel-form { display: grid; grid-template-columns: 1fr 1fr; gap: 20px 24px; }
663
+ .bevel-form__full { grid-column: 1 / -1; }
664
+ @media (max-width: 640px) { .bevel-form { grid-template-columns: 1fr; } }
665
+ .bevel-choices { display: flex; flex-wrap: wrap; gap: 12px 26px; }
666
+ .bevel-buttons { display: flex; flex-wrap: wrap; gap: 10px; align-items: center; }
667
+
668
+ /* ============================ INPUT GROUP ============================ */
669
+ .bevel-igroup {
670
+ display: flex; align-items: stretch;
671
+ background: var(--bevel-surface); border: 1px solid var(--bevel-line-2); border-radius: 0;
672
+ transition: border-color .14s;
673
+ }
674
+ .bevel-igroup:hover { border-color: var(--bevel-faint); }
675
+ .bevel-igroup > .bevel-input { border: 0; background: transparent; flex: 1; min-width: 0; }
676
+ .bevel-igroup > .bevel-input:focus-visible { outline: 0; }
677
+ .bevel-igroup:focus-within { outline: 2px solid var(--bevel-brass); outline-offset: 1px; border-color: var(--bevel-brass); }
678
+ .bevel-igroup__affix {
679
+ display: flex; align-items: center; padding: 0 11px; background: var(--bevel-sunk);
680
+ font-family: var(--bevel-font-mono); font-size: 13px; color: var(--bevel-muted); white-space: nowrap;
681
+ }
682
+ .bevel-igroup__affix:first-child { border-right: 1px solid var(--bevel-line); }
683
+ .bevel-igroup__affix:last-child { border-left: 1px solid var(--bevel-line); }
684
+
685
+ /* ============================ INVALID ============================ */
686
+ /* Native constraint validation, styled. :user-invalid fires only after the
687
+ person interacts. aria-invalid="true" covers server-side errors. */
688
+ .bevel-input:user-invalid, .bevel-input[aria-invalid="true"],
689
+ .bevel-textarea:user-invalid, .bevel-textarea[aria-invalid="true"],
690
+ .bevel-date__field:user-invalid, .bevel-date__field[aria-invalid="true"],
691
+ .bevel-select__field:user-invalid, .bevel-select__field[aria-invalid="true"],
692
+ .bevel-number:has(.bevel-number__input:user-invalid),
693
+ .bevel-number:has(.bevel-number__input[aria-invalid="true"]),
694
+ .bevel-tags:has(:user-invalid), .bevel-igroup:has([aria-invalid="true"]) {
695
+ border-color: var(--bevel-ox);
696
+ background: color-mix(in srgb, var(--bevel-ox-soft) 32%, var(--bevel-surface));
697
+ }
698
+ .bevel-input:user-invalid:focus-visible, .bevel-input[aria-invalid="true"]:focus-visible,
699
+ .bevel-textarea:user-invalid:focus-visible, .bevel-textarea[aria-invalid="true"]:focus-visible { outline-color: var(--bevel-ox); }
700
+ .bevel-checkbox:has(:user-invalid) .bevel-checkbox__box,
701
+ .bevel-toggle:has(:user-invalid) .bevel-toggle__track { border-color: var(--bevel-ox); }
702
+ .bevel-radio:has(:user-invalid) .bevel-radio__ring { box-shadow: inset 0 0 0 2px var(--bevel-ox); }
703
+
704
+ /* ============================ PROGRESS ============================ */
705
+ /* A native <progress> in the slider's clothes: ink by default (a bar in a
706
+ broadsheet is a black bar), recoloured only when the reading is a judgement.
707
+ Keep the -webkit and -moz rules in separate blocks. */
708
+ .bevel-progress {
709
+ appearance: none; -webkit-appearance: none;
710
+ display: block; width: 100%; height: 8px;
711
+ border: 1px solid var(--bevel-line-2); background: var(--bevel-sunk); border-radius: 0;
712
+ }
713
+ .bevel-progress::-webkit-progress-bar { background: transparent; }
714
+ .bevel-progress::-webkit-progress-value { background: var(--bevel-ink); }
715
+ .bevel-progress::-moz-progress-bar { background: var(--bevel-ink); }
716
+ .bevel-progress--small { height: 6px; }
717
+ .bevel-progress--ok::-webkit-progress-value { background: var(--bevel-teal); }
718
+ .bevel-progress--ok::-moz-progress-bar { background: var(--bevel-teal); }
719
+ .bevel-progress--warn::-webkit-progress-value { background: var(--bevel-brass); }
720
+ .bevel-progress--warn::-moz-progress-bar { background: var(--bevel-brass); }
721
+ .bevel-progress--bad::-webkit-progress-value { background: var(--bevel-ox); }
722
+ .bevel-progress--bad::-moz-progress-bar { background: var(--bevel-ox); }
723
+ .bevel-progress--blocks::-webkit-progress-value {
724
+ background: repeating-linear-gradient(to right, var(--bevel-ink) 0 6px, transparent 6px 8px);
725
+ }
726
+ .bevel-progress--blocks::-moz-progress-bar {
727
+ background: repeating-linear-gradient(to right, var(--bevel-ink) 0 6px, transparent 6px 8px);
728
+ }
729
+
730
+ /* ============================ GAUGE ============================ */
731
+ /* A label, a bar, a mono value on one hairline row. */
732
+ .bevel-gauges { border-top: 1px solid var(--bevel-line); }
733
+ .bevel-gauge {
734
+ display: grid; grid-template-columns: 170px 1fr auto; gap: 16px; align-items: center;
735
+ padding: 12px 0; border-bottom: 1px solid var(--bevel-line);
736
+ }
737
+ .bevel-gauge__label {
738
+ font-family: var(--bevel-font-mono); font-size: 11px; font-weight: 500;
739
+ letter-spacing: .1em; text-transform: uppercase; color: var(--bevel-muted);
740
+ }
741
+ .bevel-gauge__value {
742
+ font-family: var(--bevel-font-mono); font-size: 13px; font-weight: 600;
743
+ min-width: 56px; text-align: right; color: var(--bevel-ink);
744
+ }
745
+ .bevel-gauge--ok .bevel-gauge__value { color: var(--bevel-teal); }
746
+ .bevel-gauge--warn .bevel-gauge__value { color: color-mix(in srgb, var(--bevel-brass) 80%, var(--bevel-ink)); }
747
+ .bevel-gauge--bad .bevel-gauge__value { color: var(--bevel-ox); }
748
+ @media (max-width: 560px) {
749
+ .bevel-gauge { grid-template-columns: 1fr auto; gap: 6px 16px; }
750
+ .bevel-gauge__label { grid-column: 1 / -1; }
751
+ }
752
+
753
+ /* ============================ NOTE ============================ */
754
+ /* A callout with a grade. Flat on purpose: bevel means pressable, a note is
755
+ content. Tints mix the soft accent nearly away so a stack stays readable. */
756
+ .bevel-note {
757
+ display: grid; grid-template-columns: auto 1fr; gap: 4px 16px; align-items: baseline;
758
+ padding: 14px 18px; background: var(--bevel-surface);
759
+ border: 1px solid var(--bevel-line); border-radius: 0;
760
+ font-size: 15px; line-height: 1.55; color: var(--bevel-ink-2);
761
+ }
762
+ .bevel-note__tag {
763
+ font-family: var(--bevel-font-mono); font-size: 10.5px; font-weight: 600;
764
+ letter-spacing: .12em; text-transform: uppercase; color: var(--bevel-muted); white-space: nowrap;
765
+ }
766
+ .bevel-note__body { margin: 0; }
767
+ .bevel-note__body p { margin: 0; }
768
+ .bevel-note__body p + p { margin-top: 8px; }
769
+ .bevel-note--ok { background: color-mix(in srgb, var(--bevel-teal-soft) 45%, var(--bevel-surface)); border-color: color-mix(in srgb, var(--bevel-teal) 24%, var(--bevel-line)); }
770
+ .bevel-note--ok .bevel-note__tag { color: var(--bevel-teal); }
771
+ .bevel-note--warn { background: color-mix(in srgb, var(--bevel-brass-soft) 45%, var(--bevel-surface)); border-color: color-mix(in srgb, var(--bevel-brass) 24%, var(--bevel-line)); }
772
+ .bevel-note--warn .bevel-note__tag { color: color-mix(in srgb, var(--bevel-brass) 80%, var(--bevel-ink)); }
773
+ .bevel-note--bad { background: color-mix(in srgb, var(--bevel-ox-soft) 45%, var(--bevel-surface)); border-color: color-mix(in srgb, var(--bevel-ox) 24%, var(--bevel-line)); }
774
+ .bevel-note--bad .bevel-note__tag { color: var(--bevel-ox); }
775
+ .bevel-note--stack { grid-template-columns: 1fr; gap: 6px; }
776
+ .bevel-notes { display: grid; gap: 10px; }
777
+ @media (max-width: 480px) { .bevel-note { grid-template-columns: 1fr; gap: 3px; } }
778
+
779
+ /* ============================ CALLOUT ============================ */
780
+ /* A recessed aside for the paragraph the reader must not skim. No accent. */
781
+ .bevel-callout {
782
+ padding: 16px 18px; background: var(--bevel-sunk);
783
+ border: 1px solid var(--bevel-line); border-radius: 0;
784
+ font-size: 15.5px; line-height: 1.6; color: var(--bevel-ink-2);
785
+ }
786
+ .bevel-callout p { margin: 0; }
787
+ .bevel-callout p + p { margin-top: 10px; }
788
+
789
+ /* ============================ HINT ============================ */
790
+ .bevel-hint { margin: 0; font-size: 13.5px; line-height: 1.5; color: var(--bevel-muted); }
791
+ .bevel-hint--alert { color: var(--bevel-ox); font-weight: 500; }
792
+
793
+ /* ============================ LIST ============================ */
794
+ /* Square markers for a set of rules, zero-padded mono counters for a sequence. */
795
+ .bevel-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 6px; font-size: 17px; line-height: 1.6; }
796
+ .bevel-list li { position: relative; padding-left: 22px; }
797
+ ul.bevel-list > li::before {
798
+ content: ""; position: absolute; left: 2px; top: .62em; width: 6px; height: 6px;
799
+ background: var(--bevel-ink-2);
800
+ }
801
+ ol.bevel-list { counter-reset: bevel-li; }
802
+ ol.bevel-list > li { counter-increment: bevel-li; padding-left: 38px; }
803
+ ol.bevel-list > li::before {
804
+ content: counter(bevel-li, decimal-leading-zero);
805
+ position: absolute; left: 0; top: .1em;
806
+ font-family: var(--bevel-font-mono); font-size: 13px; font-weight: 500; color: var(--bevel-muted);
807
+ }
808
+ .bevel-list ul { list-style: none; margin: 6px 0 0; padding: 0; display: flex; flex-direction: column; gap: 6px; }
809
+ .bevel-list ul > li::before {
810
+ content: ""; position: absolute; left: 2px; top: .62em; width: 6px; height: 6px;
811
+ background: transparent; border: 1.5px solid var(--bevel-ink-2);
812
+ }
813
+ .bevel-list--small { font-size: 14px; gap: 4px; }
814
+ .bevel-list--small li { padding-left: 18px; }
815
+ ul.bevel-list--small > li::before, .bevel-list--small ul > li::before { width: 5px; height: 5px; }
816
+ ol.bevel-list--small > li { padding-left: 32px; }
817
+ ol.bevel-list--small > li::before { font-size: 11px; }
818
+
819
+ /* ============================ BADGE ============================ */
820
+ /* A static label in mono caps. Grades judge a claim: --for confirms,
821
+ --against contradicts, --note is unresolved; --alert is ox. */
822
+ .bevel-badge {
823
+ display: inline-flex; align-items: center; gap: 6px;
824
+ font-family: var(--bevel-font-mono); font-size: 10.5px; font-weight: 600;
825
+ letter-spacing: .1em; text-transform: uppercase; white-space: nowrap;
826
+ padding: 3px 8px; border-radius: 0; vertical-align: 2px;
827
+ background: var(--bevel-sunk); color: var(--bevel-muted);
828
+ border: 1px solid var(--bevel-line);
829
+ }
830
+ .bevel-badge--for { background: var(--bevel-teal-soft); color: var(--bevel-teal); border-color: color-mix(in srgb, var(--bevel-teal) 28%, var(--bevel-teal-soft)); }
831
+ .bevel-badge--against { background: var(--bevel-brass-soft); color: color-mix(in srgb, var(--bevel-brass) 80%, var(--bevel-ink)); border-color: color-mix(in srgb, var(--bevel-brass) 28%, var(--bevel-brass-soft)); }
832
+ .bevel-badge--note { background: var(--bevel-sunk); color: var(--bevel-muted); }
833
+ .bevel-badge--alert { background: var(--bevel-ox-soft); color: var(--bevel-ox); border-color: color-mix(in srgb, var(--bevel-ox) 28%, var(--bevel-ox-soft)); }
834
+ .bevel-badge--accent { background: var(--bevel-brass-soft); color: color-mix(in srgb, var(--bevel-brass) 80%, var(--bevel-ink)); border-color: color-mix(in srgb, var(--bevel-brass) 28%, var(--bevel-brass-soft)); }
835
+
836
+ /* ============================ PILL ============================ */
837
+ /* Operational status: a square marker in a tinted box. Pills grade things,
838
+ badges grade claims. --live breathes. */
839
+ .bevel-pill {
840
+ display: inline-flex; align-items: center; gap: 6px;
841
+ font-family: var(--bevel-font-mono); font-size: 10.5px; font-weight: 600;
842
+ letter-spacing: .09em; text-transform: uppercase; white-space: nowrap;
843
+ min-height: 22px; padding: 3px 9px; border-radius: 0; vertical-align: 1px;
844
+ background: var(--bevel-sunk); color: var(--bevel-muted); border: 1px solid var(--bevel-line);
845
+ }
846
+ .bevel-pill::before { content: ""; width: 5px; height: 5px; background: currentColor; flex-shrink: 0; }
847
+ .bevel-pill--live { background: var(--bevel-teal-soft); color: var(--bevel-teal); border-color: color-mix(in srgb, var(--bevel-teal) 28%, var(--bevel-teal-soft)); }
848
+ .bevel-pill--live::before { animation: bevel-pulse 2.4s ease-in-out infinite; }
849
+ .bevel-pill--warn { background: var(--bevel-brass-soft); color: color-mix(in srgb, var(--bevel-brass) 80%, var(--bevel-ink)); border-color: color-mix(in srgb, var(--bevel-brass) 28%, var(--bevel-brass-soft)); }
850
+ .bevel-pill--down { background: var(--bevel-ox-soft); color: var(--bevel-ox); border-color: color-mix(in srgb, var(--bevel-ox) 28%, var(--bevel-ox-soft)); }
851
+ .bevel-pills { display: flex; flex-wrap: wrap; gap: 10px; }
852
+ @keyframes bevel-pulse { 0%, 100% { opacity: 1; } 50% { opacity: .35; } }
853
+
854
+ /* ============================ TABLE ============================ */
855
+ /* Always mono, always inside .bevel-scroll, opened by a caption in the sans.
856
+ <b> is a cell's value and <i> its context. State helpers by descent:
857
+ win, lose, nil, dn, sel. */
858
+ .bevel-scroll { overflow-x: auto; border: 1px solid var(--bevel-line); border-radius: 0; background: var(--bevel-surface); box-shadow: var(--bevel-shadow); }
859
+ .bevel-table { border-collapse: collapse; width: 100%; font-family: var(--bevel-font-mono); font-size: 13.5px; line-height: 1.5; }
860
+ .bevel-table caption { text-align: left; padding: 16px 18px 0; font-family: var(--bevel-font-sans); font-size: 13.5px; color: var(--bevel-muted); line-height: 1.5; caption-side: top; }
861
+ .bevel-table thead th {
862
+ position: sticky; top: 0; background: var(--bevel-surface); text-align: center;
863
+ font-size: 11px; font-weight: 600; letter-spacing: .09em; text-transform: uppercase;
864
+ color: var(--bevel-muted); padding: 14px 12px 11px; border-bottom: 1px solid var(--bevel-line-2); white-space: nowrap;
865
+ }
866
+ .bevel-table thead th span { display: block; font-size: 10px; font-weight: 400; color: var(--bevel-faint); letter-spacing: .1em; margin-top: 2px; }
867
+ .bevel-table thead th:first-child { text-align: left; }
868
+ .bevel-table tbody th { text-align: left; font-weight: 500; padding: 9px 14px; border-bottom: 1px solid var(--bevel-line); white-space: nowrap; background: var(--bevel-surface); }
869
+ .bevel-table tbody th b { font-weight: 600; }
870
+ .bevel-table tbody th i { display: block; font-style: normal; font-size: 10.5px; color: var(--bevel-faint); letter-spacing: .04em; }
871
+ .bevel-table td { text-align: center; padding: 9px 12px; border-bottom: 1px solid var(--bevel-line); white-space: nowrap; vertical-align: top; }
872
+ .bevel-table td b { display: block; font-weight: 600; font-size: 13.5px; }
873
+ .bevel-table td i { display: block; font-style: normal; font-size: 10.5px; color: var(--bevel-faint); letter-spacing: .03em; margin-top: 1px; }
874
+ .bevel-table tbody tr:last-child th, .bevel-table tbody tr:last-child td { border-bottom: 0; }
875
+ .bevel-table tfoot th, .bevel-table tfoot td { border-top: 1px solid var(--bevel-line-2); border-bottom: 0; padding: 10px 12px; white-space: nowrap; background: var(--bevel-surface); }
876
+ .bevel-table tfoot th { text-align: left; font-weight: 600; padding-left: 14px; }
877
+ .bevel-table tfoot td { text-align: center; color: var(--bevel-ink-2); }
878
+ .bevel-table td.nil { color: var(--bevel-faint); }
879
+ .bevel-table td.win { background: var(--bevel-teal-soft); }
880
+ .bevel-table td.win b { color: var(--bevel-teal); }
881
+ .bevel-table td.lose { background: var(--bevel-sunk); }
882
+ .bevel-table td.lose b { color: var(--bevel-faint); }
883
+ .bevel-table .dn { color: var(--bevel-ox); }
884
+ .bevel-table tr.sel th { box-shadow: inset 3px 0 0 var(--bevel-ox); }
885
+ .bevel-table tr.sel th b { color: var(--bevel-ox); }
886
+ .bevel-table--striped tbody tr:nth-child(even) td { background: color-mix(in srgb, var(--bevel-sunk) 55%, var(--bevel-surface)); }
887
+ .bevel-table--hover tbody tr { transition: background-color .12s; }
888
+ .bevel-table--hover tbody tr:hover :is(th, td) { background: color-mix(in srgb, var(--bevel-sunk) 55%, var(--bevel-surface)); }
889
+ .bevel-table tbody tr:has(.bevel-table__pick input:checked) :is(th, td) { background: color-mix(in srgb, var(--bevel-sunk) 85%, var(--bevel-surface)); }
890
+ .bevel-table__pick { width: 38px; text-align: center; }
891
+ .bevel-table__pick .bevel-checkbox { display: inline-grid; vertical-align: middle; }
892
+ .bevel-table__pick .bevel-checkbox__box { margin-top: 0; }
893
+ .bevel-table--small { font-size: 12.5px; }
894
+ .bevel-table--small thead th { padding: 10px 10px 8px; font-size: 10px; }
895
+ .bevel-table--small td, .bevel-table--small tbody th { padding: 6px 10px; }
896
+ .bevel-table--left td { text-align: left; }
897
+
898
+ /* ============================ GRID ============================ */
899
+ /* The data table. bevel-table is content, a grid is a tool: a frame holding
900
+ a toolbar, a scroll box with a sticky head, a sticky spine (pick, row
901
+ number, anchor) and a sticky aggregate strip, then a status bar with the
902
+ pages. Language is sans, anything with a digit is mono, and alignment
903
+ follows the type: text left, figures right. Every state is an attribute:
904
+ aria-sort on the head, checked on the pick, aria-expanded on the toggle,
905
+ data-page on the frame, value on the search. Column heads sort flat, like
906
+ tabs: a row of twelve bevels would out-shout the data. The table is
907
+ border-collapse: separate because a collapsed border does not travel with
908
+ a sticky cell. */
909
+ .bevel-grid {
910
+ display: flex; flex-direction: column;
911
+ background: var(--bevel-surface); border: 1px solid var(--bevel-line-2); border-radius: 0;
912
+ box-shadow: var(--bevel-shadow); font-size: 14px; line-height: 1.5; color: var(--bevel-ink);
913
+ }
914
+ .bevel-grid__masthead { display: flex; justify-content: space-between; align-items: end; flex-wrap: wrap; gap: 20px; padding: 26px 26px 22px; }
915
+ .bevel-grid__masthead .bevel-grid__title { display: block; margin: 7px 0 6px; font-family: var(--bevel-font-serif); font-size: 42px; font-weight: 500; line-height: 1.08; letter-spacing: -.025em; }
916
+ .bevel-grid__description { margin: 0; font-size: 14px; line-height: 1.5; color: var(--bevel-muted); }
917
+ .bevel-grid__stats { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); margin: 0; border-block: 1px solid var(--bevel-line-2); background: var(--bevel-ground); }
918
+ .bevel-grid__stat { padding: 15px 24px 17px; border-right: 1px solid var(--bevel-line); }
919
+ .bevel-grid__stat:last-child { border-right: 0; }
920
+ .bevel-grid__stat dt { font-family: var(--bevel-font-mono); font-size: 10px; font-weight: 500; line-height: 1.5; letter-spacing: .12em; text-transform: uppercase; color: var(--bevel-muted); }
921
+ .bevel-grid__stat dd { margin: 5px 0 0; font-family: var(--bevel-font-mono); font-size: clamp(18px, 2.2vw, 28px); font-weight: 500; line-height: 1.2; letter-spacing: -.06em; }
922
+ .bevel-grid__views { display: flex; overflow-x: auto; padding: 0 18px; gap: 14px; border-bottom: 1px solid var(--bevel-line); }
923
+ .bevel-grid__view { appearance: none; background: none; color: var(--bevel-muted); border: 0; border-bottom: 3px solid transparent; padding: 14px 8px 11px; cursor: pointer; font-family: var(--bevel-font-sans); font-size: 13px; font-weight: 500; line-height: 1.5; white-space: nowrap; }
924
+ .bevel-grid__view span { margin-left: 8px; font-family: var(--bevel-font-mono); font-size: 11px; }
925
+ .bevel-grid__view[aria-pressed="true"] { border-bottom-color: var(--bevel-brass); color: var(--bevel-ink); }
926
+ .bevel-grid__view:hover { color: var(--bevel-ink); }
927
+ .bevel-grid__view:focus-visible { outline: 2px solid var(--bevel-brass); outline-offset: -4px; }
928
+ .bevel-grid__masthead > .bevel-grid__id { font-size: 11px; color: var(--bevel-muted); }
929
+ @media (max-width: 640px) {
930
+ .bevel-grid__masthead { padding: 20px; }
931
+ .bevel-grid__masthead .bevel-grid__title { font-size: 34px; }
932
+ .bevel-grid__stats { grid-template-columns: repeat(2, minmax(0, 1fr)); }
933
+ .bevel-grid__stat { padding: 14px 18px; }
934
+ .bevel-grid__stat:nth-child(-n+2) { border-bottom: 1px solid var(--bevel-line); }
935
+ .bevel-grid__stat:nth-child(2) { border-right: 0; }
936
+ }
937
+ .bevel-grid__bar {
938
+ display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 10px 18px;
939
+ padding: 12px 16px; border-bottom: 1px solid var(--bevel-line);
940
+ }
941
+ .bevel-grid__title { margin: 0; display: flex; align-items: baseline; gap: 10px; font-family: var(--bevel-font-sans); font-size: 16px; font-weight: 600; line-height: 1.5; color: var(--bevel-ink); }
942
+ .bevel-grid__count { font-family: var(--bevel-font-mono); font-size: 11px; font-weight: 500; letter-spacing: .06em; color: var(--bevel-muted); }
943
+ .bevel-grid__tools { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
944
+ .bevel-grid__search { width: 220px; }
945
+ .bevel-grid__scroll { overflow: auto; scrollbar-width: thin; }
946
+ .bevel-grid__table { border-collapse: separate; border-spacing: 0; width: 100%; font-family: var(--bevel-font-sans); font-size: 14px; line-height: 1.5; }
947
+
948
+ /* Head: mono caps, sticky, a line-2 rule under it. */
949
+ .bevel-grid__table thead th {
950
+ position: sticky; top: 0; z-index: 2;
951
+ background: var(--bevel-surface); text-align: left; vertical-align: bottom;
952
+ font-family: var(--bevel-font-mono); font-size: 11px; font-weight: 600; letter-spacing: .09em; text-transform: uppercase; line-height: 1.5;
953
+ color: var(--bevel-muted); padding: 10px 12px 9px; border-bottom: 1px solid var(--bevel-line-2); white-space: nowrap;
954
+ }
955
+ .bevel-grid__head { text-align: left; }
956
+ .bevel-grid__head--num { text-align: right; }
957
+ .bevel-grid__head--center { text-align: center; }
958
+ .bevel-grid__sort {
959
+ appearance: none; -webkit-appearance: none; border: 0; background: none; padding: 0; margin: 0; cursor: pointer;
960
+ font: inherit; letter-spacing: inherit; text-transform: inherit; color: inherit; line-height: inherit;
961
+ display: inline-flex; align-items: center; gap: 7px; transition: color .14s;
962
+ }
963
+ .bevel-grid__sort::after {
964
+ content: ""; width: 5px; height: 5px; flex-shrink: 0;
965
+ border-right: 1.5px solid var(--bevel-brass); border-bottom: 1.5px solid var(--bevel-brass);
966
+ transform: translateY(-2px) rotate(45deg); opacity: 0; transition: opacity .14s;
967
+ }
968
+ .bevel-grid__sort:hover { color: var(--bevel-ink); }
969
+ .bevel-grid__sort:hover::after { opacity: .45; }
970
+ .bevel-grid__sort:focus-visible { outline: 2px solid var(--bevel-brass); outline-offset: 3px; }
971
+ [aria-sort="ascending"] > .bevel-grid__sort, [aria-sort="descending"] > .bevel-grid__sort { color: var(--bevel-ink); }
972
+ [aria-sort="ascending"] > .bevel-grid__sort::after, [aria-sort="descending"] > .bevel-grid__sort::after { opacity: 1; }
973
+ [aria-sort="ascending"] > .bevel-grid__sort::after { transform: translateY(1px) rotate(-135deg); }
974
+
975
+ /* Cells paint their own surface so the sticky ones cover what scrolls under them. */
976
+ .bevel-grid__table td, .bevel-grid__table tbody th {
977
+ padding: 8px 12px; border-bottom: 1px solid var(--bevel-line); vertical-align: middle; white-space: nowrap;
978
+ background: var(--bevel-surface); text-align: left; font-weight: 400;
979
+ }
980
+ .bevel-grid__num { text-align: right; font-family: var(--bevel-font-mono); font-size: 13px; font-variant-numeric: tabular-nums; }
981
+ .bevel-grid__id { font-family: var(--bevel-font-mono); font-size: 13px; }
982
+ .bevel-grid__date { font-family: var(--bevel-font-mono); font-size: 13px; color: var(--bevel-ink-2); }
983
+ .bevel-grid__center { text-align: center; }
984
+ .bevel-grid__center .bevel-checkbox { display: inline-grid; vertical-align: middle; }
985
+ .bevel-grid__center .bevel-checkbox__box { margin-top: 0; }
986
+ .bevel-grid__actor { display: inline-flex; align-items: center; gap: 8px; vertical-align: middle; }
987
+ .bevel-grid__avatar {
988
+ display: inline-flex; align-items: center; justify-content: center; flex-shrink: 0; width: 22px; height: 22px;
989
+ font-family: var(--bevel-font-mono); font-size: 9.5px; font-weight: 600; font-style: normal; letter-spacing: .04em; line-height: 1;
990
+ color: var(--bevel-muted); background: var(--bevel-sunk); border: 1px solid var(--bevel-line-2);
991
+ }
992
+ .bevel-grid__meter { display: inline-flex; align-items: center; gap: 8px; vertical-align: middle; }
993
+ .bevel-grid__meter .bevel-progress { width: 64px; }
994
+ .bevel-grid__meter b { font-family: var(--bevel-font-mono); font-size: 12px; font-weight: 500; min-width: 34px; text-align: right; }
995
+ .bevel-grid__tags { display: inline-flex; gap: 4px; vertical-align: middle; }
996
+ .bevel-grid__tags .bevel-badge { vertical-align: 0; }
997
+
998
+ /* The spine: pick at 0, the row number beside it, the anchor after both,
999
+ each sticky at the sum of the widths before it. */
1000
+ .bevel-grid__pick, .bevel-grid__n, .bevel-grid__anchor { position: sticky; left: 0; z-index: 1; }
1001
+ .bevel-grid__table thead :is(.bevel-grid__pick, .bevel-grid__n, .bevel-grid__anchor) { z-index: 3; }
1002
+ .bevel-grid__pick { width: 44px; min-width: 44px; padding-right: 0; padding-left: 12px; text-align: center; }
1003
+ .bevel-grid__pick .bevel-checkbox { display: inline-grid; vertical-align: middle; }
1004
+ .bevel-grid__pick .bevel-checkbox__box { margin-top: 0; }
1005
+ .bevel-grid__n { width: 48px; min-width: 48px; padding-right: 10px; text-align: right; font-family: var(--bevel-font-mono); font-size: 11.5px; color: var(--bevel-faint); }
1006
+ .bevel-grid__table tbody { counter-reset: bevel-row; }
1007
+ .bevel-grid__row { counter-increment: bevel-row; }
1008
+ .bevel-grid__table tbody > .bevel-grid__row > .bevel-grid__n::before { content: counter(bevel-row); }
1009
+ .bevel-grid__table:has(.bevel-grid__pick) .bevel-grid__n { left: 44px; }
1010
+ .bevel-grid__anchor { font-weight: 500; border-right: 1px solid var(--bevel-line-2); }
1011
+ .bevel-grid__table:has(.bevel-grid__pick):not(:has(.bevel-grid__n)) .bevel-grid__anchor { left: 44px; }
1012
+ .bevel-grid__table:has(.bevel-grid__n):not(:has(.bevel-grid__pick)) .bevel-grid__anchor { left: 48px; }
1013
+ .bevel-grid__table:has(.bevel-grid__pick):has(.bevel-grid__n) .bevel-grid__anchor { left: 92px; }
1014
+
1015
+ /* Row states. Selected takes a brass tint and a brass bar on the spine,
1016
+ hover the sunk tint, changed a brass dog-ear on its first cell. */
1017
+ .bevel-grid__row:hover > :is(td, th) { background: color-mix(in srgb, var(--bevel-sunk) 55%, var(--bevel-surface)); }
1018
+ .bevel-grid__row:has(.bevel-grid__pick input:checked) > :is(td, th) { background: color-mix(in srgb, var(--bevel-brass-soft) 55%, var(--bevel-surface)); }
1019
+ .bevel-grid__row:has(.bevel-grid__pick input:checked) > :first-child { box-shadow: inset 3px 0 0 var(--bevel-brass); }
1020
+ .bevel-grid__row--changed > :first-child { position: sticky; }
1021
+ .bevel-grid__row--changed > :first-child::after {
1022
+ content: ""; position: absolute; left: 0; top: 0; border: 5px solid var(--bevel-brass);
1023
+ border-right-color: transparent; border-bottom-color: transparent;
1024
+ }
1025
+ .bevel-grid__row--disabled > :is(td, th) { color: var(--bevel-faint); }
1026
+ .bevel-grid__row--disabled:hover > :is(td, th) { background: var(--bevel-surface); }
1027
+ .bevel-grid__row:has(.bevel-grid__expand[aria-expanded="true"]) > :is(td, th) { background: color-mix(in srgb, var(--bevel-sunk) 55%, var(--bevel-surface)); border-bottom-color: transparent; }
1028
+ .bevel-grid__detail > td { padding: 0; background: var(--bevel-sunk); border-bottom: 1px solid var(--bevel-line-2); white-space: normal; }
1029
+ .bevel-grid__panel { position: sticky; left: 0; width: fit-content; max-width: 100%; padding: 12px 16px 16px 16px; color: var(--bevel-ink-2); font-size: 14px; }
1030
+ .bevel-grid__panel p { margin: 0; }
1031
+ .bevel-grid__panel p + p { margin-top: 6px; }
1032
+ .bevel-grid__group > th {
1033
+ position: sticky; left: 0; padding: 6px 12px; background: var(--bevel-sunk); text-align: left;
1034
+ border-top: 1px solid var(--bevel-line-2); border-bottom: 1px solid var(--bevel-line);
1035
+ font-family: var(--bevel-font-mono); font-size: 11px; font-weight: 600; letter-spacing: .1em; text-transform: uppercase; color: var(--bevel-muted);
1036
+ }
1037
+ .bevel-grid__group > th > span { position: sticky; left: 12px; display: inline-flex; gap: 8px; align-items: baseline; }
1038
+
1039
+ /* The expander is the details latch as a button; the menu is a raised
1040
+ square carrying three dots. Both are pressable, so both get the bevel. */
1041
+ .bevel-grid__expand, .bevel-grid__more {
1042
+ appearance: none; -webkit-appearance: none; position: relative; cursor: pointer; padding: 0; line-height: 0;
1043
+ width: 22px; height: 22px; vertical-align: middle; color: var(--bevel-ink);
1044
+ background: var(--bevel-face); border: 2px solid;
1045
+ border-color: var(--bevel-edge-hi) var(--bevel-edge-lo) var(--bevel-edge-lo) var(--bevel-edge-hi);
1046
+ border-radius: 0; outline: none;
1047
+ }
1048
+ .bevel-grid__expand { margin-right: 10px; }
1049
+ .bevel-grid__expand:hover, .bevel-grid__more:hover { background: color-mix(in srgb, var(--bevel-face), var(--bevel-edge-hi) 45%); }
1050
+ .bevel-grid__expand:active, .bevel-grid__more:active { border-color: var(--bevel-edge-lo) var(--bevel-edge-hi) var(--bevel-edge-hi) var(--bevel-edge-lo); }
1051
+ .bevel-grid__expand:focus-visible, .bevel-grid__more:focus-visible { outline: 2px solid var(--bevel-brass); outline-offset: 2px; }
1052
+ .bevel-grid__expand::before {
1053
+ content: ""; position: absolute; left: 50%; top: 50%; width: 6px; height: 6px;
1054
+ border-right: 1.5px solid currentColor; border-bottom: 1.5px solid currentColor;
1055
+ transform: translate(-65%, -50%) rotate(-45deg); transition: transform .14s;
1056
+ }
1057
+ .bevel-grid__expand[aria-expanded="true"] {
1058
+ background: var(--bevel-face-in);
1059
+ border-color: var(--bevel-edge-in) var(--bevel-edge-in-hi) var(--bevel-edge-in-hi) var(--bevel-edge-in);
1060
+ }
1061
+ .bevel-grid__expand[aria-expanded="true"]::before { transform: translate(calc(-50% + 1px), calc(-65% + 1px)) rotate(45deg); }
1062
+ .bevel-grid__more::before {
1063
+ content: ""; position: absolute; left: 50%; top: 50%; width: 3px; height: 3px; translate: -50% -50%;
1064
+ background: currentColor; box-shadow: -5px 0 0 currentColor, 5px 0 0 currentColor;
1065
+ }
1066
+ .bevel-grid__menu { width: 44px; text-align: center; padding-left: 8px; padding-right: 8px; }
1067
+
1068
+ /* The aggregate strip: sticky at the foot of the scroll box, sunk, a mono
1069
+ figure under a faint label. */
1070
+ .bevel-grid__table tfoot :is(th, td) {
1071
+ position: sticky; bottom: 0; z-index: 2; background: var(--bevel-sunk);
1072
+ border-top: 1px solid var(--bevel-line-2); border-bottom: 0; padding: 6px 12px 7px; text-align: left;
1073
+ font-family: var(--bevel-font-mono); font-size: 12.5px; font-weight: 500; color: var(--bevel-ink-2); white-space: nowrap;
1074
+ }
1075
+ .bevel-grid__table tfoot :is(.bevel-grid__pick, .bevel-grid__n, .bevel-grid__anchor) { z-index: 3; }
1076
+ .bevel-grid__table tfoot i { display: block; font-style: normal; font-size: 9.5px; font-weight: 500; letter-spacing: .12em; text-transform: uppercase; color: var(--bevel-faint); }
1077
+
1078
+ /* The status bar: selection and range in mono, pages as adjacent small
1079
+ bevel buttons with the current one pressed in. */
1080
+ .bevel-grid__foot {
1081
+ display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 10px 18px;
1082
+ padding: 10px 16px; border-top: 1px solid var(--bevel-line);
1083
+ }
1084
+ .bevel-grid__status { margin: 0; display: flex; flex-wrap: wrap; gap: 16px; font-family: var(--bevel-font-mono); font-size: 11.5px; letter-spacing: .04em; color: var(--bevel-muted); }
1085
+ .bevel-grid__status b, .bevel-grid__selected { font-weight: 600; color: var(--bevel-ink); }
1086
+ .bevel-grid__range { font-variant-numeric: tabular-nums; }
1087
+ .bevel-grid__pages { display: inline-flex; align-items: center; }
1088
+ .bevel-grid__pages > .bevel-button { font-family: var(--bevel-font-mono); font-size: 11px; font-weight: 500; letter-spacing: .04em; padding: 3px 6px; min-width: 30px; }
1089
+ .bevel-grid__pages > .bevel-button + .bevel-button { margin-left: -2px; }
1090
+ .bevel-grid__page[aria-current="page"] {
1091
+ background: var(--bevel-face-in);
1092
+ border-color: var(--bevel-edge-in) var(--bevel-edge-in-hi) var(--bevel-edge-in-hi) var(--bevel-edge-in);
1093
+ position: relative; z-index: 1;
1094
+ }
1095
+ .bevel-grid__page[aria-current="page"] .bevel-button__label { translate: 1px 1px; }
1096
+ .bevel-grid__gap { min-width: 26px; text-align: center; font-family: var(--bevel-font-mono); font-size: 11px; color: var(--bevel-faint); }
1097
+
1098
+ /* Empty and loading rows live in the body so the head and the frame stay. */
1099
+ .bevel-grid__empty > td { padding: 34px 24px; text-align: center; white-space: normal; color: var(--bevel-ink-2); border-bottom: 0; }
1100
+ .bevel-grid__empty p { margin: 0; }
1101
+ .bevel-grid__empty .bevel-kicker { margin-bottom: 6px; }
1102
+ .bevel-grid__skel > td { padding: 12px; }
1103
+ .bevel-grid__skel i { display: block; height: 11px; width: 72%; background: var(--bevel-sunk); animation: bevel-skel 1.5s ease-in-out infinite; }
1104
+ .bevel-grid__skel:nth-child(even) i { width: 52%; animation-delay: .12s; }
1105
+ .bevel-grid__skel:nth-child(3n) i { width: 88%; animation-delay: .24s; }
1106
+
1107
+ .bevel-grid--dense { font-size: 13px; }
1108
+ .bevel-grid--dense .bevel-grid__table { font-size: 13px; }
1109
+ .bevel-grid--dense .bevel-grid__table td, .bevel-grid--dense .bevel-grid__table tbody th { padding-top: 4px; padding-bottom: 4px; }
1110
+ .bevel-grid--dense .bevel-grid__table thead th { padding: 7px 12px 6px; font-size: 10.5px; }
1111
+ .bevel-grid--dense .bevel-grid__num, .bevel-grid--dense .bevel-grid__id, .bevel-grid--dense .bevel-grid__date { font-size: 12.5px; }
1112
+ .bevel-grid--ruled .bevel-grid__table :is(td, th):not(:last-child) { border-right: 1px solid var(--bevel-line); }
1113
+ .bevel-grid--ruled .bevel-grid__anchor { border-right-color: var(--bevel-line-2); }
1114
+ .bevel-grid--striped .bevel-grid__row:nth-child(even of .bevel-grid__row) > :is(td, th) { background: color-mix(in srgb, var(--bevel-sunk) 40%, var(--bevel-surface)); }
1115
+
1116
+ /* ============================ SKELETON, EMPTY ============================ */
1117
+ .bevel-skel { background: var(--bevel-surface); border: 1px solid var(--bevel-line); border-radius: 0; padding: 20px 22px; display: grid; gap: 11px; }
1118
+ .bevel-skel i { display: block; height: 12px; background: var(--bevel-sunk); animation: bevel-skel 1.5s ease-in-out infinite; }
1119
+ .bevel-skel i.hd { height: 17px; }
1120
+ .bevel-skel i:nth-child(2) { animation-delay: .12s; }
1121
+ .bevel-skel i:nth-child(3) { animation-delay: .24s; }
1122
+ .bevel-skel i:nth-child(4) { animation-delay: .36s; }
1123
+ @keyframes bevel-skel { 0%, 100% { opacity: 1; } 50% { opacity: .45; } }
1124
+ .bevel-empty { border: 1px dashed var(--bevel-line-2); border-radius: 0; padding: 34px 24px; text-align: center; }
1125
+ .bevel-empty > p { font-size: 14.5px; color: var(--bevel-ink-2); max-width: 46ch; margin: 8px auto 16px; }
1126
+ .bevel-empty > .bevel-kicker { margin: 0; color: var(--bevel-muted); }
1127
+
1128
+ /* ============================ ROWS ============================ */
1129
+ /* Labeled rows record decisions; evidence rows test claims. */
1130
+ .bevel-rev { display: grid; gap: 14px; }
1131
+ .bevel-rev__row {
1132
+ display: grid; grid-template-columns: auto 1fr; gap: 14px; align-items: baseline;
1133
+ padding: 14px 16px; background: var(--bevel-surface); border: 1px solid var(--bevel-line); border-radius: 0;
1134
+ }
1135
+ .bevel-rev__k { font-family: var(--bevel-font-mono); font-size: 11px; font-weight: 600; letter-spacing: .1em; text-transform: uppercase; color: var(--bevel-muted); white-space: nowrap; }
1136
+ .bevel-rev__row p { margin: 0; font-size: 15px; }
1137
+ .bevel-rev__row p b { font-family: var(--bevel-font-mono); font-size: 14px; color: var(--bevel-ox); }
1138
+ .bevel-ev { border-top: 1px solid var(--bevel-line); }
1139
+ .bevel-ev__row { display: grid; grid-template-columns: 132px 1fr; gap: 22px; padding: 19px 0; border-bottom: 1px solid var(--bevel-line); align-items: start; }
1140
+ .bevel-ev__row > h4, .bevel-ev__row > p { grid-column: 2; }
1141
+ .bevel-ev__row h4 { margin: 0; font-family: var(--bevel-font-sans); font-size: 15.5px; font-weight: 600; letter-spacing: -.005em; }
1142
+ .bevel-ev__row p { margin: 5px 0 0; font-size: 15px; color: var(--bevel-ink-2); }
1143
+ @media (max-width: 640px) {
1144
+ .bevel-ev__row { grid-template-columns: 1fr; gap: 9px; }
1145
+ .bevel-ev__row > h4, .bevel-ev__row > p { grid-column: auto; }
1146
+ }
1147
+
1148
+ /* ============================ TABS ============================ */
1149
+ /* Mono caps on a shared hairline; the selected tab re-inks and takes a 2px
1150
+ brass underline. A tab is a place, not a press, so it stays flat. */
1151
+ .bevel-tabs { display: flex; gap: 2px; border-bottom: 1px solid var(--bevel-line); overflow-x: auto; scrollbar-width: thin; }
1152
+ .bevel-tabs__tab {
1153
+ appearance: none; border: 0; background: none; cursor: pointer; white-space: nowrap;
1154
+ font-family: var(--bevel-font-mono); font-size: 11.5px; font-weight: 500; line-height: 1.5;
1155
+ letter-spacing: .09em; text-transform: uppercase; color: var(--bevel-muted);
1156
+ padding: 10px 12px 9px; margin-bottom: -1px; border-bottom: 2px solid transparent;
1157
+ transition: color .14s, border-color .14s;
1158
+ }
1159
+ .bevel-tabs__tab:hover { color: var(--bevel-ink); }
1160
+ .bevel-tabs__tab[aria-selected="true"] { color: var(--bevel-ink); border-bottom-color: var(--bevel-brass); }
1161
+ .bevel-tabs__tab:focus-visible { outline: 2px solid var(--bevel-brass); outline-offset: -2px; }
1162
+ .bevel-tabpanel { padding-top: 16px; }
1163
+ .bevel-tabpanel[hidden] { display: none; }
1164
+
1165
+ /* ============================ DETAILS ============================ */
1166
+ /* A boxed stack of drawers. The summary is pressable, so it carries a
1167
+ beveled latch that takes the checked recess while the drawer is open, and
1168
+ the open body is a sunk panel directly under it, edge to edge, so every
1169
+ line meets the box. Native details, so it works without script and the
1170
+ open attribute round-trips. Body text aligns with the summary text. */
1171
+ .bevel-details { background: var(--bevel-surface); border: 1px solid var(--bevel-line); border-radius: 0; }
1172
+ .bevel-details + .bevel-details { border-top: 0; }
1173
+ .bevel-details[open] + .bevel-details { border-top: 1px solid var(--bevel-line); }
1174
+ .bevel-details > summary {
1175
+ list-style: none; cursor: pointer; position: relative; user-select: none;
1176
+ display: flex; align-items: center; gap: 12px; padding: 10px 14px 10px 12px;
1177
+ font-size: 15.5px; font-weight: 600; line-height: 1.5; color: var(--bevel-ink);
1178
+ }
1179
+ .bevel-details > summary::-webkit-details-marker { display: none; }
1180
+ .bevel-details > summary:hover { background: color-mix(in srgb, var(--bevel-sunk) 55%, var(--bevel-surface)); }
1181
+ .bevel-details > summary::before {
1182
+ content: ""; flex-shrink: 0; width: 22px; height: 22px;
1183
+ background: var(--bevel-face); border: 2px solid;
1184
+ border-color: var(--bevel-edge-hi) var(--bevel-edge-lo) var(--bevel-edge-lo) var(--bevel-edge-hi);
1185
+ }
1186
+ /* The chevron sits on the latch and points where the body will open. */
1187
+ .bevel-details > summary::after {
1188
+ content: ""; position: absolute; left: 23px; top: 50%; width: 6px; height: 6px;
1189
+ border-right: 1.5px solid var(--bevel-ink); border-bottom: 1.5px solid var(--bevel-ink);
1190
+ transform: translate(-65%, -50%) rotate(-45deg); transition: transform .14s;
1191
+ }
1192
+ .bevel-details[open] > summary::before {
1193
+ background: var(--bevel-face-in);
1194
+ border-color: var(--bevel-edge-in) var(--bevel-edge-in-hi) var(--bevel-edge-in-hi) var(--bevel-edge-in);
1195
+ }
1196
+ .bevel-details[open] > summary::after { transform: translate(calc(-50% + 1px), calc(-65% + 1px)) rotate(45deg); }
1197
+ .bevel-details > summary:focus-visible { outline: 2px solid var(--bevel-brass); outline-offset: -2px; }
1198
+ .bevel-details__body {
1199
+ padding: 12px 16px 14px 46px; border-top: 1px solid var(--bevel-line);
1200
+ background: var(--bevel-sunk); font-size: 15.5px; line-height: 1.55; color: var(--bevel-ink-2);
1201
+ }
1202
+ .bevel-details__body p { margin: 0; }
1203
+ .bevel-details__body p + p { margin-top: 8px; }
1204
+
1205
+ /* ============================ SEGMENTED ============================ */
1206
+ /* Adjacent bevel buttons; the pressed one takes the checked recess. */
1207
+ .bevel-seg { display: inline-flex; }
1208
+ .bevel-seg > .bevel-button { font-family: var(--bevel-font-mono); font-size: 11px; font-weight: 500; letter-spacing: .1em; text-transform: uppercase; padding: 6px 12px; }
1209
+ .bevel-seg > .bevel-button + .bevel-button { margin-left: -2px; }
1210
+ .bevel-seg > .bevel-button[aria-pressed="true"] {
1211
+ background: var(--bevel-face-in);
1212
+ border-color: var(--bevel-edge-in) var(--bevel-edge-in-hi) var(--bevel-edge-in-hi) var(--bevel-edge-in);
1213
+ color: var(--bevel-ink); position: relative; z-index: 1;
1214
+ }
1215
+ .bevel-seg > .bevel-button[aria-pressed="true"] .bevel-button__label { translate: 1px 1px; }
1216
+
1217
+ /* ============================ STEPS ============================ */
1218
+ .bevel-steps { list-style: none; margin: 0; padding: 0; position: relative; }
1219
+ .bevel-steps::before { content: ""; position: absolute; left: 12px; top: 8px; bottom: 8px; width: 1px; background: var(--bevel-line); }
1220
+ .bevel-steps > li { position: relative; padding: 0 0 22px 44px; counter-increment: bevel-step; }
1221
+ .bevel-steps > li:last-child { padding-bottom: 0; }
1222
+ .bevel-steps > li::before {
1223
+ content: counter(bevel-step); position: absolute; left: 0; top: 0; width: 25px; height: 25px;
1224
+ display: flex; align-items: center; justify-content: center;
1225
+ font-family: var(--bevel-font-mono); font-size: 11.5px; font-weight: 600;
1226
+ background: var(--bevel-surface); border: 1px solid var(--bevel-line-2); color: var(--bevel-muted);
1227
+ }
1228
+ .bevel-steps > li.done::before { content: "\2713"; background: var(--bevel-teal-soft); border-color: color-mix(in srgb, var(--bevel-teal) 40%, var(--bevel-teal-soft)); color: var(--bevel-teal); }
1229
+ .bevel-steps > li.now::before { border-color: var(--bevel-brass); color: var(--bevel-brass); box-shadow: 0 0 0 2px var(--bevel-brass-soft); }
1230
+ .bevel-steps > li h4 { margin: 0; font-family: var(--bevel-font-sans); font-size: 16px; font-weight: 600; line-height: 1.5; }
1231
+ .bevel-steps > li.now h4::after { content: "now"; margin-left: 10px; font-family: var(--bevel-font-mono); font-size: 10px; font-weight: 600; letter-spacing: .12em; text-transform: uppercase; color: var(--bevel-brass); }
1232
+ .bevel-steps > li p { margin: 3px 0 0; font-size: 15px; color: var(--bevel-muted); }
1233
+ .bevel-steps > li:not(.done):not(.now) h4 { color: var(--bevel-muted); }
1234
+
1235
+ /* ============================ TIP, KBD ============================ */
1236
+ .bevel-tip { font-style: normal; text-decoration: underline dotted; text-decoration-color: var(--bevel-faint); text-underline-offset: 3px; cursor: help; position: relative; }
1237
+ .bevel-tip::after {
1238
+ content: attr(data-tip); position: absolute; bottom: calc(100% + 8px); left: 50%; transform: translateX(-50%);
1239
+ background: var(--bevel-ink); color: var(--bevel-ground);
1240
+ font-family: var(--bevel-font-mono); font-size: 11px; font-weight: 500; letter-spacing: .02em;
1241
+ padding: 5px 9px; white-space: nowrap; opacity: 0; pointer-events: none; transition: opacity .14s; z-index: 5;
1242
+ }
1243
+ .bevel-tip:hover::after, .bevel-tip:focus-visible::after { opacity: 1; }
1244
+ .bevel-kbd, .bevel-page :where(kbd) {
1245
+ font-family: var(--bevel-font-mono); font-size: 11px; font-weight: 500; line-height: 1;
1246
+ background: var(--bevel-sunk); border: 1px solid var(--bevel-line-2); border-radius: 0;
1247
+ padding: 2.5px 5.5px; color: var(--bevel-muted); white-space: nowrap;
1248
+ }
1249
+
1250
+ /* ============================ EYEBROW, KICKER, PROSE ============================ */
1251
+ .bevel-eyebrow {
1252
+ display: flex; justify-content: space-between; align-items: baseline; gap: 16px; margin: 0;
1253
+ font-family: var(--bevel-font-mono); font-size: 11px; font-weight: 500;
1254
+ letter-spacing: .17em; text-transform: uppercase; color: var(--bevel-brass);
1255
+ padding-bottom: 9px; border-bottom: 1px solid var(--bevel-line);
1256
+ }
1257
+ .bevel-eyebrow span { color: var(--bevel-faint); letter-spacing: .09em; }
1258
+ .bevel-eyebrow--bare { border-bottom: 0; padding-bottom: 0; display: block; }
1259
+ .bevel-kicker { margin: 0; font-family: var(--bevel-font-mono); font-size: 11.5px; font-weight: 500; letter-spacing: .16em; text-transform: uppercase; color: var(--bevel-muted); }
1260
+ .bevel-lede { font-size: 18.5px; line-height: 1.58; color: var(--bevel-ink-2); }
1261
+ .bevel-measure { max-width: 70ch; }
1262
+ .bevel-pull {
1263
+ font-family: var(--bevel-font-serif); font-size: clamp(22px, 3vw, 27px); font-style: italic; font-weight: 400;
1264
+ line-height: 1.35; letter-spacing: -.012em; color: var(--bevel-ink); text-wrap: balance; margin: 0;
1265
+ border-top: 1px solid var(--bevel-line); border-bottom: 1px solid var(--bevel-line); padding: 26px 0;
1266
+ }
1267
+ .bevel-pull cite { display: block; margin-top: 12px; font-family: var(--bevel-font-mono); font-size: 11px; font-weight: 500; letter-spacing: .13em; text-transform: uppercase; color: var(--bevel-muted); font-style: normal; }
1268
+
1269
+ /* ============================ MASTHEAD, VERDICT ============================ */
1270
+ .bevel-mast { border-bottom: 1px solid var(--bevel-line); padding: 46px 0 30px; }
1271
+ .bevel-mast__row { display: flex; justify-content: space-between; align-items: center; gap: 16px; flex-wrap: wrap; }
1272
+ .bevel-mast h1 { margin: 14px 0 0; font-family: var(--bevel-font-serif); font-weight: 500; font-size: clamp(38px, 5.6vw, 62px); line-height: 1.02; letter-spacing: -.022em; text-wrap: balance; }
1273
+ .bevel-mast h1 em { font-style: normal; font-weight: 600; }
1274
+ .bevel-mast__dek { margin: 20px 0 0; font-size: 18.5px; line-height: 1.58; color: var(--bevel-ink-2); max-width: 62ch; }
1275
+ .bevel-mast__tape { display: flex; flex-wrap: wrap; gap: 0; margin: 30px 0 0; border: 1px solid var(--bevel-line); border-radius: 0; overflow: hidden; background: var(--bevel-surface); }
1276
+ .bevel-mast__tape > div { flex: 1 1 128px; padding: 12px 16px; border-right: 1px solid var(--bevel-line); }
1277
+ .bevel-mast__tape > div:last-child { border-right: 0; }
1278
+ .bevel-mast__tape dt { margin: 0; font-family: var(--bevel-font-mono); font-size: 10.5px; letter-spacing: .13em; text-transform: uppercase; color: var(--bevel-faint); }
1279
+ .bevel-mast__tape dd { margin: 3px 0 0; font-family: var(--bevel-font-mono); font-size: 19px; font-weight: 500; letter-spacing: -.02em; }
1280
+ .bevel-mast__tape dd small { font-size: 12px; font-weight: 400; color: var(--bevel-muted); letter-spacing: 0; }
1281
+ .bevel-mast__tape .dn { color: var(--bevel-ox); }
1282
+ .bevel-verdict { background: var(--bevel-surface); border: 1px solid var(--bevel-line); border-radius: 0; padding: 30px 32px; box-shadow: var(--bevel-shadow); }
1283
+ .bevel-verdict h2 { margin: 0 0 14px; font-family: var(--bevel-font-serif); font-weight: 500; font-size: 27px; line-height: 1.2; letter-spacing: -.015em; text-wrap: balance; }
1284
+ .bevel-verdict p { margin: 0; max-width: 74ch; }
1285
+ .bevel-verdict p + p { margin-top: 13px; }
1286
+ .bevel-card { background: var(--bevel-surface); border: 1px solid var(--bevel-line); border-radius: 0; padding: 20px 22px; box-shadow: var(--bevel-shadow); }
1287
+
1288
+ /* ============================ PAGE ============================ */
1289
+ /* The scaffold: bevel-page on <body> gives a centered column and the
1290
+ typographic defaults. Every rule rides :where() (zero specificity) so any
1291
+ class beats it. Flow rhythm targets direct children only. */
1292
+ .bevel-page { max-width: 768px; margin-inline: auto; padding: 48px 24px 96px; }
1293
+ .bevel-page--wide { max-width: 1080px; }
1294
+ .bevel-page :where(h1, h2, h3, h4) { margin: 0; font-family: var(--bevel-font-serif); font-weight: 400; line-height: 1.15; text-wrap: balance; }
1295
+ .bevel-page :where(h1) { font-size: clamp(32px, 4.4vw, 44px); line-height: 1.1; letter-spacing: -.012em; }
1296
+ .bevel-page :where(h2) { font-size: 29px; line-height: 1.18; letter-spacing: -.016em; }
1297
+ .bevel-page :where(h3) { font-size: 20px; font-weight: 500; line-height: 1.3; letter-spacing: -.01em; }
1298
+ .bevel-page :where(h4) { font-family: var(--bevel-font-sans); font-size: 16px; font-weight: 600; line-height: 1.5; }
1299
+ .bevel-page :where(h1 em, h2 em, h3 em) { font-style: normal; font-weight: 600; }
1300
+ .bevel-page :where(p) { margin: 0; text-wrap: pretty; }
1301
+ .bevel-page :where(p + p) { margin-block-start: 13px; }
1302
+ .bevel-page :where(a) { color: var(--bevel-brass); text-underline-offset: 3px; text-decoration-thickness: 1px; text-decoration-color: color-mix(in srgb, var(--bevel-brass) 40%, transparent); transition: text-decoration-color .14s; }
1303
+ .bevel-page :where(a:hover) { text-decoration-color: var(--bevel-brass); }
1304
+ .bevel-page :where(b, strong) { font-weight: 600; color: var(--bevel-ink); }
1305
+ .bevel-page :where(code) { font-family: var(--bevel-font-mono); font-size: .85em; padding: 1px 5px; background: var(--bevel-sunk); border: 1px solid var(--bevel-line); color: var(--bevel-ink); }
1306
+ .bevel-page :where(pre) { margin: 0; padding: 14px 16px; font-family: var(--bevel-font-mono); font-size: 13px; line-height: 1.55; overflow-x: auto; background: var(--bevel-sunk); border: 1px solid var(--bevel-line); color: var(--bevel-ink); scrollbar-width: thin; }
1307
+ .bevel-page :where(pre code) { padding: 0; border: 0; background: none; font-size: inherit; }
1308
+ .bevel-page :where(hr) { border: 0; border-top: 1px solid var(--bevel-line); margin: 0; }
1309
+ .bevel-page :where(blockquote) { margin: 0; padding: 2px 0 2px 16px; border-left: 2px solid var(--bevel-line-2); color: var(--bevel-ink-2); }
1310
+
1311
+ .bevel-page > :where(* + *) { margin-block-start: 14px; }
1312
+ .bevel-page > :where(h1, h2, h3, h4):where(* + *) { margin-block-start: 40px; }
1313
+ .bevel-page > :where(section + section) { margin-block-start: 56px; }
1314
+ .bevel-page > :where(.bevel-eyebrow + *), .bevel-page > :where(* + .bevel-hint) { margin-block-start: 8px; }
1315
+ .bevel-page > :where(.bevel-mast + *) { margin-block-start: 44px; }
1316
+ .bevel-page > :where(.bevel-verdict + *) { margin-block-start: 56px; }
1317
+ .bevel-section > :where(* + *) { margin-block-start: 14px; }
1318
+ .bevel-section > :where(.bevel-eyebrow + *) { margin-block-start: 22px; }
1319
+ .bevel-section > :where(h3):where(* + *) { margin-block-start: 30px; }
1320
+ .bevel-section > :where(h3 + *) { margin-block-start: 9px; }
1321
+ }
1322
+
1323
+ /* Respect the machine. Unlayered, so it beats every layered rule without !important. */
1324
+ @media (prefers-reduced-motion: reduce) {
1325
+ *, ::before, ::after { transition-duration: .01ms; animation-duration: .01ms; animation-iteration-count: 1; }
1326
+ .bevel-button:active .bevel-button__label { translate: none; }
1327
+ }
1328
+ @media (forced-colors: active) {
1329
+ .bevel-button, .bevel-checkbox__box, .bevel-radio__ring, .bevel-toggle__track, .bevel-slider__nub, .bevel-tags__chip, .bevel-details > summary::before, .bevel-grid__expand, .bevel-grid__more { border: 1px solid ButtonText; }
1330
+ .bevel-radio__ring::after { background: ButtonText; }
1331
+ .bevel-progress { forced-color-adjust: none; background: Canvas; border: 1px solid ButtonText; }
1332
+ .bevel-progress::-webkit-progress-bar { background: Canvas; }
1333
+ .bevel-progress::-webkit-progress-value, .bevel-progress::-moz-progress-bar { background: ButtonText; }
1334
+ }
1335
+ @media print {
1336
+ :root { color-scheme: light; --bevel-shadow: none; }
1337
+ .bevel-page { max-width: none; padding: 0; }
1338
+ .bevel-verdict, .bevel-note, .bevel-card, .bevel-scroll { break-inside: avoid; }
1339
+ }