@expressivecss/expressive 0.11.0 → 0.13.1

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 (265) hide show
  1. package/CHANGELOG.md +392 -7
  2. package/README.md +37 -1
  3. package/dist/css/expressive.css +5440 -234
  4. package/dist/css/expressive.css.map +1 -1
  5. package/dist/css/expressive.min.css +1 -1
  6. package/dist/css/expressive.min.css.map +1 -1
  7. package/dist/fonts/material-symbols-outlined.woff2 +0 -0
  8. package/dist/fonts/material-symbols-rounded.woff2 +0 -0
  9. package/dist/fonts/material-symbols-sharp.woff2 +0 -0
  10. package/dist/js/chunks/{chunk-AYYYWUJ4.mjs → chunk-3CLXLPYS.mjs} +17 -11
  11. package/dist/js/chunks/chunk-3CLXLPYS.mjs.map +7 -0
  12. package/dist/js/chunks/chunk-3DHK5CZU.mjs +105 -0
  13. package/dist/js/chunks/chunk-3DHK5CZU.mjs.map +7 -0
  14. package/dist/js/chunks/{chunk-IMUPRRI6.mjs → chunk-3VOK6J7U.mjs} +3 -3
  15. package/dist/js/chunks/chunk-4PWAPV6F.mjs +7 -0
  16. package/dist/js/chunks/chunk-4PWAPV6F.mjs.map +7 -0
  17. package/dist/js/chunks/{chunk-XFJ452AZ.mjs → chunk-55IA2XUC.mjs} +5 -6
  18. package/dist/js/chunks/{chunk-XFJ452AZ.mjs.map → chunk-55IA2XUC.mjs.map} +2 -2
  19. package/dist/js/chunks/{chunk-XDB3G6RL.mjs → chunk-6N2XAEFK.mjs} +15 -4
  20. package/dist/js/chunks/{chunk-XDB3G6RL.mjs.map → chunk-6N2XAEFK.mjs.map} +2 -2
  21. package/dist/js/chunks/{chunk-MISGHDUU.mjs → chunk-6OMRGML6.mjs} +9 -7
  22. package/dist/js/chunks/{chunk-MISGHDUU.mjs.map → chunk-6OMRGML6.mjs.map} +2 -2
  23. package/dist/js/chunks/{chunk-A3BJA7V4.mjs → chunk-6WLSDZ4O.mjs} +2 -2
  24. package/dist/js/chunks/chunk-CCWDV5CR.mjs +292 -0
  25. package/dist/js/chunks/chunk-CCWDV5CR.mjs.map +7 -0
  26. package/dist/js/chunks/{chunk-JODJAGFS.mjs → chunk-CKQP6P76.mjs} +31 -8
  27. package/dist/js/chunks/chunk-CKQP6P76.mjs.map +7 -0
  28. package/dist/js/chunks/{chunk-KR44BSYQ.mjs → chunk-DLWYKFEI.mjs} +3 -3
  29. package/dist/js/chunks/chunk-DTKR54I6.mjs +270 -0
  30. package/dist/js/chunks/chunk-DTKR54I6.mjs.map +7 -0
  31. package/dist/js/chunks/{chunk-SLFNPY5M.mjs → chunk-EC63CHXU.mjs} +2 -2
  32. package/dist/js/chunks/chunk-GVGT6MIU.mjs +47 -0
  33. package/dist/js/chunks/chunk-GVGT6MIU.mjs.map +7 -0
  34. package/dist/js/chunks/{chunk-LZVBJ33S.mjs → chunk-GZWPXXY6.mjs} +15 -8
  35. package/dist/js/chunks/chunk-GZWPXXY6.mjs.map +7 -0
  36. package/dist/js/chunks/chunk-HKT2S7VM.mjs +48 -0
  37. package/dist/js/chunks/chunk-HKT2S7VM.mjs.map +7 -0
  38. package/dist/js/chunks/{chunk-D4UZ4HFN.mjs → chunk-IFXVDDDH.mjs} +23 -11
  39. package/dist/js/chunks/chunk-IFXVDDDH.mjs.map +7 -0
  40. package/dist/js/chunks/chunk-K4CJCRGE.mjs +262 -0
  41. package/dist/js/chunks/chunk-K4CJCRGE.mjs.map +7 -0
  42. package/dist/js/chunks/chunk-LNCCYGPC.mjs +163 -0
  43. package/dist/js/chunks/chunk-LNCCYGPC.mjs.map +7 -0
  44. package/dist/js/chunks/{chunk-QSQ24FYT.mjs → chunk-LTWPGFBR.mjs} +2 -2
  45. package/dist/js/chunks/{chunk-QSQ24FYT.mjs.map → chunk-LTWPGFBR.mjs.map} +2 -2
  46. package/dist/js/chunks/{chunk-I5KR22BY.mjs → chunk-LWBQIX5J.mjs} +15 -15
  47. package/dist/js/chunks/chunk-LWBQIX5J.mjs.map +7 -0
  48. package/dist/js/chunks/{chunk-GY2Z5CJ2.mjs → chunk-NNYP33NB.mjs} +67 -32
  49. package/dist/js/chunks/chunk-NNYP33NB.mjs.map +7 -0
  50. package/dist/js/chunks/chunk-NQLC3YMW.mjs +1 -0
  51. package/dist/js/chunks/chunk-O5XPWXIQ.mjs +406 -0
  52. package/dist/js/chunks/chunk-O5XPWXIQ.mjs.map +7 -0
  53. package/dist/js/chunks/chunk-P3G3QHII.mjs +166 -0
  54. package/dist/js/chunks/chunk-P3G3QHII.mjs.map +7 -0
  55. package/dist/js/chunks/{chunk-VAS6JQ6P.mjs → chunk-PIJ2TAR3.mjs} +3 -3
  56. package/dist/js/chunks/{chunk-74N6U5JJ.mjs → chunk-PLYXLSH3.mjs} +38 -37
  57. package/dist/js/chunks/chunk-PLYXLSH3.mjs.map +7 -0
  58. package/dist/js/chunks/{chunk-PIIAEYAJ.mjs → chunk-QDAL4IYN.mjs} +2 -2
  59. package/dist/js/chunks/chunk-QKWPQK5N.mjs +179 -0
  60. package/dist/js/chunks/chunk-QKWPQK5N.mjs.map +7 -0
  61. package/dist/js/chunks/{chunk-FRB7TOCS.mjs → chunk-QV2JAWIZ.mjs} +2 -2
  62. package/dist/js/chunks/{chunk-N3UHGN3N.mjs → chunk-QVVEWBOF.mjs} +3 -3
  63. package/dist/js/chunks/chunk-RHRQKTTX.mjs +139 -0
  64. package/dist/js/chunks/chunk-RHRQKTTX.mjs.map +7 -0
  65. package/dist/js/chunks/chunk-SPETGK25.mjs +59 -0
  66. package/dist/js/chunks/chunk-SPETGK25.mjs.map +7 -0
  67. package/dist/js/chunks/{chunk-TK6PX2GC.mjs → chunk-U2OTHOTI.mjs} +131 -19
  68. package/dist/js/chunks/chunk-U2OTHOTI.mjs.map +7 -0
  69. package/dist/js/chunks/{chunk-TYM6U5DY.mjs → chunk-UAEAQBRC.mjs} +2 -2
  70. package/dist/js/chunks/{chunk-7UXHSYIA.mjs → chunk-UBLRRJ7N.mjs} +3 -3
  71. package/dist/js/chunks/{chunk-EP3CVKB5.mjs → chunk-UEZUJQ66.mjs} +8 -5
  72. package/dist/js/chunks/chunk-UEZUJQ66.mjs.map +7 -0
  73. package/dist/js/chunks/{chunk-JNPIWFJT.mjs → chunk-UNEMYWEW.mjs} +3 -3
  74. package/dist/js/chunks/chunk-VTLBW7QS.mjs +124 -0
  75. package/dist/js/chunks/chunk-VTLBW7QS.mjs.map +7 -0
  76. package/dist/js/chunks/{chunk-JKNPQQWY.mjs → chunk-WJXDBPXQ.mjs} +28 -12
  77. package/dist/js/chunks/chunk-WJXDBPXQ.mjs.map +7 -0
  78. package/dist/js/chunks/{chunk-CDW6WIRT.mjs → chunk-XGHORT7J.mjs} +18 -11
  79. package/dist/js/chunks/chunk-XGHORT7J.mjs.map +7 -0
  80. package/dist/js/chunks/{chunk-7GKXUG4B.mjs → chunk-XH6BEEMY.mjs} +78 -25
  81. package/dist/js/chunks/chunk-XH6BEEMY.mjs.map +7 -0
  82. package/dist/js/chunks/{chunk-XO5WX3TK.mjs → chunk-YDCS5S3J.mjs} +2 -2
  83. package/dist/js/expressive.cjs +2540 -233
  84. package/dist/js/expressive.cjs.map +4 -4
  85. package/dist/js/expressive.js +2540 -233
  86. package/dist/js/expressive.js.map +4 -4
  87. package/dist/js/expressive.min.js +10 -10
  88. package/dist/js/expressive.min.js.map +4 -4
  89. package/dist/js/expressive.mjs +86 -38
  90. package/dist/js/expressive.mjs.map +1 -1
  91. package/dist/js/internal/behaviors/bottomSheets.mjs +3 -3
  92. package/dist/js/internal/behaviors/dialogs.mjs +2 -2
  93. package/dist/js/internal/behaviors/forms.mjs +2 -2
  94. package/dist/js/internal/behaviors/sheetDrag.mjs +2 -2
  95. package/dist/js/internal/behaviors/sideSheets.mjs +3 -3
  96. package/dist/js/internal/components/appBar.mjs +2 -2
  97. package/dist/js/internal/components/autocomplete.mjs +4 -4
  98. package/dist/js/internal/components/barChart.mjs +10 -0
  99. package/dist/js/internal/components/barChart.mjs.map +7 -0
  100. package/dist/js/internal/components/buttonGroup.mjs +2 -2
  101. package/dist/js/internal/components/buttons.mjs +3 -3
  102. package/dist/js/internal/components/cards.mjs +3 -3
  103. package/dist/js/internal/components/carousel.mjs +3 -3
  104. package/dist/js/internal/components/characterCounter.mjs +2 -2
  105. package/dist/js/internal/components/chips.mjs +5 -5
  106. package/dist/js/internal/components/columnChart.mjs +9 -0
  107. package/dist/js/internal/components/columnChart.mjs.map +7 -0
  108. package/dist/js/internal/components/commandPalette.mjs +9 -0
  109. package/dist/js/internal/components/commandPalette.mjs.map +7 -0
  110. package/dist/js/internal/components/datepicker.mjs +6 -6
  111. package/dist/js/internal/components/expandingCard.mjs +3 -3
  112. package/dist/js/internal/components/heatmapChart.mjs +9 -0
  113. package/dist/js/internal/components/heatmapChart.mjs.map +7 -0
  114. package/dist/js/internal/components/index.mjs +79 -31
  115. package/dist/js/internal/components/lightbox.mjs +3 -3
  116. package/dist/js/internal/components/lineChart.mjs +12 -0
  117. package/dist/js/internal/components/lineChart.mjs.map +7 -0
  118. package/dist/js/internal/components/menu.mjs +3 -3
  119. package/dist/js/internal/components/messageScroller.mjs +9 -0
  120. package/dist/js/internal/components/messageScroller.mjs.map +7 -0
  121. package/dist/js/internal/components/mixedChart.mjs +10 -0
  122. package/dist/js/internal/components/mixedChart.mjs.map +7 -0
  123. package/dist/js/internal/components/navigationRail.mjs +2 -2
  124. package/dist/js/internal/components/pieChart.mjs +9 -0
  125. package/dist/js/internal/components/pieChart.mjs.map +7 -0
  126. package/dist/js/internal/components/questionnaire.mjs +9 -0
  127. package/dist/js/internal/components/questionnaire.mjs.map +7 -0
  128. package/dist/js/internal/components/radarChart.mjs +9 -0
  129. package/dist/js/internal/components/radarChart.mjs.map +7 -0
  130. package/dist/js/internal/components/radialChart.mjs +9 -0
  131. package/dist/js/internal/components/radialChart.mjs.map +7 -0
  132. package/dist/js/internal/components/registry.mjs +37 -25
  133. package/dist/js/internal/components/richTextEditor.mjs +9 -0
  134. package/dist/js/internal/components/richTextEditor.mjs.map +7 -0
  135. package/dist/js/internal/components/scrollspy.mjs +2 -2
  136. package/dist/js/internal/components/select.mjs +4 -4
  137. package/dist/js/internal/components/slider.mjs +3 -3
  138. package/dist/js/internal/components/snackbar.mjs +2 -2
  139. package/dist/js/internal/components/tabs.mjs +4 -4
  140. package/dist/js/internal/components/timepicker.mjs +4 -4
  141. package/dist/js/internal/components/tooltip.mjs +3 -3
  142. package/dist/js/internal/core/component.mjs +1 -1
  143. package/dist/js/internal/core/utils.mjs +1 -1
  144. package/dist/js/internal/plugins/dockedDisplayPlugin.mjs +2 -2
  145. package/dist/js/modular.mjs +86 -38
  146. package/dist/types/behaviors/forms.d.ts +22 -0
  147. package/dist/types/components/appBar.d.ts +1 -1
  148. package/dist/types/components/barChart.d.ts +24 -0
  149. package/dist/types/components/columnChart.d.ts +21 -0
  150. package/dist/types/components/commandPalette.d.ts +96 -0
  151. package/dist/types/components/datepicker.d.ts +5 -2
  152. package/dist/types/components/heatmapChart.d.ts +49 -0
  153. package/dist/types/components/index.d.ts +12 -0
  154. package/dist/types/components/lineChart.d.ts +134 -0
  155. package/dist/types/components/menu.d.ts +32 -0
  156. package/dist/types/components/messageScroller.d.ts +111 -0
  157. package/dist/types/components/mixedChart.d.ts +25 -0
  158. package/dist/types/components/pieChart.d.ts +40 -0
  159. package/dist/types/components/questionnaire.d.ts +96 -0
  160. package/dist/types/components/radarChart.d.ts +39 -0
  161. package/dist/types/components/radialChart.d.ts +45 -0
  162. package/dist/types/components/registry.d.ts +44 -0
  163. package/dist/types/components/richTextEditor.d.ts +71 -0
  164. package/dist/types/components/slider.d.ts +1 -0
  165. package/dist/types/components/snackbar.d.ts +6 -0
  166. package/dist/types/components/timepicker.d.ts +4 -1
  167. package/dist/types/components/tooltip.d.ts +2 -1
  168. package/dist/types/modular.d.ts +10 -1
  169. package/package.json +4 -1
  170. package/src/sass/README.md +3 -6
  171. package/src/sass/abstracts/_index.scss +1 -1
  172. package/src/sass/abstracts/_mixins.scss +226 -0
  173. package/src/sass/abstracts/_variables.scss +14 -0
  174. package/src/sass/base/_typography.scss +45 -0
  175. package/src/sass/components/_accordion.scss +161 -0
  176. package/src/sass/components/_aura.scss +119 -0
  177. package/src/sass/components/_avatar.scss +86 -0
  178. package/src/sass/components/_bar-chart.scss +285 -0
  179. package/src/sass/components/_bottom-sheet.scss +1 -0
  180. package/src/sass/components/_button-groups.scss +13 -3
  181. package/src/sass/components/_cards.scss +16 -13
  182. package/src/sass/components/_carousel.scss +9 -7
  183. package/src/sass/components/_column-chart.scss +134 -0
  184. package/src/sass/components/_command-palette.scss +140 -0
  185. package/src/sass/components/_countdown.scss +89 -0
  186. package/src/sass/components/_data-table.scss +188 -0
  187. package/src/sass/components/_dialog.scss +1 -0
  188. package/src/sass/components/_empty-state.scss +78 -0
  189. package/src/sass/components/_expanding-card.scss +3 -0
  190. package/src/sass/components/_heatmap-chart.scss +156 -0
  191. package/src/sass/components/_index.scss +27 -0
  192. package/src/sass/components/_kpi.scss +162 -0
  193. package/src/sass/components/_line-chart.scss +102 -0
  194. package/src/sass/components/_marquee.scss +111 -0
  195. package/src/sass/components/_menu.scss +10 -0
  196. package/src/sass/components/_message-scroller.scss +66 -0
  197. package/src/sass/components/_message.scss +202 -0
  198. package/src/sass/components/_mixed-chart.scss +157 -0
  199. package/src/sass/components/_navbar.scss +11 -6
  200. package/src/sass/components/_navigation-bar.scss +1 -0
  201. package/src/sass/components/_navigation-rail.scss +9 -0
  202. package/src/sass/components/_page-footer.scss +0 -11
  203. package/src/sass/components/_pie-chart.scss +203 -0
  204. package/src/sass/components/_popover.scss +112 -0
  205. package/src/sass/components/_progress.scss +25 -6
  206. package/src/sass/components/_questionnaire.scss +144 -0
  207. package/src/sass/components/_radar-chart.scss +205 -0
  208. package/src/sass/components/_radial-chart.scss +174 -0
  209. package/src/sass/components/_rich-text-editor.scss +99 -0
  210. package/src/sass/components/_search.scss +1 -0
  211. package/src/sass/components/_side-sheet.scss +1 -0
  212. package/src/sass/components/_skeleton.scss +81 -0
  213. package/src/sass/components/_snackbar.scss +2 -1
  214. package/src/sass/components/_stat.scss +86 -0
  215. package/src/sass/components/_stepper.scss +190 -0
  216. package/src/sass/components/_timeline.scss +114 -0
  217. package/src/sass/components/_timepicker.scss +2 -2
  218. package/src/sass/components/_toolbar.scss +2 -1
  219. package/src/sass/components/_tooltip.scss +2 -0
  220. package/src/sass/components/_tree.scss +139 -0
  221. package/src/sass/components/forms/_checkboxes.scss +2 -2
  222. package/src/sass/components/forms/_drop-zone.scss +128 -0
  223. package/src/sass/components/forms/_index.scss +2 -0
  224. package/src/sass/components/forms/_input-fields.scss +166 -15
  225. package/src/sass/components/forms/_radio-buttons.scss +2 -2
  226. package/src/sass/components/forms/_rating.scss +165 -0
  227. package/src/sass/components/forms/_slider.scss +51 -29
  228. package/src/sass/components/forms/_switches.scss +3 -3
  229. package/src/sass/tokens/_reference.scss +3 -15
  230. package/src/sass/utilities/_helpers.scss +14 -0
  231. package/src/sass/utilities/_index.scss +2 -0
  232. package/src/sass/utilities/_scroll-area.scss +35 -0
  233. package/src/sass/utilities/_shapes.scss +164 -0
  234. package/src/sass/utilities/_spacing.scss +29 -23
  235. package/src/sass/utilities/_visibility.scss +3 -2
  236. package/dist/js/chunks/chunk-74N6U5JJ.mjs.map +0 -7
  237. package/dist/js/chunks/chunk-7GKXUG4B.mjs.map +0 -7
  238. package/dist/js/chunks/chunk-AYYYWUJ4.mjs.map +0 -7
  239. package/dist/js/chunks/chunk-CDW6WIRT.mjs.map +0 -7
  240. package/dist/js/chunks/chunk-D4UZ4HFN.mjs.map +0 -7
  241. package/dist/js/chunks/chunk-EP3CVKB5.mjs.map +0 -7
  242. package/dist/js/chunks/chunk-GY2Z5CJ2.mjs.map +0 -7
  243. package/dist/js/chunks/chunk-I5KR22BY.mjs.map +0 -7
  244. package/dist/js/chunks/chunk-JKNPQQWY.mjs.map +0 -7
  245. package/dist/js/chunks/chunk-JODJAGFS.mjs.map +0 -7
  246. package/dist/js/chunks/chunk-JR24UB4X.mjs +0 -100
  247. package/dist/js/chunks/chunk-JR24UB4X.mjs.map +0 -7
  248. package/dist/js/chunks/chunk-LZVBJ33S.mjs.map +0 -7
  249. package/dist/js/chunks/chunk-PMBPAFAS.mjs +0 -7
  250. package/dist/js/chunks/chunk-PMBPAFAS.mjs.map +0 -7
  251. package/dist/js/chunks/chunk-TK6PX2GC.mjs.map +0 -7
  252. package/dist/js/chunks/chunk-WWPAPHMA.mjs +0 -1
  253. /package/dist/js/chunks/{chunk-IMUPRRI6.mjs.map → chunk-3VOK6J7U.mjs.map} +0 -0
  254. /package/dist/js/chunks/{chunk-A3BJA7V4.mjs.map → chunk-6WLSDZ4O.mjs.map} +0 -0
  255. /package/dist/js/chunks/{chunk-KR44BSYQ.mjs.map → chunk-DLWYKFEI.mjs.map} +0 -0
  256. /package/dist/js/chunks/{chunk-SLFNPY5M.mjs.map → chunk-EC63CHXU.mjs.map} +0 -0
  257. /package/dist/js/chunks/{chunk-WWPAPHMA.mjs.map → chunk-NQLC3YMW.mjs.map} +0 -0
  258. /package/dist/js/chunks/{chunk-VAS6JQ6P.mjs.map → chunk-PIJ2TAR3.mjs.map} +0 -0
  259. /package/dist/js/chunks/{chunk-PIIAEYAJ.mjs.map → chunk-QDAL4IYN.mjs.map} +0 -0
  260. /package/dist/js/chunks/{chunk-FRB7TOCS.mjs.map → chunk-QV2JAWIZ.mjs.map} +0 -0
  261. /package/dist/js/chunks/{chunk-N3UHGN3N.mjs.map → chunk-QVVEWBOF.mjs.map} +0 -0
  262. /package/dist/js/chunks/{chunk-TYM6U5DY.mjs.map → chunk-UAEAQBRC.mjs.map} +0 -0
  263. /package/dist/js/chunks/{chunk-7UXHSYIA.mjs.map → chunk-UBLRRJ7N.mjs.map} +0 -0
  264. /package/dist/js/chunks/{chunk-JNPIWFJT.mjs.map → chunk-UNEMYWEW.mjs.map} +0 -0
  265. /package/dist/js/chunks/{chunk-XO5WX3TK.mjs.map → chunk-YDCS5S3J.mjs.map} +0 -0
