@ethlete/components 1.0.0-next.77 → 1.0.0-next.79

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 (318) hide show
  1. package/CHANGELOG.md +119 -0
  2. package/design/accordion.ts +73 -0
  3. package/design/avatar.ts +90 -0
  4. package/design/badge.ts +48 -0
  5. package/design/banner.ts +77 -0
  6. package/design/bracket.ts +457 -0
  7. package/design/breadcrumb.ts +145 -0
  8. package/design/button.ts +49 -0
  9. package/design/calendar.ts +306 -0
  10. package/design/card.ts +92 -0
  11. package/design/carousel.ts +240 -0
  12. package/design/chart.ts +512 -0
  13. package/design/checkbox.ts +275 -0
  14. package/design/chip.ts +64 -0
  15. package/design/config.json +22 -0
  16. package/design/control.ts +19 -0
  17. package/design/copy-button.ts +59 -0
  18. package/design/description-list.ts +41 -0
  19. package/design/dialog.ts +214 -0
  20. package/design/divider.ts +27 -0
  21. package/design/empty-state.ts +45 -0
  22. package/design/floating-action.ts +55 -0
  23. package/design/form-field.ts +40 -1
  24. package/design/grid.ts +148 -0
  25. package/design/icon-set.ts +19 -0
  26. package/design/icon.ts +9 -0
  27. package/design/input.ts +86 -0
  28. package/design/kbd.ts +19 -0
  29. package/design/loader.ts +152 -0
  30. package/design/masonry.ts +115 -0
  31. package/design/match.ts +131 -0
  32. package/design/menu.ts +143 -0
  33. package/design/notification.ts +129 -0
  34. package/design/otp-input.ts +107 -0
  35. package/design/pagination.ts +120 -0
  36. package/design/picture.ts +80 -0
  37. package/design/progress-steps.ts +79 -0
  38. package/design/query-error.ts +60 -0
  39. package/design/radio-group.ts +132 -0
  40. package/design/scheduler.ts +369 -0
  41. package/design/scrollable.ts +218 -0
  42. package/design/scrollbar.ts +47 -0
  43. package/design/sdk/assets/fallback.svg +1 -0
  44. package/design/sdk/assets/tall.svg +1 -0
  45. package/design/sdk/assets/wide.svg +1 -0
  46. package/design/sdk/components/accent-on-light/accent-on-light.css +35 -0
  47. package/design/sdk/components/accent-on-light/accent-on-light.ts +10 -0
  48. package/design/sdk/components/accent-on-light/shared/controls.ts +46 -0
  49. package/design/sdk/components/accordion/accordion.css +17 -0
  50. package/design/sdk/components/accordion/accordion.ts +64 -0
  51. package/design/sdk/components/avatar/avatar.css +14 -0
  52. package/design/sdk/components/avatar/avatar.ts +78 -0
  53. package/design/sdk/components/badge/badge.css +13 -0
  54. package/design/sdk/components/badge/badge.ts +52 -0
  55. package/design/sdk/components/banner/banner.css +18 -0
  56. package/design/sdk/components/banner/banner.ts +87 -0
  57. package/design/sdk/components/bracket/bracket.css +59 -0
  58. package/design/sdk/components/bracket/bracket.ts +143 -0
  59. package/design/sdk/components/breadcrumb/breadcrumb.css +25 -0
  60. package/design/sdk/components/breadcrumb/breadcrumb.ts +81 -0
  61. package/design/sdk/components/button/button.css +33 -0
  62. package/design/sdk/components/button/button.ts +82 -0
  63. package/design/sdk/components/calendar/calendar.css +33 -0
  64. package/design/sdk/components/calendar/calendar.ts +96 -0
  65. package/design/sdk/components/card/card.css +19 -0
  66. package/design/sdk/components/card/card.ts +61 -0
  67. package/design/sdk/components/carousel/carousel.css +44 -0
  68. package/design/sdk/components/carousel/carousel.ts +74 -0
  69. package/design/sdk/components/chart/chart.css +56 -0
  70. package/design/sdk/components/chart/chart.ts +98 -0
  71. package/design/sdk/components/chip/chip.css +18 -0
  72. package/design/sdk/components/chip/chip.ts +76 -0
  73. package/design/sdk/components/copy-button/copy-button.css +14 -0
  74. package/design/sdk/components/copy-button/copy-button.ts +59 -0
  75. package/design/sdk/components/description-list/description-list.css +7 -0
  76. package/design/sdk/components/description-list/description-list.ts +53 -0
  77. package/design/sdk/components/dialog/dialog.css +29 -0
  78. package/design/sdk/components/dialog/dialog.ts +78 -0
  79. package/design/sdk/components/divider/divider.css +26 -0
  80. package/design/sdk/components/divider/divider.ts +43 -0
  81. package/design/sdk/components/empty-state/empty-state.css +15 -0
  82. package/design/sdk/components/empty-state/empty-state.ts +56 -0
  83. package/design/sdk/components/floating-action/floating-action.css +51 -0
  84. package/design/sdk/components/floating-action/floating-action.ts +63 -0
  85. package/design/sdk/components/form-field/form-field.ts +118 -0
  86. package/design/sdk/components/grid/grid.css +17 -0
  87. package/design/sdk/components/grid/grid.ts +80 -0
  88. package/design/sdk/components/input/input.css +75 -0
  89. package/design/sdk/components/input/input.ts +79 -0
  90. package/design/sdk/components/kbd/kbd.css +25 -0
  91. package/design/sdk/components/kbd/kbd.ts +57 -0
  92. package/design/sdk/components/loader/loader.css +37 -0
  93. package/design/sdk/components/loader/loader.ts +68 -0
  94. package/design/sdk/components/masonry/masonry.css +7 -0
  95. package/design/sdk/components/masonry/masonry.ts +42 -0
  96. package/design/sdk/components/match/match.css +25 -0
  97. package/design/sdk/components/match/match.ts +76 -0
  98. package/design/sdk/components/menu/menu.css +22 -0
  99. package/design/sdk/components/menu/menu.ts +91 -0
  100. package/design/sdk/components/notification/notification.css +32 -0
  101. package/design/sdk/components/notification/notification.ts +106 -0
  102. package/design/sdk/components/otp-input/otp-input.css +35 -0
  103. package/design/sdk/components/otp-input/otp-input.ts +64 -0
  104. package/design/sdk/components/pagination/pagination.css +14 -0
  105. package/design/sdk/components/pagination/pagination.ts +75 -0
  106. package/design/sdk/components/picture/picture.css +37 -0
  107. package/design/sdk/components/picture/picture.ts +96 -0
  108. package/design/sdk/components/progress-steps/progress-steps.css +37 -0
  109. package/design/sdk/components/progress-steps/progress-steps.ts +91 -0
  110. package/design/sdk/components/query-error/query-error.css +33 -0
  111. package/design/sdk/components/query-error/query-error.ts +120 -0
  112. package/design/sdk/components/scheduler/scheduler.css +55 -0
  113. package/design/sdk/components/scheduler/scheduler.ts +239 -0
  114. package/design/sdk/components/scrollable/scrollable.css +58 -0
  115. package/design/sdk/components/scrollable/scrollable.ts +133 -0
  116. package/design/sdk/components/scrollbar/scrollbar.css +78 -0
  117. package/design/sdk/components/scrollbar/scrollbar.ts +123 -0
  118. package/design/sdk/components/select/select.css +5 -0
  119. package/design/sdk/components/select/select.ts +16 -0
  120. package/design/sdk/components/select/shared/select-part.ts +75 -0
  121. package/design/sdk/components/select-panel/select-panel.css +3 -0
  122. package/design/sdk/components/select-panel/select-panel.ts +124 -0
  123. package/design/sdk/components/skeleton/skeleton.css +22 -0
  124. package/design/sdk/components/skeleton/skeleton.ts +50 -0
  125. package/design/sdk/components/slider/slider.css +52 -0
  126. package/design/sdk/components/slider/slider.ts +86 -0
  127. package/design/sdk/components/standings/standings.css +33 -0
  128. package/design/sdk/components/standings/standings.ts +130 -0
  129. package/design/sdk/components/stat-tile/stat-tile.css +15 -0
  130. package/design/sdk/components/stat-tile/stat-tile.ts +84 -0
  131. package/design/sdk/components/stream/stream.css +48 -0
  132. package/design/sdk/components/stream/stream.ts +38 -0
  133. package/design/sdk/components/switch/switch.css +35 -0
  134. package/design/sdk/components/switch/switch.ts +63 -0
  135. package/design/sdk/components/table/table.css +67 -0
  136. package/design/sdk/components/table/table.ts +160 -0
  137. package/design/sdk/components/tabs/tabs.css +13 -0
  138. package/design/sdk/components/tabs/tabs.ts +74 -0
  139. package/design/sdk/components/textarea/textarea.css +116 -0
  140. package/design/sdk/components/textarea/textarea.ts +64 -0
  141. package/design/sdk/components/timeline/timeline.css +30 -0
  142. package/design/sdk/components/timeline/timeline.ts +87 -0
  143. package/design/sdk/components/toolbar/toolbar.css +24 -0
  144. package/design/sdk/components/toolbar/toolbar.ts +87 -0
  145. package/design/sdk/components/tooltip/tooltip.css +15 -0
  146. package/design/sdk/components/tooltip/tooltip.ts +28 -0
  147. package/design/sdk/components/tree/selected-tint.css +15 -0
  148. package/design/sdk/components/tree/tree.ts +70 -0
  149. package/design/sdk/fixtures.ts +0 -0
  150. package/design/sdk/foundations/colors/colors.css +632 -0
  151. package/design/sdk/foundations/colors/colors.ts +188 -0
  152. package/design/sdk/foundations/colors/overrides.json +19 -0
  153. package/design/sdk/foundations/colors/shared/contrast.ts +120 -0
  154. package/design/sdk/foundations/elevation/elevation.css +6 -0
  155. package/design/sdk/foundations/elevation/elevation.ts +11 -0
  156. package/design/sdk/foundations/elevation/shared/elevation/scene.css +101 -0
  157. package/design/sdk/foundations/elevation/shared/elevation/scene.ts +74 -0
  158. package/design/sdk/foundations/icons/icons.ts +119 -0
  159. package/design/select.ts +113 -28
  160. package/design/skeleton.ts +67 -0
  161. package/design/slider.ts +155 -0
  162. package/design/standings.ts +161 -0
  163. package/design/stat-tile.ts +109 -0
  164. package/design/stream.ts +92 -0
  165. package/design/switch.ts +83 -0
  166. package/design/table.ts +302 -0
  167. package/design/tabs.ts +75 -0
  168. package/design/textarea.ts +92 -0
  169. package/design/timeline.ts +52 -0
  170. package/design/toolbar.ts +95 -0
  171. package/design/tooltip.ts +87 -0
  172. package/design/tree.ts +106 -0
  173. package/fesm2022/ethlete-components.mjs +240 -199
  174. package/fesm2022/ethlete-components.mjs.map +1 -1
  175. package/package.json +1 -1
  176. package/src/lib/accordion/accordion.component.css +2 -1
  177. package/src/lib/avatar/avatar.component.css +10 -0
  178. package/src/lib/badge/badge.component.css +2 -2
  179. package/src/lib/banner/banner.component.css +3 -1
  180. package/src/lib/breadcrumb/breadcrumb-outlet.component.css +5 -0
  181. package/src/lib/breadcrumb/breadcrumb.component.css +5 -1
  182. package/src/lib/button/button.component.css +19 -0
  183. package/src/lib/button/icon-button.component.css +19 -20
  184. package/src/lib/button/split-button.component.css +5 -1
  185. package/src/lib/calendar/calendar.component.css +13 -3
  186. package/src/lib/card/card.component.css +4 -0
  187. package/src/lib/carousel/carousel-autoplay-styles.component.css +1 -1
  188. package/src/lib/carousel/carousel.component.css +2 -2
  189. package/src/lib/chart/chart-axis.component.css +3 -3
  190. package/src/lib/chip/chip.component.css +8 -2
  191. package/src/lib/description-list/description-list.component.css +2 -1
  192. package/src/lib/empty-state/empty-state.component.css +4 -0
  193. package/src/lib/floating-action/floating-action-styles.component.css +27 -0
  194. package/src/lib/focus-ring/focus-ring-styles.component.css +4 -1
  195. package/src/lib/forms/checkbox/checkbox.component.css +31 -5
  196. package/src/lib/forms/color-input/color-input.component.css +3 -1
  197. package/src/lib/forms/color-input/color-picker-panel.component.css +6 -2
  198. package/src/lib/forms/date-time/date-input/date-input.component.css +1 -1
  199. package/src/lib/forms/date-time/date-time-input/date-time-input.component.css +1 -1
  200. package/src/lib/forms/date-time/duration-input/duration-input.component.css +1 -1
  201. package/src/lib/forms/date-time/range-input-shell-styles.component.css +1 -1
  202. package/src/lib/forms/date-time/time-input/time-input.component.css +1 -1
  203. package/src/lib/forms/description/description.component.css +7 -0
  204. package/src/lib/forms/dropzone/dropzone.component.css +26 -0
  205. package/src/lib/forms/form-field/form-field-control-suffix-styles.component.css +4 -2
  206. package/src/lib/forms/form-field/form-field-text-shell-styles.component.css +74 -17
  207. package/src/lib/forms/form-field/form-field-textarea-styles.component.css +62 -0
  208. package/src/lib/forms/form-field/form-field.component.css +6 -0
  209. package/src/lib/forms/form-field/headless/label.directive.css +1 -1
  210. package/src/lib/forms/input/input.component.css +6 -2
  211. package/src/lib/forms/input/number-input.component.css +2 -2
  212. package/src/lib/forms/input/password-input.component.css +4 -3
  213. package/src/lib/forms/otp-input/otp-input.component.css +23 -4
  214. package/src/lib/forms/phone-input/phone-input.component.css +4 -3
  215. package/src/lib/forms/rating/rating.component.css +2 -1
  216. package/src/lib/forms/rich-text-editor/rich-text-editor.component.css +1 -1
  217. package/src/lib/forms/select/select-option-styles.component.css +3 -2
  218. package/src/lib/forms/selection-card-styles.component.css +3 -2
  219. package/src/lib/forms/selection-list/checkbox-group/checkbox-group-select-all.component.css +4 -2
  220. package/src/lib/forms/selection-list/checkbox-group/checkbox-option.component.css +4 -2
  221. package/src/lib/forms/selection-list/radio-group/radio.component.css +5 -2
  222. package/src/lib/forms/selection-list/segmented-button-group/segmented-button.component.css +2 -1
  223. package/src/lib/forms/slider/range-slider.component.css +98 -6
  224. package/src/lib/forms/slider/slider.component.css +96 -4
  225. package/src/lib/forms/switch/switch.component.css +47 -4
  226. package/src/lib/forms/tag-input/tag-input.component.css +2 -2
  227. package/src/lib/forms/textarea/textarea-autosize-styles.component.css +2 -3
  228. package/src/lib/forms/textarea/textarea.component.css +7 -2
  229. package/src/lib/grid/grid-item-toolbar.component.css +10 -0
  230. package/src/lib/grid/grid-item.component.css +6 -1
  231. package/src/lib/icon/headless/align-icons.ts +30 -0
  232. package/src/lib/icon/headless/arrow-out-up-right-icon.ts +17 -0
  233. package/src/lib/icon/headless/arrow-right-icon.ts +23 -0
  234. package/src/lib/icon/headless/arrow-up-icon.ts +30 -0
  235. package/src/lib/icon/headless/arrows-left-right-icon.ts +31 -0
  236. package/src/lib/icon/headless/bold-icon.ts +11 -0
  237. package/src/lib/icon/headless/calendar-icon.ts +21 -0
  238. package/src/lib/icon/headless/check-icon.ts +14 -0
  239. package/src/lib/icon/headless/chevron-icon.ts +14 -0
  240. package/src/lib/icon/headless/circle-check-icon.ts +14 -0
  241. package/src/lib/icon/headless/circle-info-icon.ts +14 -0
  242. package/src/lib/icon/headless/clipboard-check-icon.ts +28 -0
  243. package/src/lib/icon/headless/clock-icon.ts +21 -0
  244. package/src/lib/icon/headless/code-block-icon.ts +15 -0
  245. package/src/lib/icon/headless/code-icon.ts +14 -0
  246. package/src/lib/icon/headless/ellipsis-icon.ts +13 -0
  247. package/src/lib/icon/headless/ellipsis-vertical-icon.ts +13 -0
  248. package/src/lib/icon/headless/eye-icons.ts +27 -0
  249. package/src/lib/icon/headless/eyedropper-icon.ts +22 -0
  250. package/src/lib/icon/headless/file-icon.ts +16 -0
  251. package/src/lib/icon/headless/filter-icon.ts +11 -0
  252. package/src/lib/icon/headless/floppy-disk-icon.ts +27 -0
  253. package/src/lib/icon/headless/focus-frame-icon.ts +16 -0
  254. package/src/lib/icon/headless/grid-2x2-icon.ts +17 -0
  255. package/src/lib/icon/headless/heading-1-icon.ts +11 -0
  256. package/src/lib/icon/headless/heading-2-icon.ts +11 -0
  257. package/src/lib/icon/headless/heading-3-icon.ts +11 -0
  258. package/src/lib/icon/headless/icon-definition.ts +14 -0
  259. package/src/lib/icon/headless/image-icon.ts +14 -0
  260. package/src/lib/icon/headless/italic-icon.ts +19 -0
  261. package/src/lib/icon/headless/link-icon.ts +17 -0
  262. package/src/lib/icon/headless/list-bulleted-icon.ts +14 -0
  263. package/src/lib/icon/headless/list-numbered-icon.ts +14 -0
  264. package/src/lib/icon/headless/location-icon.ts +21 -0
  265. package/src/lib/icon/headless/lock-icon.ts +14 -0
  266. package/src/lib/icon/headless/minus-icon.ts +14 -0
  267. package/src/lib/icon/headless/paragraph-icon.ts +11 -0
  268. package/src/lib/icon/headless/pause-icon.ts +11 -0
  269. package/src/lib/icon/headless/pencil-icon.ts +21 -0
  270. package/src/lib/icon/headless/play-icon.ts +10 -0
  271. package/src/lib/icon/headless/plus-icon.ts +21 -0
  272. package/src/lib/icon/headless/quote-icon.ts +15 -0
  273. package/src/lib/icon/headless/rotate-right-icon.ts +16 -0
  274. package/src/lib/icon/headless/star-icon.ts +14 -0
  275. package/src/lib/icon/headless/strikethrough-icon.ts +18 -0
  276. package/src/lib/icon/headless/table-icon.ts +15 -0
  277. package/src/lib/icon/headless/thumbtack-icon.ts +18 -0
  278. package/src/lib/icon/headless/times-icon.ts +14 -0
  279. package/src/lib/icon/headless/trash-icon.ts +24 -0
  280. package/src/lib/icon/headless/triangle-exclamation-icon.ts +14 -0
  281. package/src/lib/icon/headless/trophy-icon.ts +24 -0
  282. package/src/lib/icon/headless/underline-icon.ts +12 -0
  283. package/src/lib/icon/headless/undo-redo-icons.ts +24 -0
  284. package/src/lib/icon/headless/upload-icon.ts +16 -0
  285. package/src/lib/loader/brand-loader/brand-loader.component.css +4 -1
  286. package/src/lib/loader/progress-bar/progress-bar.component.css +1 -1
  287. package/src/lib/loader/spinner/spinner-styles.component.css +1 -1
  288. package/src/lib/match/match-card.component.css +9 -3
  289. package/src/lib/match/match-score.component.css +4 -1
  290. package/src/lib/menu/menu-selection-item.component.css +1 -1
  291. package/src/lib/menu/menu.component.css +5 -0
  292. package/src/lib/overlay/overlay-container.component.css +4 -0
  293. package/src/lib/pagination/pagination.component.css +4 -0
  294. package/src/lib/progress-steps/progress-step.component.css +4 -4
  295. package/src/lib/query-error/query-error.component.css +4 -0
  296. package/src/lib/scheduler/scheduler-appointment-styles.component.css +21 -5
  297. package/src/lib/scheduler/scheduler-month-view.component.css +4 -2
  298. package/src/lib/scheduler/scheduler-time-grid-view.component.css +8 -2
  299. package/src/lib/scrollable/headless/scrollable-navigation.component.css +1 -1
  300. package/src/lib/standings/standings-pick.component.css +1 -1
  301. package/src/lib/standings/standings.component.css +10 -10
  302. package/src/lib/stat-tile/stat-tile-sparkline.component.css +1 -1
  303. package/src/lib/stream/consent/stream-consent.component.css +99 -0
  304. package/src/lib/stream/error/stream-player-error.component.css +100 -0
  305. package/src/lib/stream/loading/stream-player-loading.component.css +16 -0
  306. package/src/lib/stream/pip/pip-slot-placeholder.component.css +68 -0
  307. package/src/lib/stream/stream-player-slot-styles.component.css +4 -0
  308. package/src/lib/table/table-resize-grip.component.css +2 -1
  309. package/src/lib/table/table-select-cell.component.css +45 -15
  310. package/src/lib/table/table.component.css +15 -5
  311. package/src/lib/tabs/tab-bar-styles.component.css +1 -1
  312. package/src/lib/tabs/tabs/tab-group.component.css +111 -0
  313. package/src/lib/time-picker/time-picker.component.css +2 -1
  314. package/src/lib/timeline/timeline-item.component.css +5 -1
  315. package/src/lib/toolbar/toolbar.component.css +4 -0
  316. package/src/lib/tooltip/tooltip.component.css +14 -0
  317. package/src/lib/tree/tree.component.css +2 -2
  318. package/types/ethlete-components.d.ts +62 -53