@@ -0,0 +1,128 @@
1
+ @use "../../abstracts" as *;
2
+
3
+ // Drop zone. A .drop-zone is a large target for choosing files: a <label>
4
+ // holding an icon, a prompt and a native <input type="file">, with an
5
+ // optional .drop-zone-files list after it.
6
+ //
7
+ // The input is stretched invisibly over the whole label, so the browser
8
+ // takes a click, a keypress or a dropped file exactly as it does on a plain
9
+ // file input. The Forms behavior adds .dragover while files are dragged over
10
+ // it and fills .drop-zone-files with each chosen file's name and size.
11
+ //
12
+ // Tokens:
13
+ // --md-comp-drop-zone-shape 16px
14
+ // --md-comp-drop-zone-outline-color outline
15
+ // --md-comp-drop-zone-dragover-container-color primary-container
16
+ // --md-comp-drop-zone-dragover-color on-primary-container
17
+
18
+ .drop-zone {
19
+ --md-comp-drop-zone-shape: 16px;
20
+ --md-comp-drop-zone-outline-color: var(--md-sys-color-outline);
21
+ --md-comp-drop-zone-dragover-container-color: var(--md-sys-color-primary-container);
22
+ --md-comp-drop-zone-dragover-color: var(--md-sys-color-on-primary-container);
23
+
24
+ margin: $element-top-margin 0 $element-bottom-margin;
25
+
26
+ > label {
27
+ position: relative;
28
+ box-sizing: border-box;
29
+ display: flex;
30
+ flex-direction: column;
31
+ align-items: center;
32
+ gap: 4px;
33
+ padding: 32px 24px;
34
+ border: 1px dashed var(--md-comp-drop-zone-outline-color);
35
+ border-radius: var(--md-comp-drop-zone-shape);
36
+ text-align: center;
37
+ color: var(--md-sys-color-on-surface-variant);
38
+ cursor: pointer;
39
+ transition: background-color 0.2s ease-out, border-color 0.2s ease-out;
40
+ @include typescale("body-large");
41
+
42
+ > #{$icon} {
43
+ margin-block-end: 8px;
44
+ font-size: 32px;
45
+ color: var(--md-sys-color-primary);
46
+ }
47
+
48
+ > small {
49
+ @include typescale("body-small");
50
+ }
51
+
52
+ > input[type="file"] {
53
+ position: absolute;
54
+ inset: 0;
55
+ width: 100%;
56
+ height: 100%;
57
+ margin: 0;
58
+ padding: 0;
59
+ opacity: 0;
60
+ cursor: pointer;
61
+ }
62
+
63
+ &:hover {
64
+ background-color: color-mix(
65
+ in oklab,
66
+ var(--md-sys-color-on-surface) state-opacity("hover"),
67
+ transparent
68
+ );
69
+ }
70
+
71
+ &:has(> input:focus-visible) {
72
+ @include focus-ring;
73
+ }
74
+
75
+ &:has(> input:disabled) {
76
+ opacity: 0.38;
77
+ cursor: default;
78
+ pointer-events: none;
79
+ }
80
+ }
81
+
82
+ &.dragover > label {
83
+ border-style: solid;
84
+ border-color: var(--md-sys-color-primary);
85
+ background-color: var(--md-comp-drop-zone-dragover-container-color);
86
+ color: var(--md-comp-drop-zone-dragover-color);
87
+ }
88
+
89
+ > .drop-zone-files {
90
+ display: flex;
91
+ flex-direction: column;
92
+ gap: 2px;
93
+ margin: 8px 0 0;
94
+ padding: 0;
95
+ list-style: none;
96
+
97
+ > li {
98
+ display: flex;
99
+ justify-content: space-between;
100
+ gap: 16px;
101
+ padding: 8px 16px;
102
+ border-radius: 8px;
103
+ background-color: var(--md-sys-color-surface-container);
104
+ color: var(--md-sys-color-on-surface);
105
+ @include typescale("body-medium");
106
+
107
+ > :first-child {
108
+ min-width: 0;
109
+ overflow-wrap: anywhere;
110
+ }
111
+
112
+ > :last-child:not(:first-child) {
113
+ flex: none;
114
+ color: var(--md-sys-color-on-surface-variant);
115
+ }
116
+ }
117
+
118
+ &:empty {
119
+ display: none;
120
+ }
121
+ }
122
+ }
123
+
124
+ @media (prefers-reduced-motion: reduce) {
125
+ .drop-zone > label {
126
+ transition: none;
127
+ }
128
+ }
@@ -1,9 +1,11 @@
1
1
  @forward 'input-fields';
2
2
  @forward 'radio-buttons';
3
+ @forward 'rating';
3
4
  @forward 'checkboxes';
4
5
  @forward 'switches';
5
6
  @forward 'select';
6
7
  @forward 'file-input';
8
+ @forward 'drop-zone';
7
9
  @forward 'slider';
8
10
  @forward 'fieldset';
9
11
 
@@ -177,7 +177,7 @@ $_not-label: ".supporting-text, .character-counter, .file-path, .caret, .prefix,
177
177
  // .character-counter, .file-path). So the documented markup names the side
178
178
  // explicitly with .prefix / .suffix, and those rules key on nothing else.
179
179
  > i:is(.prefix, .suffix, :first-of-type, :last-of-type, :last-child),
180
- > :is(.prefix, .suffix) {
180
+ > :is(.prefix, .suffix):not(.icon-button) {
181
181
  position: absolute;
182
182
  top: 16px;
183
183
  display: flex;
@@ -200,7 +200,7 @@ $_not-label: ".supporting-text, .character-counter, .file-path, .caret, .prefix,
200
200
  > i.suffix,
201
201
  > i:last-of-type:not(:first-of-type),
202
202
  > i:last-child:not(:first-child):not(.prefix),
203
- > .suffix {
203
+ > .suffix:not(.icon-button) {
204
204
  right: 12px;
205
205
  // Both icons inherited this from the floating-label rule until they were
206
206
  // excluded from it. .prefix restates it below; .suffix has to as well, or
@@ -208,6 +208,15 @@ $_not-label: ".supporting-text, .character-counter, .file-path, .caret, .prefix,
208
208
  pointer-events: none;
209
209
  }
210
210
 
211
+ // A trailing icon button is a control, so it keeps its 40dp target and its
212
+ // clicks. It centres on the same point as a 24dp trailing icon.
213
+ > .icon-button.suffix {
214
+ position: absolute;
215
+ top: 8px;
216
+ right: 4px;
217
+ z-index: 1;
218
+ }
219
+
211
220
  &:has(> i:first-of-type:not(.suffix):not(:last-child), > i.prefix, > .prefix) {
212
221
  > :is(input, textarea) {
213
222
  padding-left: 52px;
@@ -310,24 +319,166 @@ textarea {
310
319
  }
311
320
  }
312
321
 
313
- :is(.datepicker-date-input, .date-picker-date-input) {
314
- position: relative;
315
- text-indent: -9999px;
322
+ // Datepicker paints its formatted date over the native value with ::after.
323
+ // Firefox renders no generated content on an <input>, so hiding the native
324
+ // value there left the field blank. The engines that do render it are the ones
325
+ // that expose ::-webkit-datetime-edit.
326
+ @supports selector(::-webkit-datetime-edit) {
327
+ // The positioned input would paint its filled container over the field's
328
+ // icons, which come before it. Raise them inside the field's own stacking
329
+ // context, so they do not also rise over the docked search view or a
330
+ // sticky header. A docked calendar in the field has to escape it.
331
+ .field:has(> :is(.datepicker-date-input, .date-picker-date-input)) {
332
+ &:not(:has(> .display-docked)) {
333
+ isolation: isolate;
334
+ }
316
335
 
317
- &::after {
318
- display: block;
319
- position: absolute;
320
- top: 1.1rem;
321
- content: attr(data-date);
322
- color: var(--input-color);
323
- text-indent: 0;
336
+ > :is(i, .prefix, .suffix) {
337
+ z-index: 1;
338
+ }
339
+ }
340
+
341
+ :is(.datepicker-date-input, .date-picker-date-input) {
342
+ position: relative;
343
+ text-indent: -9999px;
344
+
345
+ &::after {
346
+ display: block;
347
+ position: absolute;
348
+ top: 1.1rem;
349
+ content: attr(data-date);
350
+ color: var(--input-color);
351
+ text-indent: 0;
352
+ }
353
+
354
+ &:focus-visible {
355
+ text-indent: 0;
356
+ }
357
+
358
+ &:focus-visible:after {
359
+ text-indent: -9999px;
360
+ }
361
+ }
362
+ }
363
+
364
+ // Password visibility toggle. A trailing .icon-button.password-toggle with
365
+ // aria-pressed holds two icons: the first shows while the password is hidden,
366
+ // the second once it is shown. The Forms behavior flips the input's type.
367
+ .password-toggle {
368
+ > #{$icon}:last-child:not(:first-child) {
369
+ display: none;
324
370
  }
325
371
 
372
+ &[aria-pressed="true"] {
373
+ > #{$icon}:first-child:not(:last-child) {
374
+ display: none;
375
+ }
376
+
377
+ > #{$icon}:last-child:not(:first-child) {
378
+ display: inline-block;
379
+ }
380
+ }
381
+ }
382
+
383
+ // One-time code. A single native input drawn as a row of cells, so paste,
384
+ // autofill from autocomplete="one-time-code", undo and the caret all stay the
385
+ // browser's. A monospace face makes every digit 1ch wide; letter-spacing
386
+ // moves each one to the next cell, and the input is clipped after the last.
387
+ //
388
+ // Tokens:
389
+ // --md-comp-otp-length 6
390
+ // --md-comp-otp-cell-width 48px
391
+ // --md-comp-otp-cell-height 56px
392
+ // --md-comp-otp-gap 8px
393
+ // --md-comp-otp-cell-color surface-container-highest
394
+ // --md-comp-otp-indicator-color on-surface-variant / focus: primary
395
+ //
396
+ // :not(.browser-default) matches the weight of the shared text-input rule
397
+ // above, which would otherwise win on width, height and letter-spacing.
398
+ input.otp:not(.browser-default) {
399
+ --md-comp-otp-length: 6;
400
+ --md-comp-otp-cell-width: 48px;
401
+ --md-comp-otp-cell-height: 56px;
402
+ --md-comp-otp-gap: 8px;
403
+ --md-comp-otp-cell-color: var(--md-sys-color-surface-container-highest);
404
+ --md-comp-otp-indicator-color: var(--md-sys-color-on-surface-variant);
405
+ // Derived, not for overriding: the distance between cell starts, the
406
+ // inset that centres a digit in its cell, and the box past the last cell
407
+ // that the caret needs and the clip hides.
408
+ --md-comp-otp-pitch: calc(var(--md-comp-otp-cell-width) + var(--md-comp-otp-gap));
409
+ --md-comp-otp-inset: calc((var(--md-comp-otp-cell-width) - 1ch) / 2);
410
+ --md-comp-otp-overhang: calc(var(--md-comp-otp-gap) + var(--md-comp-otp-inset) + 2px);
411
+
412
+ box-sizing: border-box;
413
+ display: block;
414
+ // Room for the caret after the last digit, clipped back to the cells; the
415
+ // negative margin gives the overhang back to the layout.
416
+ width: calc(var(--md-comp-otp-length) * var(--md-comp-otp-pitch) + var(--md-comp-otp-inset) + 2px);
417
+ height: var(--md-comp-otp-cell-height);
418
+ margin: 0 calc(var(--md-comp-otp-overhang) * -1) 0 0;
419
+ padding: 0 0 0 var(--md-comp-otp-inset);
420
+ border: 0;
421
+ border-radius: 0;
422
+ outline: 0;
423
+ box-shadow: none;
424
+ clip-path: inset(0 var(--md-comp-otp-overhang) 0 0);
425
+ // Digits read left to right in every script.
426
+ direction: ltr;
427
+ font-family: ui-monospace, "SFMono-Regular", Menlo, Consolas, "Liberation Mono", monospace;
428
+ font-size: 24px;
429
+ font-variant-numeric: tabular-nums;
430
+ letter-spacing: calc(var(--md-comp-otp-pitch) - 1ch);
431
+ color: var(--md-sys-color-on-surface);
432
+ caret-color: var(--md-sys-color-primary);
433
+ background-color: transparent;
434
+ background-image:
435
+ linear-gradient(
436
+ to right,
437
+ var(--md-comp-otp-indicator-color) var(--md-comp-otp-cell-width),
438
+ transparent 0
439
+ ),
440
+ linear-gradient(
441
+ to right,
442
+ var(--md-comp-otp-cell-color) var(--md-comp-otp-cell-width),
443
+ transparent 0
444
+ );
445
+ background-size:
446
+ var(--md-comp-otp-pitch) 1px,
447
+ var(--md-comp-otp-pitch) 100%;
448
+ background-position: left bottom, left top;
449
+ background-repeat: repeat-x;
450
+
451
+ &::placeholder {
452
+ color: var(--md-sys-color-on-surface-variant);
453
+ opacity: 1;
454
+ }
455
+
456
+ // Every cell's indicator turns primary and thickens while the code has
457
+ // focus; the clip would cut an outline, so this is the focus ring.
458
+ &:focus,
326
459
  &:focus-visible {
327
- text-indent: 0;
460
+ --md-comp-otp-indicator-color: var(--md-sys-color-primary);
461
+
462
+ outline: 0;
463
+ background-size:
464
+ var(--md-comp-otp-pitch) 2px,
465
+ var(--md-comp-otp-pitch) 100%;
328
466
  }
329
467
 
330
- &:focus-visible:after {
331
- text-indent: -9999px;
468
+ &.invalid,
469
+ &[aria-invalid="true"] {
470
+ --md-comp-otp-indicator-color: var(--md-sys-color-error);
471
+ }
472
+
473
+ &:disabled {
474
+ opacity: 0.38;
475
+ }
476
+
477
+ @media (forced-colors: active) {
478
+ --md-comp-otp-indicator-color: CanvasText;
479
+
480
+ &:focus {
481
+ --md-comp-otp-indicator-color: Highlight;
482
+ }
332
483
  }
333
484
  }
@@ -4,7 +4,7 @@
4
4
  //
5
5
  // Anatomy is the HTML. A <label> wrapping <input type="radio"> is the
6
6
  // control. The label text is a sibling of the input — no extra class, no
7
- // required <span>. input + span still works (legacy / BeerCSS).
7
+ // required <span>. input + span still works (legacy).
8
8
  //
9
9
  // Tokens follow https://m3.material.io/components/radio-button/specs
10
10
  // icon 20dp ring, 2dp stroke, on-surface-variant
@@ -136,7 +136,7 @@ label:has(> [type="radio"]:disabled),
136
136
  cursor: default;
137
137
  }
138
138
 
139
- // Legacy / BeerCSS: input + span draws the same 20/10 anatomy.
139
+ // Legacy: input + span draws the same 20/10 anatomy.
140
140
  [type="radio"] + span {
141
141
  position: relative;
142
142
  display: inline-flex;
@@ -0,0 +1,165 @@
1
+ @use "../../abstracts" as *;
2
+
3
+ // Rating. Two forms share the star.
4
+ //
5
+ // Input: a <fieldset class="rating"> with a <legend> and one radio per star,
6
+ // each in a <label> whose visually hidden text ("3 stars") comes before the
7
+ // radio: a span after it is the older input + span radio, which hides the
8
+ // input. The radio itself is drawn as the star, so arrow keys, form
9
+ // submission and the group's name stay native. A star fills when it or a
10
+ // later star is checked; hovering previews.
11
+ //
12
+ // Display: <span class="rating" role="img" aria-label="Rated 4.5 out of 5">
13
+ // with --md-comp-rating-value. The stars fill to that value, halves included.
14
+ //
15
+ // Loaded after radio-buttons: the input rules match the radio rules' weight
16
+ // and win on order.
17
+ //
18
+ // Tokens:
19
+ // --md-comp-rating-size 24px (display 20px)
20
+ // --md-comp-rating-color tertiary
21
+ // --md-comp-rating-empty-color outline-variant
22
+ // --md-comp-rating-value 0 (display)
23
+ // --md-comp-rating-max 5 (display)
24
+
25
+ $_rating-star: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='m12 17.27 6.18 3.73-1.64-7.03L22 9.24l-7.19-.61L12 2 9.19 8.63 2 9.24l5.46 4.73L5.82 21z'/%3E%3C/svg%3E");
26
+
27
+ .rating {
28
+ --md-comp-rating-size: 24px;
29
+ --md-comp-rating-color: var(--md-sys-color-tertiary);
30
+ --md-comp-rating-empty-color: var(--md-sys-color-outline-variant);
31
+ }
32
+
33
+ fieldset.rating {
34
+ display: flex;
35
+ flex-wrap: wrap;
36
+ align-items: center;
37
+ margin: 0;
38
+ padding: 0;
39
+ border: 0;
40
+
41
+ > legend {
42
+ margin-block-end: 4px;
43
+ padding: 0;
44
+ color: var(--md-sys-color-on-surface-variant);
45
+ @include typescale("body-medium");
46
+ }
47
+
48
+ > label {
49
+ display: inline-flex;
50
+ gap: 0;
51
+ min-height: 0;
52
+ padding: 4px;
53
+ border-radius: 50%;
54
+ cursor: pointer;
55
+
56
+ &:has(> input:focus-visible) {
57
+ @include focus-ring;
58
+ }
59
+
60
+ &:has(> input:disabled) {
61
+ opacity: 0.38;
62
+ cursor: default;
63
+ }
64
+ }
65
+
66
+ > label > [type="radio"] {
67
+ flex: none;
68
+ width: var(--md-comp-rating-size);
69
+ height: var(--md-comp-rating-size);
70
+ border: 0;
71
+ border-radius: 0;
72
+ background-color: var(--md-comp-rating-empty-color);
73
+ background-image: none;
74
+ box-shadow: none;
75
+ mask: $_rating-star center / 100% no-repeat;
76
+ outline: 0;
77
+ transition: background-color 0.15s ease-out;
78
+
79
+ // The base radio draws its dot in :checked, :hover and the disabled
80
+ // states, some at a higher weight; the star mask would show it.
81
+ &:checked,
82
+ &:hover,
83
+ &:disabled,
84
+ &:disabled:checked {
85
+ border: 0;
86
+ background-image: none;
87
+ box-shadow: none;
88
+ }
89
+ }
90
+
91
+ // Filled: the checked star and every star before it.
92
+ > label:has(> :checked) > [type="radio"],
93
+ > label:has(~ label > :checked) > [type="radio"] {
94
+ background-color: var(--md-comp-rating-color);
95
+ }
96
+
97
+ // Hovering previews the rating under the pointer. Both rules sit under the
98
+ // same :has() so the preview outranks the reset.
99
+ &:has(> label:hover) {
100
+ > label > [type="radio"] {
101
+ background-color: var(--md-comp-rating-empty-color);
102
+ }
103
+
104
+ > label:hover > [type="radio"],
105
+ > label:has(~ label:hover) > [type="radio"] {
106
+ background-color: color-mix(in oklab, var(--md-comp-rating-color) 70%, transparent);
107
+ }
108
+ }
109
+
110
+ @media (prefers-reduced-motion: reduce) {
111
+ > label > [type="radio"] {
112
+ transition: none;
113
+ }
114
+ }
115
+ }
116
+
117
+ .rating:not(fieldset) {
118
+ --md-comp-rating-size: 20px;
119
+ --md-comp-rating-value: 0;
120
+ --md-comp-rating-max: 5;
121
+
122
+ display: inline-block;
123
+ width: calc(var(--md-comp-rating-size) * var(--md-comp-rating-max));
124
+ height: var(--md-comp-rating-size);
125
+ vertical-align: middle;
126
+ background: linear-gradient(
127
+ to right,
128
+ var(--md-comp-rating-color) calc(var(--md-comp-rating-value) / var(--md-comp-rating-max) * 100%),
129
+ var(--md-comp-rating-empty-color) 0
130
+ );
131
+ mask: $_rating-star left center / var(--md-comp-rating-size) repeat-x;
132
+
133
+ &:dir(rtl) {
134
+ background: linear-gradient(
135
+ to left,
136
+ var(--md-comp-rating-color) calc(var(--md-comp-rating-value) / var(--md-comp-rating-max) * 100%),
137
+ var(--md-comp-rating-empty-color) 0
138
+ );
139
+ mask-position: right center;
140
+ }
141
+ }
142
+
143
+ @media (forced-colors: active) {
144
+ fieldset.rating > label > [type="radio"],
145
+ .rating:not(fieldset) {
146
+ forced-color-adjust: none;
147
+ }
148
+
149
+ fieldset.rating > label > [type="radio"] {
150
+ background-color: GrayText;
151
+ }
152
+
153
+ fieldset.rating > label:has(> :checked) > [type="radio"],
154
+ fieldset.rating > label:has(~ label > :checked) > [type="radio"] {
155
+ background-color: Highlight;
156
+ }
157
+
158
+ .rating:not(fieldset) {
159
+ background: linear-gradient(
160
+ to right,
161
+ Highlight calc(var(--md-comp-rating-value) / var(--md-comp-rating-max) * 100%),
162
+ GrayText 0
163
+ );
164
+ }
165
+ }
@@ -54,7 +54,6 @@ input[type="range"] {
54
54
  --md-comp-slider-active-fraction: 0%;
55
55
  --md-comp-slider-start-fraction: 0%;
56
56
  --md-comp-slider-end-fraction: 100%;
57
- --md-comp-slider-stop-count: 6;
58
57
  }
59
58
 
60
59
  :is(#{$_host}) {
@@ -582,42 +581,65 @@ input[type="range"]:active:not(:disabled)::-moz-range-thumb {
582
581
  }
583
582
  }
584
583
 
585
- // Discrete stops. Dots along the active track; JS sets --stop-count.
586
- :is(#{$_host}).stops::after {
584
+ // Discrete stops. Dots on the active track, horizontal only. Stop k sits where
585
+ // the handle centre sits at min + k * step: handle / 2 + k * spacing from the
586
+ // input's start edge. JS writes --md-comp-slider-stop-spacing only for a usable
587
+ // step, and for a single input the handle position and track centre, on the
588
+ // host. Tiles repeat from the start edge with the dot half a handle in, and
589
+ // clip-path keeps the stretch from --_from to --_to, measured from that edge.
590
+ // Without a spacing the tile is 0px wide and nothing paints. A centered slider
591
+ // leaves out the dot on the midpoint; an inset icon hides the dots under it.
592
+ //
593
+ // WebKit rounds a background tile to whole device pixels, so at 1x its dot k
594
+ // drifts by k times that rounding. Every tiled image does this there, and the
595
+ // exact repeating-linear-gradient row has square dots. WebKit is outside the
596
+ // Chrome/Firefox baseline, so the dots stay round.
597
+ :is(#{$_host}).stops:not(.vertical)::after {
598
+ --_position: var(--md-comp-slider-active-position, var(--md-comp-slider-active-fraction));
599
+ --_start: calc(var(--_position) + var(--md-comp-slider-gap) + var(--md-comp-slider-handle-width) / 2);
600
+ --_end: calc(var(--_position) - var(--md-comp-slider-gap) - var(--md-comp-slider-handle-width) / 2);
601
+ --_from: 0px;
602
+ --_to: var(--_end);
603
+ --_icon: 0px;
604
+ --_dot: calc(var(--md-comp-slider-handle-width) / 2);
605
+
587
606
  content: "";
588
607
  position: absolute;
589
608
  z-index: 1;
590
609
  left: 0;
591
- top: 50%;
592
- width: max(
593
- 0px,
594
- calc(
595
- var(--md-comp-slider-active-position, var(--md-comp-slider-active-fraction)) - var(--md-comp-slider-gap) -
596
- var(--md-comp-slider-handle-width) / 2
597
- )
598
- );
610
+ top: var(--md-comp-slider-track-center, 50%);
611
+ width: 100%;
599
612
  height: var(--md-comp-slider-track-height);
600
613
  translate: 0 -50%;
601
614
  pointer-events: none;
602
- background-image: radial-gradient(
603
- circle var(--md-comp-slider-stop-size),
604
- var(--md-sys-color-on-primary) 99%,
605
- transparent
606
- );
607
- background-size: calc(100% / max(1, var(--md-comp-slider-stop-count) - 1)) 100%;
608
- background-repeat: repeat-x;
609
- background-position: center;
610
- }
611
-
612
- :is(#{$_host}).stops.centered::after {
613
- left: min(50%, var(--md-comp-slider-active-position, var(--md-comp-slider-active-fraction)));
614
- width: max(
615
- 0%,
616
- calc(
617
- abs(50% - var(--md-comp-slider-active-position, var(--md-comp-slider-active-fraction))) - var(--md-comp-slider-gap) -
618
- var(--md-comp-slider-handle-width) / 2
615
+ background: radial-gradient(
616
+ circle var(--md-comp-slider-stop-size) at var(--_dot) 50%,
617
+ var(--md-sys-color-on-primary) 99%,
618
+ transparent
619
619
  )
620
- );
620
+ 0 0 / var(--md-comp-slider-stop-spacing, 0px) 100% repeat-x;
621
+ // The inset icon stays on the left in both directions, so --_icon clips the left.
622
+ clip-path: inset(0 calc(100% - var(--_to)) 0 max(var(--_from), var(--_icon)));
623
+ }
624
+
625
+ // The input's direction, not the host's: it decides which end is min.
626
+ :is(#{$_host}).stops:not(.vertical):has([type="range"]:dir(rtl))::after {
627
+ --_dot: calc(100% - var(--md-comp-slider-handle-width) / 2);
628
+ background-position-x: right;
629
+ clip-path: inset(0 var(--_from) 0 max(calc(100% - var(--_to)), var(--_icon)));
630
+ }
631
+
632
+ :is(#{$_host}).stops.centered:not(.vertical)::after {
633
+ --_from: min(50% + var(--md-comp-slider-stop-size), var(--_start));
634
+ --_to: max(50% - var(--md-comp-slider-stop-size), var(--_end));
635
+ }
636
+
637
+ :is(#{$_host}).stops:not(.vertical):has(> #{$icon}:first-child)::after {
638
+ --_icon: calc(var(--md-comp-slider-stop-inset) + var(--md-comp-slider-icon-size));
639
+ }
640
+
641
+ :is(#{$_host}).stops:has(> [type="range"]:disabled)::after {
642
+ opacity: 0.38;
621
643
  }
622
644
 
623
645
  // Value label — 40dp, 4dp above the handle. JS inserts this after the input.
@@ -5,7 +5,7 @@
5
5
  // Anatomy is the HTML. A <label class="switch"> wrapping
6
6
  // <input type="checkbox"> is the control. The label text is a sibling of
7
7
  // the input — no .lever required. input + .lever and input + span still
8
- // work (legacy / BeerCSS).
8
+ // work (legacy).
9
9
  //
10
10
  // Tokens follow https://m3.material.io/components/switch/specs
11
11
  // track 52×32dp, 16dp corners
@@ -129,7 +129,7 @@
129
129
  cursor: default;
130
130
  }
131
131
 
132
- // Legacy / BeerCSS: input + .lever or input + span draws the same anatomy.
132
+ // Legacy: input + .lever or input + span draws the same anatomy.
133
133
  .switch [type="checkbox"] + .lever,
134
134
  .switch [type="checkbox"] + span {
135
135
  position: relative;
@@ -207,7 +207,7 @@
207
207
  cursor: default;
208
208
  }
209
209
 
210
- // BeerCSS: span holds the label text as well as the track.
210
+ // The span holds the label text as well as the track.
211
211
  .switch [type="checkbox"] + span:not(.lever):not(:empty) {
212
212
  width: auto;
213
213
  min-width: var(--md-comp-switch-track-width);
@@ -24,21 +24,9 @@
24
24
  // against #006495, the one source there is ground truth for - $md-source below
25
25
  // is a branding choice and is free to change without failing it.
26
26
 
27
- // The seed every generated ramp derives from. Chosen for a restaurant POS: the
28
- // error ramp is pinned at hue 27.7deg and both primary and tertiary (source
29
- // +62deg) derive from this, so the seed has to keep both clear of red. Warm
30
- // "appetising" hues (0-60deg) are disqualified outright - they put primary on
31
- // top of error, dEok 0.07-0.12 against ~0.28 here.
32
- //
33
- // Teal wins on *worst case* across both schemes rather than on either one
34
- // alone, which is the metric that matters: evening service runs dark mode in a
35
- // dim room, and that is where a confirm/void mix-up actually happens.
36
- // light primary40 vs error40 dEok 0.278
37
- // dark primary80 vs error80 dEok 0.212 <- best of the candidates
38
- // light tertiary40 vs error40 dEok 0.224
39
- // It also leaves green free for the "settled/paid" role a POS will want and
40
- // Material does not supply.
41
- $md-source: #006A79 !default;
27
+ // Mist Iris is the default seed for the generated ramps. Primary, secondary,
28
+ // tertiary and neutral colors derive from it; the error ramp stays fixed.
29
+ $md-source: #c6a0f6 !default;
42
30
 
43
31
  // tone -> OKLCH lightness. Fitted against the reference ramps; see the test.
44
32
  $tones: (