@@ -0,0 +1,188 @@
1
+ import { definePart, html, tokenSheet, type Drawing } from '@design-system';
2
+ import { contrastSheet, contrastStyles } from './shared/contrast';
3
+ import css from './colors.css?inline';
4
+
5
+ type Surface = 'light' | 'dark';
6
+
7
+ type Theme = 'brand' | 'danger' | 'warning';
8
+
9
+ type Props = { group: 'surface' | 'contrast' | Theme; surface: Surface };
10
+
11
+ const STATE_ENDS = ['', '-hover', '-focus', '-active', '-disabled'];
12
+
13
+ const labelOf = (end: string) => (end ? end.slice(1) : 'rest');
14
+
15
+ const SURFACE_TOKEN =
16
+ /^et-(surface-(background|color(-muted|-subtle)?|border|interaction(-hover|-focus|-active|-disabled)?)|shadow-color-rgb)$/u;
17
+
18
+ const COLOR_TOKEN = /^et-color-(on-)?primary(-ink)?(-hover|-focus|-active|-disabled)?$/u;
19
+
20
+ const TEXT_TOKEN = /^et-surface-(background|color(-muted|-subtle)?)$/u;
21
+
22
+ const themeClassOf = (theme: Theme, surface: Surface) => `et-color--${theme}${surface === 'light' ? '-on-light' : ''}`;
23
+
24
+ const demoNote = (theme: Theme, surface: Surface) =>
25
+ `${theme} is a demo theme of the SDK Storybook (apps/storybook/src/themes.ts); the SDK ships no theme names, each app registers its own.${surface === 'light' ? ` On a light surface the sheet reads .${themeClassOf(theme, surface)}.` : ''}`;
26
+
27
+ const swatch = (token: string) => html`<span class="sdk-swatch" style="background: rgb(var(--${token}))"></span>`;
28
+
29
+ const disabledOf = (name: string) => (name.endsWith('-disabled') ? 'aria-disabled="true"' : '');
30
+
31
+ const ink = (token: string, label = 'Aa') =>
32
+ html`<span class="sdk-ink" ${disabledOf(token)} style="color: rgb(var(--${token}))">${label}</span>`;
33
+
34
+ const surfaceSample = (name: string) => {
35
+ if (name === 'et-shadow-color-rgb') return html`<span class="sdk-swatch sdk-shadow"></span>`;
36
+ if (/^et-surface-color/u.test(name)) return ink(name);
37
+
38
+ return swatch(name);
39
+ };
40
+
41
+ const colorSample = (name: string) => {
42
+ const onFill = /^et-color-on-primary(.*)$/u.exec(name);
43
+ if (onFill)
44
+ return html`<span
45
+ class="sdk-fill"
46
+ ${disabledOf(name)}
47
+ style="background: rgb(var(--et-color-primary${onFill[1]})); color: rgb(var(--${name}))"
48
+ >Aa</span
49
+ >`;
50
+ if (name.startsWith('et-color-primary-ink')) return ink(name, 'Ink');
51
+
52
+ return swatch(name);
53
+ };
54
+
55
+ const surfacePanel = html`<div class="sdk-card">
56
+ <span>Text</span>
57
+ <span class="sdk-muted">Muted text</span>
58
+ <span class="sdk-subtle">Subtle text</span>
59
+ </div>
60
+ <div class="sdk-states">
61
+ ${STATE_ENDS.map(
62
+ (end) =>
63
+ html`<span class="sdk-state"
64
+ ><span class="sdk-swatch" style="background: rgb(var(--et-surface-interaction${end}))"></span
65
+ >${labelOf(end)}</span
66
+ >`,
67
+ ).join('')}
68
+ </div>
69
+ <div class="sdk-elevations">
70
+ <span class="sdk-elevation sdk-shadow-resting">Resting</span>
71
+ <span class="sdk-elevation sdk-shadow-raised">Raised</span>
72
+ </div>`;
73
+
74
+ const themePanel = html`<div class="sdk-states">
75
+ ${STATE_ENDS.map(
76
+ (end) =>
77
+ html`<span
78
+ class="sdk-fill sdk-fill--wide"
79
+ ${disabledOf(end)}
80
+ style="background: rgb(var(--et-color-primary${end})); color: rgb(var(--et-color-on-primary${end}))"
81
+ >${labelOf(end)}</span
82
+ >`,
83
+ ).join('')}
84
+ </div>
85
+ <div class="sdk-states">
86
+ ${STATE_ENDS.map(
87
+ (end) =>
88
+ html`<span class="sdk-link" ${disabledOf(end)} style="color: rgb(var(--et-color-primary-ink${end}))"
89
+ >Ink ${labelOf(end)}</span
90
+ >`,
91
+ ).join('')}
92
+ </div>`;
93
+
94
+ const scopeOf = ({ group, surface }: Props) =>
95
+ group === 'surface' || group === 'contrast'
96
+ ? `sdk-colors et-surface--${surface}`
97
+ : `sdk-colors et-surface--${surface} ${themeClassOf(group, surface)}`;
98
+
99
+ const titleOf = ({ group, surface }: Props) =>
100
+ group === 'surface'
101
+ ? `Surface, ${surface}`
102
+ : group === 'contrast'
103
+ ? `Contrast, ${surface}`
104
+ : `${group} (demo theme) on ${surface}`;
105
+
106
+ const sheetOf = (props: Props) => {
107
+ const { group, surface } = props;
108
+
109
+ if (group === 'surface')
110
+ return tokenSheet({
111
+ title: titleOf(props),
112
+ scope: scopeOf(props),
113
+ css,
114
+ sample: surfacePanel,
115
+ sampleOf: surfaceSample,
116
+ only: (name) => SURFACE_TOKEN.test(name),
117
+ });
118
+ if (group === 'contrast')
119
+ return tokenSheet({
120
+ title: titleOf(props),
121
+ scope: scopeOf(props),
122
+ css,
123
+ sample: contrastSheet(css, surface),
124
+ sampleClass: 'sdk-contrast',
125
+ sampleOf: surfaceSample,
126
+ only: (name) => TEXT_TOKEN.test(name),
127
+ });
128
+
129
+ return tokenSheet({
130
+ title: titleOf(props),
131
+ scope: scopeOf(props),
132
+ note: demoNote(group, surface),
133
+ css,
134
+ sample: themePanel,
135
+ sampleOf: colorSample,
136
+ only: (name) => COLOR_TOKEN.test(name),
137
+ });
138
+ };
139
+
140
+ const STYLES = `
141
+ ${contrastStyles}
142
+ .sdk-colors { --surface: var(--et-surface-background-solid); --text: var(--et-surface-color-solid); --text-muted: var(--et-surface-color-muted-solid); --surface-border: var(--et-surface-border-solid); --font-ui: var(--et-font-family); --font-code: var(--et-font-family-mono); width: max-content; }
143
+ .sdk-colors .ts-row { grid-template-columns: 300px 160px 1fr; }
144
+ section.ts-panel { display: flex; flex-direction: column; gap: 1.2rem; }
145
+ section.ts-panel.sdk-contrast { flex-direction: row; flex-wrap: wrap; gap: 2.4rem; }
146
+ .sdk-table { display: flex; flex-direction: column; gap: 0.8rem; }
147
+ .sdk-title { margin: 0; font-size: 1.4rem; font-weight: 600; }
148
+ .sdk-value { font-family: var(--et-font-family-mono); font-size: 1.2rem; color: var(--et-surface-color-muted-solid); white-space: nowrap; }
149
+ .sdk-card { display: flex; gap: 2.4rem; padding: 1.2rem 1.6rem; border: 0.1rem solid var(--et-surface-border-solid); border-radius: 0.6rem; }
150
+ .sdk-muted { color: var(--et-surface-color-muted-solid); }
151
+ .sdk-subtle { color: var(--et-surface-color-subtle-solid); }
152
+ .sdk-states { display: flex; flex-wrap: wrap; gap: 1.2rem; align-items: center; }
153
+ .sdk-state { display: inline-flex; align-items: center; gap: 0.6rem; font-size: 1.2rem; }
154
+ .sdk-swatch { display: block; width: 4rem; height: 2.4rem; border-radius: 0.4rem; border: 0.1rem solid var(--et-surface-border-solid); }
155
+ .sdk-shadow { background: var(--et-surface-background-solid); box-shadow: 0 0.6rem 1.2rem rgb(var(--et-shadow-color-rgb) / 0.22), 0 0.2rem 0.4rem rgb(var(--et-shadow-color-rgb) / 0.14); }
156
+ .sdk-ink { font-size: 1.6rem; font-weight: 600; }
157
+ .sdk-fill { display: inline-grid; place-items: center; min-width: 4rem; height: 2.4rem; padding: 0 0.8rem; box-sizing: border-box; border-radius: 0.4rem; font-size: 1.2rem; font-weight: 600; }
158
+ .sdk-fill--wide { min-width: 8rem; height: 3.2rem; }
159
+ .sdk-link { min-width: 8rem; font-size: 1.3rem; font-weight: 600; text-decoration: underline; }
160
+ .sdk-elevations { display: flex; gap: 2.4rem; padding: 0.8rem 0; }
161
+ .sdk-elevation { display: grid; place-items: center; width: 12rem; height: 4.8rem; border-radius: 0.6rem; background: var(--et-surface-background-solid); font-size: 1.2rem; }
162
+ .sdk-shadow-resting { box-shadow: 0 0.3rem 0.8rem rgb(var(--et-shadow-color-rgb) / 0.2), 0 0.1rem 0.3rem rgb(var(--et-shadow-color-rgb) / 0.12); }
163
+ .sdk-shadow-raised { box-shadow: 0 0.6rem 1.2rem rgb(var(--et-shadow-color-rgb) / 0.22), 0 0.2rem 0.4rem rgb(var(--et-shadow-color-rgb) / 0.14); }
164
+ `;
165
+
166
+ const render = (props: Props): Drawing => {
167
+ const sheet = sheetOf(props);
168
+
169
+ return { ...sheet, styles: `${sheet.styles ?? ''}${STYLES}` };
170
+ };
171
+
172
+ export default definePart<Props>({
173
+ note: 'The SDK colour tokens: a light and a dark surface, the demo colour themes brand, danger and warning with their on-light variants, and the AA contrast of text and fills. Every frame loads it before the part styles. Generated by tools/scripts/generate-sdk-tokens.mjs from the Storybook themes; never edit the CSS by hand.',
174
+ madeBy: ['claude-opus-5-5'],
175
+ states: {
176
+ 'surface-light': { group: 'surface', surface: 'light' },
177
+ 'surface-dark': { group: 'surface', surface: 'dark' },
178
+ 'brand-light': { group: 'brand', surface: 'light' },
179
+ 'brand-dark': { group: 'brand', surface: 'dark' },
180
+ 'danger-light': { group: 'danger', surface: 'light' },
181
+ 'danger-dark': { group: 'danger', surface: 'dark' },
182
+ 'warning-light': { group: 'warning', surface: 'light' },
183
+ 'warning-dark': { group: 'warning', surface: 'dark' },
184
+ 'contrast-light': { group: 'contrast', surface: 'light' },
185
+ 'contrast-dark': { group: 'contrast', surface: 'dark' },
186
+ },
187
+ render,
188
+ });
@@ -0,0 +1,19 @@
1
+ {
2
+ "extraColorThemes": ["brand-on-light", "danger-on-light", "warning-on-light"],
3
+ "values": {
4
+ "danger": {
5
+ "primary.color.hover": "185 28 28",
6
+ "primary.color.focus": "185 28 28",
7
+ "primary.color.active": "153 27 27"
8
+ },
9
+ "danger-on-light": {
10
+ "primary.color.hover": "185 28 28",
11
+ "primary.color.focus": "185 28 28",
12
+ "primary.color.active": "153 27 27"
13
+ },
14
+ "warning": { "primary.color.active": "251 191 36" },
15
+ "warning-on-light": { "primary.color.active": "251 191 36" },
16
+ "light": { "colorSubtle": "112 112 112" },
17
+ "dark": { "colorSubtle": "135 135 135" }
18
+ }
19
+ }
@@ -0,0 +1,120 @@
1
+ import { html } from '@design-system';
2
+
3
+ type Surface = 'light' | 'dark';
4
+
5
+ const tokenValues = (css: string, selector: string) => {
6
+ const start = css.indexOf(`${selector} {`);
7
+
8
+ if (start === -1) throw new Error(`colors.css has no ${selector} block`);
9
+
10
+ const block = css.slice(start, css.indexOf('}', start));
11
+
12
+ return Object.fromEntries(
13
+ [...block.matchAll(/(--[\w-]+): (\d+ \d+ \d+);/g)].map(([, name, value]) => [name, value as string]),
14
+ ) as Record<string, string>;
15
+ };
16
+
17
+ const channel = (value: number) => {
18
+ const c = value / 255;
19
+
20
+ return c <= 0.03928 ? c / 12.92 : ((c + 0.055) / 1.055) ** 2.4;
21
+ };
22
+
23
+ const luminance = (rgb: string) => {
24
+ const [r = 0, g = 0, b = 0] = rgb.split(' ').map(Number);
25
+
26
+ return 0.2126 * channel(r) + 0.7152 * channel(g) + 0.0722 * channel(b);
27
+ };
28
+
29
+ const contrastRatio = (a: string, b: string) => {
30
+ const [high, low] = [luminance(a), luminance(b)].sort((x, y) => y - x) as [number, number];
31
+
32
+ return (high + 0.05) / (low + 0.05);
33
+ };
34
+
35
+ const AA = 4.5;
36
+
37
+ const pair = (label: string, fill: string, ink: string, fixed: boolean) => {
38
+ const ratio = contrastRatio(fill, ink);
39
+
40
+ return html`<span class="sdk-pair" style="background: rgb(${fill}); color: rgb(${ink})">Aa</span>
41
+ <span class="sdk-pair-label${fixed ? ' sdk-fixed' : ''}">${label}</span>
42
+ <code class="sdk-value">${fill} / ${ink}</code>
43
+ <strong class="sdk-ratio" data-pass="${ratio >= AA}"
44
+ >${ratio.toFixed(2)}:1 ${ratio >= AA ? 'AA' : 'below AA'}</strong
45
+ >`;
46
+ };
47
+
48
+ const STATE_SUFFIX = { rest: '', hover: '-hover', focus: '-focus', active: '-active' } as const;
49
+
50
+ const FIXED: Record<string, (keyof typeof STATE_SUFFIX)[]> = { danger: ['hover', 'focus'], warning: ['active'] };
51
+
52
+ const pairTable = (title: string, rows: string) =>
53
+ html`<section class="sdk-table">
54
+ <h2 class="sdk-title">${title}</h2>
55
+ <div class="sdk-pairs">${rows}</div>
56
+ </section>`;
57
+
58
+ export const contrastSheet = (css: string, surface: Surface) => {
59
+ const level = tokenValues(css, `.et-surface--${surface}`);
60
+ const background = level['--et-surface-background'] ?? '';
61
+ const suffix = surface === 'light' ? '-on-light' : '';
62
+
63
+ const text = pairTable(
64
+ `Text on the ${surface} background`,
65
+ (
66
+ [
67
+ ['text', '--et-surface-color'],
68
+ ['muted', '--et-surface-color-muted'],
69
+ ['subtle', '--et-surface-color-subtle'],
70
+ ] as const
71
+ )
72
+ .map(([role, token]) => pair(role, background, level[token] ?? '', role === 'subtle'))
73
+ .join(''),
74
+ );
75
+
76
+ const fills = (['danger', 'warning'] as const)
77
+ .map((theme) => {
78
+ const values = tokenValues(css, `.et-color--${theme}${suffix}`);
79
+
80
+ return pairTable(
81
+ `.et-color--${theme}${suffix} (demo theme): on-primary on the fill`,
82
+ Object.entries(STATE_SUFFIX)
83
+ .map(([state, end]) =>
84
+ pair(
85
+ state,
86
+ values[`--et-color-primary${end}`] ?? '',
87
+ values[`--et-color-on-primary${end}`] ?? '',
88
+ FIXED[theme]?.includes(state as keyof typeof STATE_SUFFIX) ?? false,
89
+ ),
90
+ )
91
+ .join(''),
92
+ );
93
+ })
94
+ .join('');
95
+
96
+ const ink = pairTable(
97
+ `Ink on the ${surface} background`,
98
+ (['brand', 'danger', 'warning'] as const)
99
+ .map((theme) =>
100
+ pair(
101
+ `${theme}${suffix}`,
102
+ background,
103
+ tokenValues(css, `.et-color--${theme}${suffix}`)['--et-color-primary-ink'] ?? '',
104
+ false,
105
+ ),
106
+ )
107
+ .join(''),
108
+ );
109
+
110
+ return text + fills + ink;
111
+ };
112
+
113
+ export const contrastStyles = `
114
+ .sdk-pairs { display: grid; grid-template-columns: 4rem auto auto auto; gap: 0.6rem 1.2rem; align-items: center; margin-top: 0.4rem; }
115
+ .sdk-pair { display: grid; place-items: center; width: 4rem; height: 2.8rem; border-radius: 0.4rem; border: 0.1rem solid var(--et-surface-border-solid); font-size: 1.4rem; font-weight: 600; }
116
+ .sdk-pair-label { font-size: 1.2rem; white-space: nowrap; }
117
+ .sdk-fixed { font-weight: 600; }
118
+ .sdk-ratio { font-size: 1.2rem; font-variant-numeric: tabular-nums; white-space: nowrap; }
119
+ .sdk-ratio[data-pass='false'] { color: var(--et-surface-color-muted-solid); text-decoration: line-through; }
120
+ `;
@@ -0,0 +1,6 @@
1
+ @media (prefers-color-scheme: dark) {
2
+ .sdk-ring {
3
+ --et-surface-ring-solid: color-mix(in srgb, var(--et-surface-color-solid) 24%, var(--et-surface-background-solid));
4
+ --sdk-elevation-edge: var(--et-surface-ring-solid);
5
+ }
6
+ }
@@ -0,0 +1,11 @@
1
+ import { definePart } from '@design-system';
2
+ import { ELEVATION_STATES, elevationScene, type ElevationProps } from './shared/elevation/scene';
3
+ import edge from './elevation.css?inline';
4
+
5
+ export default definePart<ElevationProps>({
6
+ note: 'How the SDK lifts things off the base surface: a card, an elevated panel and an overlay pane (the select panel mock), side by side and as a pane over a panel. Fills come from the elevated surface tokens; no background colour differs from the product. In the dark scheme a 1 px ring in --et-surface-ring-solid (24 % --et-surface-color-solid over the fill) replaces the border colour. The token is defined here; the generator does not emit it yet.',
7
+ madeBy: ['claude-opus-5-5'],
8
+ states: ELEVATION_STATES,
9
+ render: (props: ElevationProps) =>
10
+ elevationScene(props, { card: 'sdk-ring', panel: 'sdk-ring', pane: 'sdk-ring' }, edge),
11
+ });
@@ -0,0 +1,101 @@
1
+ .sdk-elevation {
2
+ box-sizing: border-box;
3
+ width: max-content;
4
+ padding: 4rem;
5
+ background: var(--et-surface-background-solid);
6
+ color: var(--et-surface-color-solid);
7
+ font-size: 1.4rem;
8
+ }
9
+
10
+ .sdk-elevation-row {
11
+ display: flex;
12
+ gap: 4rem;
13
+ align-items: flex-start;
14
+ }
15
+
16
+ .sdk-elevation-card,
17
+ .sdk-elevation-panel,
18
+ .sdk-elevation-pane-panel {
19
+ --sdk-elevation-edge: var(--et-surface-border-solid);
20
+ --sdk-elevation-highlight: 0 0 0 0 transparent;
21
+
22
+ box-sizing: border-box;
23
+ border: 0.1rem solid var(--sdk-elevation-edge);
24
+ background: var(--et-surface-background-solid);
25
+ color: var(--et-surface-color-solid);
26
+ box-shadow: var(--sdk-elevation-highlight), var(--sdk-elevation-shadow);
27
+ }
28
+
29
+ .sdk-elevation-card {
30
+ --sdk-elevation-shadow:
31
+ 0 0.3rem 0.8rem rgb(var(--et-shadow-color-rgb) / 0.2), 0 0.1rem 0.3rem rgb(var(--et-shadow-color-rgb) / 0.12);
32
+
33
+ display: flex;
34
+ flex-direction: column;
35
+ gap: 0.4rem;
36
+ width: 20rem;
37
+ padding: 1.6rem;
38
+ border-radius: 1.2rem;
39
+ }
40
+
41
+ .sdk-elevation-panel {
42
+ --sdk-elevation-shadow:
43
+ 0 0.6rem 1.2rem rgb(var(--et-shadow-color-rgb) / 0.22), 0 0.2rem 0.4rem rgb(var(--et-shadow-color-rgb) / 0.14);
44
+
45
+ display: flex;
46
+ flex-direction: column;
47
+ gap: 0.6rem;
48
+ width: 28rem;
49
+ padding: 2rem;
50
+ border-radius: 1.6rem;
51
+ }
52
+
53
+ .sdk-elevation-pane-panel {
54
+ --sdk-elevation-shadow: var(--et-anchored-panel-shadow, 0 1rem 2.4rem rgb(var(--et-shadow-color-rgb) / 0.16));
55
+
56
+ width: 22rem;
57
+ }
58
+
59
+ .sdk-elevation-pane {
60
+ display: flex;
61
+ flex-direction: column;
62
+ gap: 0.8rem;
63
+ }
64
+
65
+ .sdk-elevation-label {
66
+ color: var(--et-surface-color-muted-solid);
67
+ font-size: 1.2rem;
68
+ }
69
+
70
+ .sdk-elevation-muted {
71
+ color: var(--et-surface-color-muted-solid);
72
+ }
73
+
74
+ .sdk-elevation-line {
75
+ height: 3.2rem;
76
+ margin-top: 0.8rem;
77
+ border-radius: 0.6rem;
78
+ background: color-mix(in srgb, var(--et-surface-interaction-solid) 12%, transparent);
79
+ }
80
+
81
+ .sdk-elevation-line--short {
82
+ width: 60%;
83
+ margin-top: 0;
84
+ }
85
+
86
+ .sdk-elevation-stack {
87
+ position: relative;
88
+ width: 40rem;
89
+ height: 30rem;
90
+ }
91
+
92
+ .sdk-elevation-stack .sdk-elevation-panel {
93
+ width: 32rem;
94
+ height: 22rem;
95
+ }
96
+
97
+ .sdk-elevation-pane--over {
98
+ position: absolute;
99
+ top: 12rem;
100
+ left: 16rem;
101
+ }
@@ -0,0 +1,74 @@
1
+ import { selectOption, selectPanel, selectStyles } from '@ethlete/components/design/select';
2
+ import { drawing, html } from '@design-system';
3
+ import sceneStyles from './scene.css?inline';
4
+
5
+ export type ElevationProps = { scene: 'overview' | 'stacked' };
6
+
7
+ /** The variant's class for each elevated thing. */
8
+ type ElevationEdges = { card: string; panel: string; pane: string };
9
+
10
+ const OPTIONS = [
11
+ { value: 'drafts', label: 'Drafts' },
12
+ { value: 'review', label: 'In review' },
13
+ { value: 'merged', label: 'Merged' },
14
+ { value: 'archived', label: 'Archived' },
15
+ ];
16
+
17
+ const pane = (id: string, edge: string) =>
18
+ selectPanel({
19
+ id,
20
+ color: 'brand',
21
+ content: OPTIONS.map((option) =>
22
+ selectOption(option, {
23
+ id: `${id}-${option.value}`,
24
+ selected: option.value === 'review',
25
+ active: option.value === 'merged' ? 'keyboard' : undefined,
26
+ }),
27
+ ).join(''),
28
+ }).replace(
29
+ '<et-select-panel class="',
30
+ `<et-select-panel data-et-surface-fill class="sdk-elevation-pane-panel ${edge} `,
31
+ );
32
+
33
+ const card = (edge: string) =>
34
+ html`<article class="sdk-elevation-card ${edge} et-surface--inherited" data-et-surface-fill>
35
+ <span class="sdk-elevation-label">Card</span>
36
+ <strong>Season 2026</strong>
37
+ <span class="sdk-elevation-muted">12 matches, 3 open</span>
38
+ </article>`;
39
+
40
+ const panel = (edge: string) =>
41
+ html`<section class="sdk-elevation-panel ${edge} et-surface--inherited" data-et-surface-fill>
42
+ <span class="sdk-elevation-label">Panel</span>
43
+ <strong>Edit match</strong>
44
+ <span class="sdk-elevation-muted">Kick-off, venue and referee</span>
45
+ <div class="sdk-elevation-line"></div>
46
+ <div class="sdk-elevation-line sdk-elevation-line--short"></div>
47
+ </section>`;
48
+
49
+ const overview = (edges: ElevationEdges) =>
50
+ html`<div class="sdk-elevation-row">
51
+ ${card(edges.card)} ${panel(edges.panel)}
52
+ <div class="sdk-elevation-pane">
53
+ <span class="sdk-elevation-label">Overlay pane</span>
54
+ ${pane('overview', edges.pane)}
55
+ </div>
56
+ </div>`;
57
+
58
+ const stacked = (edges: ElevationEdges) =>
59
+ html`<div class="sdk-elevation-stack">
60
+ ${panel(edges.panel)}
61
+ <div class="sdk-elevation-pane sdk-elevation-pane--over">${pane('stacked', edges.pane)}</div>
62
+ </div>`;
63
+
64
+ /** Draws the elevated things of one scene on the base surface, each with its class from `edges`. */
65
+ export const elevationScene = ({ scene }: ElevationProps, edges: ElevationEdges, styles: string) =>
66
+ drawing({
67
+ body: html`<div class="sdk-elevation">${scene === 'overview' ? overview(edges) : stacked(edges)}</div>`,
68
+ styles: [selectStyles, sceneStyles, styles].join('\n'),
69
+ });
70
+
71
+ export const ELEVATION_STATES = {
72
+ overview: { scene: 'overview' },
73
+ stacked: { scene: 'stacked' },
74
+ } satisfies Record<string, ElevationProps>;
@@ -0,0 +1,119 @@
1
+ import { SDK_ICONS } from '@ethlete/components/design/icon-set';
2
+ import { definePart, iconSheet } from '@design-system';
3
+
4
+ const GRID = 16;
5
+
6
+ const PADDING = 1;
7
+
8
+ const svg = (body: string) =>
9
+ `<svg width="100%" height="100%" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.4" stroke-linecap="round" stroke-linejoin="round">${body}</svg>`;
10
+
11
+ const FILL = 'fill="currentColor" stroke="none"';
12
+
13
+ const REDRAWN: Record<string, string> = {
14
+ 'et-arrow-out-up-right': svg(
15
+ '<path d="M5.5 5.5H4A1.5 1.5 0 0 0 2.5 7v5A1.5 1.5 0 0 0 4 13.5h5a1.5 1.5 0 0 0 1.5-1.5v-1.5"/><path d="M9.5 2.5h4v4M13.5 2.5l-6 6"/>',
16
+ ),
17
+ 'et-arrow-right': svg('<path d="M2.5 8.5h11M9 4l4.5 4.5L9 13"/>'),
18
+ 'et-arrow-up': svg('<path d="M8.5 13.5v-11M4 7l4.5-4.5L13 7"/>'),
19
+ 'et-arrows-left-right': svg('<path d="M2 8.5h12M5.5 5 2 8.5 5.5 12M10.5 5 14 8.5 10.5 12"/>'),
20
+ 'et-calendar': svg('<rect x="2.5" y="3.5" width="11" height="10" rx="1.5"/><path d="M5.5 2v3M10.5 2v3M2.5 6.5h11"/>'),
21
+ 'et-check': svg('<path d="M2.5 8.5 6 12l7.5-7.5"/>'),
22
+ 'et-chevron': svg('<path d="M3 10.5 8 5.5l5 5"/>'),
23
+ 'et-circle-check': svg('<circle cx="8" cy="8" r="6.25"/><path d="M5.25 8.25 7.2 10.2 10.75 6.5"/>'),
24
+ 'et-circle-info': svg(
25
+ `<circle cx="8" cy="8" r="6.25"/><path d="M8 7.25V11"/><circle cx="8" cy="4.75" r=".85" ${FILL}/>`,
26
+ ),
27
+ 'et-clipboard-check': svg(
28
+ '<path d="M5.5 3.5H4A1.5 1.5 0 0 0 2.5 5v7A1.5 1.5 0 0 0 4 13.5h8a1.5 1.5 0 0 0 1.5-1.5V5A1.5 1.5 0 0 0 12 3.5h-1.5"/><rect x="5.5" y="2" width="5" height="2.5" rx=".75"/><path d="M5.5 9 7.25 10.75 10.5 7.5"/>',
29
+ ),
30
+ 'et-clock': svg('<circle cx="8" cy="8" r="6.25"/><path d="M8 4.5V8l2.5 1.5"/>'),
31
+ 'et-ellipsis': svg(
32
+ `<circle cx="3" cy="8" r="1.25" ${FILL}/><circle cx="8" cy="8" r="1.25" ${FILL}/><circle cx="13" cy="8" r="1.25" ${FILL}/>`,
33
+ ),
34
+ 'et-ellipsis-vertical': svg(
35
+ `<circle cx="8" cy="3" r="1.25" ${FILL}/><circle cx="8" cy="8" r="1.25" ${FILL}/><circle cx="8" cy="13" r="1.25" ${FILL}/>`,
36
+ ),
37
+ 'et-eye': svg(
38
+ '<path d="M1.75 8C3 5.5 5.25 3.5 8 3.5s5 2 6.25 4.5C13 10.5 10.75 12.5 8 12.5S3 10.5 1.75 8Z"/><circle cx="8" cy="8" r="2"/>',
39
+ ),
40
+ 'et-eye-slash': svg(
41
+ '<mask id="et-eye-slash-cut"><rect width="16" height="16" fill="#fff"/><path d="M2.5 2.5l11 11" stroke="#000" stroke-width="4.2"/></mask><g mask="url(#et-eye-slash-cut)"><path d="M1.75 8C3 5.5 5.25 3.5 8 3.5s5 2 6.25 4.5C13 10.5 10.75 12.5 8 12.5S3 10.5 1.75 8Z"/><circle cx="8" cy="8" r="2"/></g><path d="M2.5 2.5l11 11"/>',
42
+ ),
43
+ 'et-eyedropper': svg(
44
+ '<path d="M2 14l.67-.67h2l5.67-5.67"/><path d="M2.67 13.33v-2l5.67-5.67"/><path d="M10 4l1.93-1.93a1.37 1.37 0 0 1 1.93 1.93L11.93 5.93l.27.27a1.37 1.37 0 0 1-1.93 1.93l-2.4-2.4a1.37 1.37 0 0 1 1.93-1.93l.2.2Z"/>',
45
+ ),
46
+ 'et-file': svg(
47
+ '<path d="M9 2H5a1.5 1.5 0 0 0-1.5 1.5v9A1.5 1.5 0 0 0 5 14h6a1.5 1.5 0 0 0 1.5-1.5V5.5M9 2l3.5 3.5M9 2v3.5h3.5"/>',
48
+ ),
49
+ 'et-floppy-disk': svg(
50
+ '<path d="M2.5 2.5H11l2.5 2.5v7a1.5 1.5 0 0 1-1.5 1.5H4A1.5 1.5 0 0 1 2.5 12Z"/><path d="M5.5 2.5v3h4v-3M5.5 10.5h5"/>',
51
+ ),
52
+ 'et-focus-frame': svg(
53
+ `<rect x="2.5" y="2.5" width="11" height="11" rx="1.5"/><rect x="5.5" y="5.5" width="5" height="5" rx=".75" ${FILL}/>`,
54
+ ),
55
+ 'et-grid-2x2': svg('<rect x="2.5" y="2.5" width="11" height="11" rx="1.5"/><path d="M8 2.5v11M2.5 8h11"/>'),
56
+ 'et-image': svg(
57
+ `<rect x="1.5" y="2.5" width="13" height="11" rx="1.5"/><circle cx="5.25" cy="5.75" r="1.1" ${FILL}/><path d="M3.75 11 6.5 8l1.6 1.75L10 6.5l2.25 4.5Z" ${FILL}/>`,
58
+ ),
59
+ 'et-location': svg(
60
+ '<path d="M8 14.25s-4.75-4.2-4.75-7.75a4.75 4.75 0 0 1 9.5 0c0 3.55-4.75 7.75-4.75 7.75Z"/><circle cx="8" cy="6.5" r="1.75"/>',
61
+ ),
62
+ 'et-lock': svg(
63
+ `<path d="M5.5 7.5V4.75a2.5 2.5 0 0 1 5 0V7.5"/><rect x="2.5" y="7.5" width="11" height="6" rx="1.5"/><circle cx="8" cy="10.5" r="1" ${FILL}/>`,
64
+ ),
65
+ 'et-minus': svg('<path d="M3.5 8.5h10"/>'),
66
+ 'et-pause': svg(
67
+ `<rect x="4" y="3" width="3" height="10" rx=".75" ${FILL}/><rect x="9" y="3" width="3" height="10" rx=".75" ${FILL}/>`,
68
+ ),
69
+ 'et-pencil': svg(
70
+ '<path d="M2.5 13.5l.75-3.1L9.6 4.05a1.3 1.3 0 0 1 1.85 0l.5.5a1.3 1.3 0 0 1 0 1.85L5.6 12.75Z"/><path d="M8.5 5.25l2.25 2.25"/>',
71
+ ),
72
+ 'et-play': svg('<path d="M5 3.5v9l7.5-4.5Z" fill="currentColor"/>'),
73
+ 'et-plus': svg('<path d="M8.5 3.5v10M3.5 8.5h10"/>'),
74
+ 'et-quote': svg(
75
+ `<path d="M6.5 4.5C4.5 5.17 3.5 6.83 3.5 8.83V11.5H7V8H5.17c0-1.33.47-2.2 1.33-2.67Z" ${FILL}/><path d="M12.5 4.5c-2 .67-3 2.33-3 4.33v2.67H13V8h-1.83c0-1.33.47-2.2 1.33-2.67Z" ${FILL}/>`,
76
+ ),
77
+ 'et-redo': svg('<path d="M10 10l3.5-3.5L10 3M13.5 6.5h-7a3.5 3.5 0 0 0 0 7h2"/>'),
78
+ 'et-rotate-right': svg(
79
+ '<path d="M2.75 6A5.5 5.5 0 0 1 12.25 4M13.5 2v4h-4M13.25 10A5.5 5.5 0 0 1 3.75 12M2.5 14v-4h4"/>',
80
+ ),
81
+ 'et-star': svg(
82
+ '<path d="M8 2.5l1.62 3.88 4.18.33-3.18 2.74.97 4.09L8 11.35l-3.59 2.19.97-4.09L2.2 6.71l4.18-.33Z" fill="currentColor"/>',
83
+ ),
84
+ 'et-thumbtack': svg('<path d="M6 2.5h4M6.75 2.5v3.75L4.5 9.5h7L9.25 6.25V2.5M8 9.5v4"/>'),
85
+ 'et-times': svg('<path d="M4 4l8 8M12 4l-8 8"/>'),
86
+ 'et-trash': svg(
87
+ '<path d="M2.5 4h11M6 4V2.75A.75.75 0 0 1 6.75 2h2.5a.75.75 0 0 1 .75.75V4M3.75 4l.7 8.75A1.25 1.25 0 0 0 5.7 14h4.6a1.25 1.25 0 0 0 1.25-1.25l.7-8.75M6.5 7v4M9.5 7v4"/>',
88
+ ),
89
+ 'et-triangle-exclamation': svg(
90
+ `<path d="M8 1.75 14.25 13.75H1.75Z"/><path d="M8 6.25v3"/><circle cx="8" cy="11.4" r=".85" ${FILL}/>`,
91
+ ),
92
+ 'et-trophy': svg(
93
+ '<path d="M4.5 2.5h7V6a3.5 3.5 0 0 1-7 0Z"/><path d="M4.5 3.5h-2v1a2.5 2.5 0 0 0 2.2 2.48M11.5 3.5h2v1a2.5 2.5 0 0 1-2.2 2.48M8 9.5v2M5 13.5h6l-.5-2h-5Z"/>',
94
+ ),
95
+ 'et-undo': svg('<path d="M6 10 2.5 6.5 6 3M2.5 6.5h7a3.5 3.5 0 0 1 0 7h-2"/>'),
96
+ 'et-upload': svg(
97
+ '<path d="M8 10V2.5M4.5 6 8 2.5 11.5 6M2.5 10.5V12A1.5 1.5 0 0 0 4 13.5h8a1.5 1.5 0 0 0 1.5-1.5v-1.5"/>',
98
+ ),
99
+ };
100
+
101
+ const icons = SDK_ICONS.map((icon) => {
102
+ const name = icon.variant ? `${icon.name}--${icon.variant}` : icon.name;
103
+
104
+ return { name, svg: REDRAWN[name] ?? icon.data, grid: GRID, padding: PADDING };
105
+ });
106
+
107
+ const titles = {
108
+ catalogue: `Icons: the ${SDK_ICONS.length} icons the SDK ships, at each size a component draws`,
109
+ construction: `Every icon on the ${GRID} px candidate grid: pixel lines, centre lines, and the ${PADDING} px padding`,
110
+ };
111
+
112
+ type View = 'catalogue' | 'construction';
113
+
114
+ export default definePart<{ view: View }>({
115
+ note: "Today's look",
116
+ madeBy: ['claude-opus-5-5'],
117
+ states: { catalogue: { view: 'catalogue' }, construction: { view: 'construction' } },
118
+ render: ({ view }) => iconSheet({ view, title: titles[view], icons, sizes: [16, 20, 24] }),
119
+ });