plass-ui 1.3.0 → 1.4.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 (340) hide show
  1. package/CHANGELOG.md +590 -0
  2. package/README.md +1 -1
  3. package/dist/components/alert/PlAlert.js +1 -1
  4. package/dist/components/anchor/PlAnchor.d.ts +72 -0
  5. package/dist/components/anchor/PlAnchor.js +1 -0
  6. package/dist/components/anchor/index.d.ts +2 -0
  7. package/dist/components/anchor/index.js +1 -0
  8. package/dist/components/animate-appear/PlAnimateAppear.d.ts +10 -0
  9. package/dist/components/animate-appear/PlAnimateAppear.js +1 -1
  10. package/dist/components/animate-blink/PlAnimateBlink.d.ts +2 -2
  11. package/dist/components/animate-blink/PlAnimateBlink.js +1 -1
  12. package/dist/components/animate-counter/PlAnimateCounter.d.ts +83 -0
  13. package/dist/components/animate-counter/PlAnimateCounter.js +1 -0
  14. package/dist/components/animate-counter/index.d.ts +2 -0
  15. package/dist/components/animate-counter/index.js +1 -0
  16. package/dist/components/animate-fade/PlAnimateFade.d.ts +2 -2
  17. package/dist/components/animate-fade/PlAnimateFade.js +1 -1
  18. package/dist/components/animate-float/PlAnimateFloat.d.ts +51 -0
  19. package/dist/components/animate-float/PlAnimateFloat.js +1 -0
  20. package/dist/components/animate-float/index.d.ts +2 -0
  21. package/dist/components/animate-float/index.js +1 -0
  22. package/dist/components/animate-grow/PlAnimateGrow.d.ts +2 -2
  23. package/dist/components/animate-grow/PlAnimateGrow.js +1 -1
  24. package/dist/components/animate-reveal/PlAnimateReveal.d.ts +51 -0
  25. package/dist/components/animate-reveal/PlAnimateReveal.js +1 -0
  26. package/dist/components/animate-reveal/index.d.ts +2 -0
  27. package/dist/components/animate-reveal/index.js +1 -0
  28. package/dist/components/animate-rotate/PlAnimateRotate.d.ts +2 -2
  29. package/dist/components/animate-rotate/PlAnimateRotate.js +1 -1
  30. package/dist/components/animate-scramble/PlAnimateScramble.d.ts +75 -0
  31. package/dist/components/animate-scramble/PlAnimateScramble.js +1 -0
  32. package/dist/components/animate-scramble/index.d.ts +2 -0
  33. package/dist/components/animate-scramble/index.js +1 -0
  34. package/dist/components/animate-shake/PlAnimateShake.d.ts +57 -0
  35. package/dist/components/animate-shake/PlAnimateShake.js +1 -0
  36. package/dist/components/animate-shake/index.d.ts +2 -0
  37. package/dist/components/animate-shake/index.js +1 -0
  38. package/dist/components/animate-slide/PlAnimateSlide.d.ts +2 -2
  39. package/dist/components/animate-slide/PlAnimateSlide.js +1 -1
  40. package/dist/components/animate-split/PlAnimateSplit.d.ts +54 -0
  41. package/dist/components/animate-split/PlAnimateSplit.js +1 -0
  42. package/dist/components/animate-split/index.d.ts +2 -0
  43. package/dist/components/animate-split/index.js +1 -0
  44. package/dist/components/animate-zoom/PlAnimateZoom.d.ts +2 -2
  45. package/dist/components/animate-zoom/PlAnimateZoom.js +1 -1
  46. package/dist/components/app-logo/PlAppLogo.d.ts +78 -0
  47. package/dist/components/app-logo/PlAppLogo.js +1 -0
  48. package/dist/components/app-logo/index.d.ts +2 -0
  49. package/dist/components/app-logo/index.js +1 -0
  50. package/dist/components/area-chart/PlAreaChart.d.ts +54 -0
  51. package/dist/components/area-chart/PlAreaChart.js +1 -0
  52. package/dist/components/area-chart/index.d.ts +2 -0
  53. package/dist/components/area-chart/index.js +1 -0
  54. package/dist/components/avatar/PlAvatar.js +1 -1
  55. package/dist/components/back-top/PlBackTop.js +1 -1
  56. package/dist/components/bar-chart/PlBarChart.d.ts +63 -0
  57. package/dist/components/bar-chart/PlBarChart.js +1 -0
  58. package/dist/components/bar-chart/index.d.ts +2 -0
  59. package/dist/components/bar-chart/index.js +1 -0
  60. package/dist/components/breadcrumb/PlBreadcrumb.js +1 -1
  61. package/dist/components/button-group/PlButtonGroup.js +1 -1
  62. package/dist/components/carousel/PlCarousel.js +1 -1
  63. package/dist/components/chat-bubble/PlChatBubble.js +1 -1
  64. package/dist/components/checkbox/PlCheckbox.js +1 -1
  65. package/dist/components/chip/PlChip.js +1 -1
  66. package/dist/components/code-block/PlCodeBlock.d.ts +175 -0
  67. package/dist/components/code-block/PlCodeBlock.js +1 -0
  68. package/dist/components/code-block/index.d.ts +2 -0
  69. package/dist/components/code-block/index.js +1 -0
  70. package/dist/components/combobox/PlCombobox.d.ts +1 -1
  71. package/dist/components/combobox/PlCombobox.js +1 -1
  72. package/dist/components/command-palette/PlCommandPalette.d.ts +1 -1
  73. package/dist/components/command-palette/PlCommandPalette.js +1 -1
  74. package/dist/components/container/PlContainer.d.ts +22 -6
  75. package/dist/components/container/PlContainer.js +1 -1
  76. package/dist/components/data-list/PlDataList.d.ts +74 -0
  77. package/dist/components/data-list/PlDataList.js +1 -0
  78. package/dist/components/data-list/index.d.ts +2 -0
  79. package/dist/components/data-list/index.js +1 -0
  80. package/dist/components/data-table/PlDataTable.d.ts +202 -0
  81. package/dist/components/data-table/PlDataTable.js +1 -0
  82. package/dist/components/data-table/index.d.ts +2 -0
  83. package/dist/components/data-table/index.js +1 -0
  84. package/dist/components/drawer/PlDrawer.d.ts +1 -1
  85. package/dist/components/drawer/PlDrawer.js +1 -1
  86. package/dist/components/flex/PlFlex.d.ts +83 -0
  87. package/dist/components/flex/PlFlex.js +1 -0
  88. package/dist/components/flex/index.d.ts +2 -0
  89. package/dist/components/flex/index.js +1 -0
  90. package/dist/components/floating-action-button/PlFloatingActionButton.d.ts +81 -0
  91. package/dist/components/floating-action-button/PlFloatingActionButton.js +1 -0
  92. package/dist/components/floating-action-button/index.d.ts +2 -0
  93. package/dist/components/floating-action-button/index.js +1 -0
  94. package/dist/components/footer/PlFooter.d.ts +4 -3
  95. package/dist/components/footer/PlFooter.js +1 -1
  96. package/dist/components/gallery/PlGallery.d.ts +154 -0
  97. package/dist/components/gallery/PlGallery.js +1 -0
  98. package/dist/components/gallery/PlGalleryViewer.d.ts +31 -0
  99. package/dist/components/gallery/PlGalleryViewer.js +1 -0
  100. package/dist/components/gallery/index.d.ts +2 -0
  101. package/dist/components/gallery/index.js +1 -0
  102. package/dist/components/gauge-chart/PlGaugeChart.d.ts +64 -0
  103. package/dist/components/gauge-chart/PlGaugeChart.js +1 -0
  104. package/dist/components/gauge-chart/index.d.ts +2 -0
  105. package/dist/components/gauge-chart/index.js +1 -0
  106. package/dist/components/grid/PlGrid.js +1 -1
  107. package/dist/components/grid/PlGridItem.js +1 -1
  108. package/dist/components/header/PlHeader.d.ts +4 -3
  109. package/dist/components/header/PlHeader.js +1 -1
  110. package/dist/components/heatmap-chart/PlHeatmapChart.d.ts +69 -0
  111. package/dist/components/heatmap-chart/PlHeatmapChart.js +1 -0
  112. package/dist/components/heatmap-chart/index.d.ts +2 -0
  113. package/dist/components/heatmap-chart/index.js +1 -0
  114. package/dist/components/hover-card/PlHoverCard.d.ts +94 -0
  115. package/dist/components/hover-card/PlHoverCard.js +1 -0
  116. package/dist/components/hover-card/index.d.ts +2 -0
  117. package/dist/components/hover-card/index.js +1 -0
  118. package/dist/components/how-to-steps/PlHowToSteps.d.ts +87 -0
  119. package/dist/components/how-to-steps/PlHowToSteps.js +1 -0
  120. package/dist/components/how-to-steps/index.d.ts +2 -0
  121. package/dist/components/how-to-steps/index.js +1 -0
  122. package/dist/components/image/PlImage.js +1 -1
  123. package/dist/components/line-chart/PlLineChart.d.ts +74 -0
  124. package/dist/components/line-chart/PlLineChart.js +1 -0
  125. package/dist/components/line-chart/index.d.ts +2 -0
  126. package/dist/components/line-chart/index.js +1 -0
  127. package/dist/components/meter/PlMeter.d.ts +83 -0
  128. package/dist/components/meter/PlMeter.js +1 -0
  129. package/dist/components/meter/index.d.ts +2 -0
  130. package/dist/components/meter/index.js +1 -0
  131. package/dist/components/mockup/PlMockup.d.ts +146 -0
  132. package/dist/components/mockup/PlMockup.js +1 -0
  133. package/dist/components/mockup/index.d.ts +2 -0
  134. package/dist/components/mockup/index.js +1 -0
  135. package/dist/components/modal/PlModal.d.ts +1 -1
  136. package/dist/components/modal/PlModal.js +1 -1
  137. package/dist/components/number-field/PlNumberField.d.ts +1 -1
  138. package/dist/components/number-field/PlNumberField.js +1 -1
  139. package/dist/components/overlay/PlOverlay.d.ts +1 -1
  140. package/dist/components/overlay/PlOverlay.js +1 -1
  141. package/dist/components/page-layout/PlPageLayout.js +1 -1
  142. package/dist/components/pagination/PlPagination.js +1 -1
  143. package/dist/components/panes/PlPanes.d.ts +2 -2
  144. package/dist/components/panes/PlPanes.js +1 -1
  145. package/dist/components/pie-chart/PlPieChart.d.ts +58 -0
  146. package/dist/components/pie-chart/PlPieChart.js +1 -0
  147. package/dist/components/pie-chart/index.d.ts +2 -0
  148. package/dist/components/pie-chart/index.js +1 -0
  149. package/dist/components/popconfirm/PlPopconfirm.d.ts +1 -1
  150. package/dist/components/popconfirm/PlPopconfirm.js +1 -1
  151. package/dist/components/popover/PlPopover.d.ts +1 -1
  152. package/dist/components/popover/PlPopover.js +1 -1
  153. package/dist/components/portal/PlPortal.d.ts +78 -0
  154. package/dist/components/portal/PlPortal.js +1 -0
  155. package/dist/components/portal/index.d.ts +2 -0
  156. package/dist/components/portal/index.js +1 -0
  157. package/dist/components/radio-group/PlRadioGroup.js +1 -1
  158. package/dist/components/rating/PlRating.js +1 -1
  159. package/dist/components/scatter-chart/PlScatterChart.d.ts +46 -0
  160. package/dist/components/scatter-chart/PlScatterChart.js +1 -0
  161. package/dist/components/scatter-chart/index.d.ts +2 -0
  162. package/dist/components/scatter-chart/index.js +1 -0
  163. package/dist/components/scroll-area/PlScrollArea.d.ts +98 -0
  164. package/dist/components/scroll-area/PlScrollArea.js +1 -0
  165. package/dist/components/scroll-area/index.d.ts +2 -0
  166. package/dist/components/scroll-area/index.js +1 -0
  167. package/dist/components/scroll-zone/PlScrollZone.d.ts +9 -5
  168. package/dist/components/scroll-zone/PlScrollZone.js +1 -1
  169. package/dist/components/select/PlSelect.js +1 -1
  170. package/dist/components/show/PlShow.d.ts +60 -0
  171. package/dist/components/show/PlShow.js +1 -0
  172. package/dist/components/show/index.d.ts +2 -0
  173. package/dist/components/show/index.js +1 -0
  174. package/dist/components/sidebar/PlSidebar.js +1 -1
  175. package/dist/components/slider/PlSlider.js +1 -1
  176. package/dist/components/sparkline/PlSparkline.d.ts +68 -0
  177. package/dist/components/sparkline/PlSparkline.js +1 -0
  178. package/dist/components/sparkline/index.d.ts +2 -0
  179. package/dist/components/sparkline/index.js +1 -0
  180. package/dist/components/spoiler/PlSpoiler.d.ts +8 -0
  181. package/dist/components/spoiler/PlSpoiler.js +1 -1
  182. package/dist/components/stack/PlStack.d.ts +114 -0
  183. package/dist/components/stack/PlStack.js +1 -0
  184. package/dist/components/stack/index.d.ts +2 -0
  185. package/dist/components/stack/index.js +1 -0
  186. package/dist/components/stepper/PlStepper.d.ts +2 -2
  187. package/dist/components/stepper/PlStepper.js +1 -1
  188. package/dist/components/table/PlTable.js +1 -1
  189. package/dist/components/tabs/PlTabs.d.ts +2 -2
  190. package/dist/components/tabs/PlTabs.js +1 -1
  191. package/dist/components/text-link/PlTextLink.js +1 -1
  192. package/dist/components/timeline/PlTimeline.d.ts +2 -2
  193. package/dist/components/timeline/PlTimeline.js +1 -1
  194. package/dist/components/timeline-chart/PlTimelineChart.d.ts +44 -0
  195. package/dist/components/timeline-chart/PlTimelineChart.js +1 -0
  196. package/dist/components/timeline-chart/index.d.ts +2 -0
  197. package/dist/components/timeline-chart/index.js +1 -0
  198. package/dist/components/toast/PlToast.d.ts +1 -1
  199. package/dist/components/toast/PlToast.js +1 -1
  200. package/dist/components/toggle/PlToggle.js +1 -1
  201. package/dist/components/toggle/PlToggleGroup.js +1 -1
  202. package/dist/components/tour/PlTour.d.ts +134 -0
  203. package/dist/components/tour/PlTour.js +1 -0
  204. package/dist/components/tour/index.d.ts +2 -0
  205. package/dist/components/tour/index.js +1 -0
  206. package/dist/components/transfer/PlTransfer.js +1 -1
  207. package/dist/components/tree/PlTree.js +1 -1
  208. package/dist/components/tree-select/PlTreeSelect.d.ts +99 -0
  209. package/dist/components/tree-select/PlTreeSelect.js +1 -0
  210. package/dist/components/tree-select/index.d.ts +2 -0
  211. package/dist/components/tree-select/index.js +1 -0
  212. package/dist/components/window-pane/PlWindowPane.d.ts +179 -0
  213. package/dist/components/window-pane/PlWindowPane.js +1 -0
  214. package/dist/components/window-pane/index.d.ts +2 -0
  215. package/dist/components/window-pane/index.js +1 -0
  216. package/dist/css/anchor.css +2 -0
  217. package/dist/css/animate-counter.css +2 -0
  218. package/dist/css/animate-float.css +2 -0
  219. package/dist/css/animate-reveal.css +2 -0
  220. package/dist/css/animate-scramble.css +2 -0
  221. package/dist/css/animate-shake.css +2 -0
  222. package/dist/css/animate-split.css +2 -0
  223. package/dist/css/app-logo.css +2 -0
  224. package/dist/css/area-chart.css +2 -0
  225. package/dist/css/bar-chart.css +2 -0
  226. package/dist/css/code-block.css +2 -0
  227. package/dist/css/data-list.css +2 -0
  228. package/dist/css/data-table.css +2 -0
  229. package/dist/css/flex.css +2 -0
  230. package/dist/css/floating-action-button.css +2 -0
  231. package/dist/css/gallery.css +2 -0
  232. package/dist/css/gauge-chart.css +2 -0
  233. package/dist/css/heatmap-chart.css +2 -0
  234. package/dist/css/hover-card.css +2 -0
  235. package/dist/css/how-to-steps.css +2 -0
  236. package/dist/css/line-chart.css +2 -0
  237. package/dist/css/meter.css +2 -0
  238. package/dist/css/mockup.css +2 -0
  239. package/dist/css/pie-chart.css +2 -0
  240. package/dist/css/portal.css +2 -0
  241. package/dist/css/scatter-chart.css +2 -0
  242. package/dist/css/scroll-area.css +2 -0
  243. package/dist/css/show.css +2 -0
  244. package/dist/css/sparkline.css +2 -0
  245. package/dist/css/stack.css +2 -0
  246. package/dist/css/timeline-chart.css +2 -0
  247. package/dist/css/tour.css +2 -0
  248. package/dist/css/tree-select.css +2 -0
  249. package/dist/css/window-pane.css +2 -0
  250. package/dist/hooks/index.d.ts +6 -0
  251. package/dist/hooks/index.js +1 -1
  252. package/dist/hooks/usePlBreakpoint.d.ts +3 -0
  253. package/dist/hooks/usePlBreakpoint.js +1 -1
  254. package/dist/hooks/usePlDisclosure.d.ts +44 -0
  255. package/dist/hooks/usePlDisclosure.js +1 -0
  256. package/dist/hooks/usePlElementSize.d.ts +31 -0
  257. package/dist/hooks/usePlElementSize.js +1 -0
  258. package/dist/hooks/usePlOnScreen.d.ts +50 -0
  259. package/dist/hooks/usePlOnScreen.js +1 -0
  260. package/dist/index.d.ts +34 -1
  261. package/dist/index.js +1 -1
  262. package/dist/internal/animate.d.ts +91 -5
  263. package/dist/internal/animate.js +1 -1
  264. package/dist/internal/breakpoints.d.ts +31 -0
  265. package/dist/internal/breakpoints.js +1 -0
  266. package/dist/internal/button-group.d.ts +29 -2
  267. package/dist/internal/button-group.js +2 -2
  268. package/dist/internal/calendar.d.ts +11 -36
  269. package/dist/internal/calendar.js +1 -1
  270. package/dist/internal/chart-frame.d.ts +458 -0
  271. package/dist/internal/chart-frame.js +1 -0
  272. package/dist/internal/chart-line.d.ts +44 -0
  273. package/dist/internal/chart-line.js +1 -0
  274. package/dist/internal/chart.d.ts +473 -0
  275. package/dist/internal/chart.js +1 -0
  276. package/dist/internal/data-table.d.ts +69 -0
  277. package/dist/internal/data-table.js +1 -0
  278. package/dist/internal/defaults.d.ts +8 -3
  279. package/dist/internal/drag.d.ts +49 -0
  280. package/dist/internal/drag.js +1 -0
  281. package/dist/internal/format.d.ts +2 -0
  282. package/dist/internal/format.js +1 -1
  283. package/dist/internal/gallery.d.ts +34 -0
  284. package/dist/internal/gallery.js +1 -0
  285. package/dist/internal/grid.d.ts +6 -27
  286. package/dist/internal/grid.js +1 -1
  287. package/dist/internal/highlight.d.ts +98 -0
  288. package/dist/internal/highlight.js +1 -0
  289. package/dist/internal/icons.d.ts +10 -0
  290. package/dist/internal/icons.js +1 -1
  291. package/dist/internal/labels.d.ts +138 -0
  292. package/dist/internal/labels.js +1 -0
  293. package/dist/internal/mockup.d.ts +193 -0
  294. package/dist/internal/mockup.js +1 -0
  295. package/dist/internal/page-layout.js +1 -1
  296. package/dist/internal/progress.d.ts +6 -0
  297. package/dist/internal/responsive.d.ts +108 -0
  298. package/dist/internal/responsive.js +1 -0
  299. package/dist/internal/scramble.d.ts +31 -0
  300. package/dist/internal/scramble.js +1 -0
  301. package/dist/internal/styles.d.ts +15 -0
  302. package/dist/internal/styles.js +1 -1
  303. package/dist/internal/table.d.ts +86 -0
  304. package/dist/internal/table.js +1 -0
  305. package/dist/internal/threshold.d.ts +19 -0
  306. package/dist/internal/threshold.js +1 -0
  307. package/dist/internal/tour.d.ts +42 -0
  308. package/dist/internal/tour.js +1 -0
  309. package/dist/internal/window.d.ts +201 -0
  310. package/dist/internal/window.js +1 -0
  311. package/dist/locales/de.d.ts +3 -0
  312. package/dist/locales/de.js +1 -0
  313. package/dist/locales/en.d.ts +2 -0
  314. package/dist/locales/en.js +1 -0
  315. package/dist/locales/es.d.ts +3 -0
  316. package/dist/locales/es.js +1 -0
  317. package/dist/locales/fr.d.ts +3 -0
  318. package/dist/locales/fr.js +1 -0
  319. package/dist/locales/index.d.ts +33 -0
  320. package/dist/locales/index.js +1 -0
  321. package/dist/locales/ja.d.ts +3 -0
  322. package/dist/locales/ja.js +1 -0
  323. package/dist/locales/ko.d.ts +3 -0
  324. package/dist/locales/ko.js +1 -0
  325. package/dist/locales/zh-Hans.d.ts +3 -0
  326. package/dist/locales/zh-Hans.js +1 -0
  327. package/dist/provider/index.d.ts +1 -0
  328. package/dist/provider/index.js +1 -1
  329. package/dist/styles.css +1 -1
  330. package/dist/tailwind.css +1104 -19
  331. package/dist/tokens.css +1104 -19
  332. package/dist/types.d.ts +381 -2
  333. package/package.json +14 -4
  334. package/dist/components/avatar-group/PlAvatarGroup.d.ts +0 -47
  335. package/dist/components/avatar-group/PlAvatarGroup.js +0 -1
  336. package/dist/components/avatar-group/index.d.ts +0 -2
  337. package/dist/components/avatar-group/index.js +0 -1
  338. package/dist/css/avatar-group.css +0 -2
  339. package/dist/internal/avatar-group.d.ts +0 -25
  340. package/dist/internal/avatar-group.js +0 -2
package/dist/tokens.css CHANGED
@@ -135,6 +135,43 @@
135
135
  --plass-info-on-solid: #ffffff;
136
136
  }
137
137
 
138
+ /* ---------------------------------------------------------------------------
139
+ * The breakpoint ladder
140
+ *
141
+ * Four widths, and **one place they are written down**. Everything in this
142
+ * library that changes with the width of the window reads them: the grid's
143
+ * `@variant` blocks below, the classes that keep a sidebar off a narrow screen,
144
+ * and the `matchMedia` queries `usePlBreakpoint` asks.
145
+ *
146
+ * They are Tailwind's own, which is the whole point — a layout decided by a
147
+ * `md:` utility and a layout decided by this library have to change at the same
148
+ * moment, or a page has two answers about how wide it is. So the source is
149
+ * Tailwind's `--breakpoint-*` theme, and a project that moves one moves both:
150
+ *
151
+ * @theme { --breakpoint-md: 50rem; }
152
+ *
153
+ * A media query's *condition* cannot read a custom property — `@media (width >=
154
+ * var(--x))` is not valid CSS and never will be — so the CSS half cannot follow
155
+ * a value set at runtime. It follows the theme at build time instead, through
156
+ * the `@variant` blocks, and these four tokens are how the **JavaScript** half
157
+ * reads the same answer: it is a value rather than a condition there, so it can
158
+ * be read off the document.
159
+ *
160
+ * The fallback is what makes them safe to read before Tailwind has resolved
161
+ * anything at all — a consumer on the precompiled `plass-ui/styles.css` has our
162
+ * values baked in, and these say what they are.
163
+ *
164
+ * Setting a `--plass-breakpoint-*` directly moves the JavaScript half **and not
165
+ * the CSS half**, which is almost never what anybody wants. Set Tailwind's.
166
+ * ------------------------------------------------------------------------- */
167
+
168
+ :root {
169
+ --plass-breakpoint-sm: var(--breakpoint-sm, 40rem);
170
+ --plass-breakpoint-md: var(--breakpoint-md, 48rem);
171
+ --plass-breakpoint-lg: var(--breakpoint-lg, 64rem);
172
+ --plass-breakpoint-xl: var(--breakpoint-xl, 80rem);
173
+ }
174
+
138
175
  /* ---------------------------------------------------------------------------
139
176
  * Light theme (default)
140
177
  *
@@ -268,6 +305,92 @@
268
305
  --plass-warning-accent: #96600c;
269
306
  --plass-danger-accent: #bb3339;
270
307
  --plass-info-accent: #1668ae;
308
+
309
+ /* Eight hues in a fixed order, and the one place in the library where a
310
+ colour is not a semantic role.
311
+
312
+ A series is an *entity* — a region, a plan, a competitor — and nothing
313
+ about it says success or danger. What the colour has to do is stay the same
314
+ colour when the chart is filtered, and be tellable apart from its
315
+ neighbours by every reader. So these are not the six families reused: those
316
+ were picked to mean something on a control, they are only six, and two of
317
+ them (`secondary`, `info`) sit close enough in hue that adjacent series
318
+ would collapse.
319
+
320
+ What the eight satisfy, measured against this file's own grounds rather
321
+ than asserted:
322
+
323
+ - every slot at 4:1 or better on white and 4.9:1 or better on the dark
324
+ sheet, so a 2px line is a line;
325
+ - adjacent pairs at least 10.4 apart in OKLab (×100) under simulated
326
+ protanopia and deuteranopia, which is the pair that touches in a stack
327
+ or a legend;
328
+ - chroma at or above 0.10, below which a hue reads as grey and stops
329
+ carrying identity at all.
330
+
331
+ The order is the mechanism, not a preference: slots are handed out in
332
+ sequence and never cycled, which is what keeps the *adjacent* pairs the
333
+ ones that were checked. A ninth series is not a ninth colour; it is an
334
+ "Other" row, or a second chart.
335
+
336
+ Slot one is the page's own `primary`, not a solved hue like the rest — a
337
+ one-series chart should look like it belongs to the page it is on. It is
338
+ the one slot louder than its neighbours (4.9:1 against their 4:1), and
339
+ that is the price. */
340
+ --plass-chart-1: #3f63f2;
341
+ --plass-chart-2: #cf5c00;
342
+ --plass-chart-3: #e23895;
343
+ --plass-chart-4: #997b00;
344
+ --plass-chart-5: #0288b8;
345
+ --plass-chart-6: #039227;
346
+ --plass-chart-7: #a657ed;
347
+ --plass-chart-8: #058f80;
348
+
349
+ /* The sequential ramp — one hue, light to dark, for a mark whose colour is a
350
+ *magnitude* rather than an identity.
351
+
352
+ A different job from the eight above and so a different set, not a subset
353
+ of them. The eight are solved to be as far apart as possible, which is
354
+ exactly what a magnitude must not be: a heatmap coloured from a categorical
355
+ ramp says its cells are five unrelated things. Here the order is the whole
356
+ meaning, so what is solved for is the opposite — one hue throughout,
357
+ lightness strictly falling, and the palest step still at 2.07:1 on the
358
+ sheet, because below that the low end of the scale reads as empty rather
359
+ than as small.
360
+
361
+ Five steps and not a continuous gradient, because a reader cannot rank a
362
+ continuum by eye and can rank five steps against a legend. */
363
+ --plass-chart-seq-1: #95b5ee;
364
+ --plass-chart-seq-2: #6e9aec;
365
+ --plass-chart-seq-3: #477ee8;
366
+ --plass-chart-seq-4: #2763d7;
367
+ --plass-chart-seq-5: #1346ab;
368
+
369
+ /* And the diverging ramp, for a value with a **middle** — a change against
370
+ last quarter, a temperature against the average. Two hues away from a pale
371
+ neutral, so which side of zero a cell is on is the first thing read and how
372
+ far from it the second. The neutral is not white: a cell at zero is a
373
+ reading, and a white cell is a hole in the grid. */
374
+ --plass-chart-div-1: #055d7e;
375
+ --plass-chart-div-2: #2095c5;
376
+ --plass-chart-div-3: #b1b4b9;
377
+ --plass-chart-div-4: #d4614c;
378
+ --plass-chart-div-5: #9a210c;
379
+
380
+ /* What is legible written *on* a ramp step, which flips partway down both.
381
+ A heatmap that writes its numbers in the cells needs this and nothing else
382
+ does. */
383
+ --plass-chart-seq-on-1: var(--plass-fg);
384
+ --plass-chart-seq-on-2: var(--plass-fg);
385
+ --plass-chart-seq-on-3: var(--plass-fg);
386
+ --plass-chart-seq-on-4: var(--plass-surface);
387
+ --plass-chart-seq-on-5: var(--plass-surface);
388
+
389
+ --plass-chart-div-on-1: var(--plass-surface);
390
+ --plass-chart-div-on-2: var(--plass-fg);
391
+ --plass-chart-div-on-3: var(--plass-fg);
392
+ --plass-chart-div-on-4: var(--plass-fg);
393
+ --plass-chart-div-on-5: var(--plass-surface);
271
394
  }
272
395
 
273
396
  /* ---------------------------------------------------------------------------
@@ -322,6 +445,39 @@
322
445
  --plass-warning-accent: #f2b74e;
323
446
  --plass-danger-accent: #ff8a8f;
324
447
  --plass-info-accent: #5fb4ee;
448
+
449
+ --plass-chart-1: #93a8ff;
450
+ --plass-chart-2: #e66700;
451
+ --plass-chart-3: #ef45a0;
452
+ --plass-chart-4: #b08e05;
453
+ --plass-chart-5: #049fd6;
454
+ --plass-chart-6: #07b031;
455
+ --plass-chart-7: #b264fb;
456
+ --plass-chart-8: #02a998;
457
+
458
+ --plass-chart-seq-1: #294c91;
459
+ --plass-chart-seq-2: #3263c3;
460
+ --plass-chart-seq-3: #3f7cf3;
461
+ --plass-chart-seq-4: #6a9cfb;
462
+ --plass-chart-seq-5: #9ebef8;
463
+
464
+ --plass-chart-div-1: #066082;
465
+ --plass-chart-div-2: #0892c4;
466
+ --plass-chart-div-3: #aeb1b6;
467
+ --plass-chart-div-4: #d15e49;
468
+ --plass-chart-div-5: #9a2b19;
469
+
470
+ --plass-chart-seq-on-1: var(--plass-fg);
471
+ --plass-chart-seq-on-2: var(--plass-fg);
472
+ --plass-chart-seq-on-3: var(--plass-surface);
473
+ --plass-chart-seq-on-4: var(--plass-surface);
474
+ --plass-chart-seq-on-5: var(--plass-surface);
475
+
476
+ --plass-chart-div-on-1: var(--plass-fg);
477
+ --plass-chart-div-on-2: var(--plass-surface);
478
+ --plass-chart-div-on-3: var(--plass-surface);
479
+ --plass-chart-div-on-4: var(--plass-surface);
480
+ --plass-chart-div-on-5: var(--plass-fg);
325
481
  }
326
482
  }
327
483
 
@@ -366,6 +522,39 @@
366
522
  --plass-warning-accent: #f2b74e;
367
523
  --plass-danger-accent: #ff8a8f;
368
524
  --plass-info-accent: #5fb4ee;
525
+
526
+ --plass-chart-1: #93a8ff;
527
+ --plass-chart-2: #e66700;
528
+ --plass-chart-3: #ef45a0;
529
+ --plass-chart-4: #b08e05;
530
+ --plass-chart-5: #049fd6;
531
+ --plass-chart-6: #07b031;
532
+ --plass-chart-7: #b264fb;
533
+ --plass-chart-8: #02a998;
534
+
535
+ --plass-chart-seq-1: #294c91;
536
+ --plass-chart-seq-2: #3263c3;
537
+ --plass-chart-seq-3: #3f7cf3;
538
+ --plass-chart-seq-4: #6a9cfb;
539
+ --plass-chart-seq-5: #9ebef8;
540
+
541
+ --plass-chart-div-1: #066082;
542
+ --plass-chart-div-2: #0892c4;
543
+ --plass-chart-div-3: #aeb1b6;
544
+ --plass-chart-div-4: #d15e49;
545
+ --plass-chart-div-5: #9a2b19;
546
+
547
+ --plass-chart-seq-on-1: var(--plass-fg);
548
+ --plass-chart-seq-on-2: var(--plass-fg);
549
+ --plass-chart-seq-on-3: var(--plass-surface);
550
+ --plass-chart-seq-on-4: var(--plass-surface);
551
+ --plass-chart-seq-on-5: var(--plass-surface);
552
+
553
+ --plass-chart-div-on-1: var(--plass-fg);
554
+ --plass-chart-div-on-2: var(--plass-surface);
555
+ --plass-chart-div-on-3: var(--plass-surface);
556
+ --plass-chart-div-on-4: var(--plass-surface);
557
+ --plass-chart-div-on-5: var(--plass-fg);
369
558
  }
370
559
 
371
560
  /* ---------------------------------------------------------------------------
@@ -508,6 +697,24 @@
508
697
  --plass-info-line: color-mix(in srgb, var(--plass-info-accent) 30%, transparent);
509
698
  --plass-info-line-hover: color-mix(in srgb, var(--plass-info-accent) 48%, transparent);
510
699
  --plass-info-ring: color-mix(in srgb, var(--plass-info-solid) 55%, transparent);
700
+ /* The three greys a chart draws its frame with, derived so a project that
701
+ re-tones its border moves the grid with it.
702
+
703
+ The grid is the faintest thing on the plot on purpose: a gridline that
704
+ competes with a data line is a reader deciding which is which. The axis is
705
+ the border at full strength, because it is the edge of the picture rather
706
+ than a reading. And the baseline is allowed to be darker than either — it
707
+ is where a bar starts from and where zero is, which is a fact about the
708
+ data rather than furniture. */
709
+ --plass-chart-grid: color-mix(in srgb, var(--plass-border) 70%, transparent);
710
+ --plass-chart-axis: var(--plass-border);
711
+ --plass-chart-baseline: color-mix(in srgb, var(--plass-muted-fg) 35%, transparent);
712
+ /* And the sheet itself, for the 2px between two marks that touch — a
713
+ marker's ring, the seam between two stacked bands, the halo round a
714
+ scatter's dot. It is the surface and not a stroke, because a coloured line
715
+ drawn between two marks is ink that is not data; what separates them is the
716
+ page showing through. */
717
+ --plass-chart-gap: var(--plass-surface);
511
718
  }
512
719
 
513
720
  /* ---------------------------------------------------------------------------
@@ -803,7 +1010,152 @@
803
1010
  }
804
1011
 
805
1012
  /* ---------------------------------------------------------------------------
806
- * The grid
1013
+ * A strip that runs off the end of its own box
1014
+ *
1015
+ * A row that scrolls has to say so, and on a Mac it cannot: the scrollbar is an
1016
+ * overlay that appears while the strip is moving and is invisible the rest of
1017
+ * the time, which is every moment a reader is deciding whether there is
1018
+ * anything more to look at. On Windows the same bar is fifteen pixels of
1019
+ * permanent furniture under a row of tab labels. Neither is a signal, so both
1020
+ * are taken away and the ends are faded instead — and *only* the end that still
1021
+ * has something behind it, which is the part that makes it a signal rather than
1022
+ * a decoration.
1023
+ *
1024
+ * The fade is a `mask-image` rather than two gradient overlays because a bar
1025
+ * can sit on anything. An overlay has to be painted in the colour of whatever
1026
+ * is behind the strip, and a component does not know that: a `PlTabs` inside a
1027
+ * `PlCard` inside a tinted section has three candidate backgrounds and no way
1028
+ * to choose. A mask takes the pixels away instead, so whatever is behind shows
1029
+ * through and the answer is right on every surface.
1030
+ *
1031
+ * The two lengths are per-instance slots because *which* end fades is measured
1032
+ * rather than declared — it depends on how far along the strip is, which no
1033
+ * prop can know. `0px` on both ends is a gradient with no transition in it at
1034
+ * all, so a strip that fits is not paying for a mask it does not need.
1035
+ *
1036
+ * They are physical (`left`, `right`) while the state the component publishes
1037
+ * is logical, and the split is the same one `PlTabs` already makes for its
1038
+ * indicator: a CSS gradient runs in a physical direction and a reader runs in
1039
+ * a writing direction, so the measurement is turned round once, here, rather
1040
+ * than in four places that could disagree.
1041
+ *
1042
+ * The mask is dropped entirely while something inside holds a visible focus
1043
+ * ring. Focusing a tab scrolls it flush against the edge it came from, which is
1044
+ * exactly where the fade is strongest — so the one control whose outline has to
1045
+ * be legible would be the one drawn half transparent. `:focus-visible` and not
1046
+ * `:focus-within`: a tab that was clicked has the focus and no ring, and a bar
1047
+ * that stopped fading for the rest of the session because somebody pressed a
1048
+ * tab would have lost the signal at the first interaction.
1049
+ * ------------------------------------------------------------------------- */
1050
+
1051
+ .plass-fade-x {
1052
+ --p-fade: 1.5rem;
1053
+
1054
+ scrollbar-width: none;
1055
+ mask-image: linear-gradient(
1056
+ to right,
1057
+ transparent,
1058
+ #000 var(--p-fade-left, 0px),
1059
+ #000 calc(100% - var(--p-fade-right, 0px)),
1060
+ transparent
1061
+ );
1062
+ }
1063
+
1064
+ .plass-fade-x::-webkit-scrollbar {
1065
+ display: none;
1066
+ }
1067
+
1068
+ .plass-fade-x:has(:focus-visible) {
1069
+ mask-image: none;
1070
+ }
1071
+
1072
+ /* ---------------------------------------------------------------------------
1073
+ * Showing something at some widths and not others
1074
+ *
1075
+ * `PlShow`, and the reason it is CSS rather than a `useMediaQuery` and a
1076
+ * ternary. A media query answered in JavaScript is `false` on a server and on
1077
+ * the first frame a browser renders, so a JavaScript gate draws the wrong half
1078
+ * and then throws it away — a flash on every page load rather than an edge
1079
+ * case. The stylesheet knows the width before React has been asked anything.
1080
+ *
1081
+ * `display: contents` while it is showing, so the element is **not a box**: its
1082
+ * children take part in the parent's layout exactly as they would have without
1083
+ * it, and a gate inside a flex row does not become a flex item. `display: none`
1084
+ * is what hides, which also takes the subtree off the accessibility tree — a
1085
+ * gate that only moved it off screen would leave a screen reader reading both
1086
+ * halves of a responsive layout.
1087
+ *
1088
+ * Attribute selectors rather than Tailwind's `max-md:hidden`, and that is not a
1089
+ * preference: the real classes in this file are emitted *after* the utilities so
1090
+ * they can outrank them, which would make a `display: contents` here beat the
1091
+ * very variant meant to hide it. Nine rules that only fight each other are
1092
+ * simpler than one that has to win a sort it does not control.
1093
+ *
1094
+ * Both bounds at once is `[data-from]` and `[data-until]` on one element, and
1095
+ * it resolves by source order: the `from` rules come first, so a rung at or
1096
+ * above `until` is hidden by the later rule whatever `from` said.
1097
+ * ------------------------------------------------------------------------- */
1098
+
1099
+ .plass-show {
1100
+ display: contents;
1101
+ }
1102
+
1103
+ /* Below its floor, a gate with a `from` is closed. Each rung then opens it. */
1104
+ .plass-show[data-from] {
1105
+ display: none;
1106
+ }
1107
+
1108
+ @variant sm {
1109
+ .plass-show[data-from='sm'] {
1110
+ display: contents;
1111
+ }
1112
+ }
1113
+
1114
+ @variant md {
1115
+ .plass-show[data-from='md'] {
1116
+ display: contents;
1117
+ }
1118
+ }
1119
+
1120
+ @variant lg {
1121
+ .plass-show[data-from='lg'] {
1122
+ display: contents;
1123
+ }
1124
+ }
1125
+
1126
+ @variant xl {
1127
+ .plass-show[data-from='xl'] {
1128
+ display: contents;
1129
+ }
1130
+ }
1131
+
1132
+ /* And `until` closes it again from its own rung up. */
1133
+ @variant sm {
1134
+ .plass-show[data-until='sm'] {
1135
+ display: none;
1136
+ }
1137
+ }
1138
+
1139
+ @variant md {
1140
+ .plass-show[data-until='md'] {
1141
+ display: none;
1142
+ }
1143
+ }
1144
+
1145
+ @variant lg {
1146
+ .plass-show[data-until='lg'] {
1147
+ display: none;
1148
+ }
1149
+ }
1150
+
1151
+ @variant xl {
1152
+ .plass-show[data-until='xl'] {
1153
+ display: none;
1154
+ }
1155
+ }
1156
+
1157
+ /* ---------------------------------------------------------------------------
1158
+ * The grid, and the responsive slots
807
1159
  *
808
1160
  * `PlGrid` is a flex row and `PlGridItem` is a width in it, which is the shape
809
1161
  * a twelve-column grid has had since long before CSS had one of its own — and
@@ -825,16 +1177,49 @@
825
1177
  * chains get long at `xl`; that is the cost of keeping the DOM lean, and it is
826
1178
  * paid once here rather than on every grid item in a consumer's app.
827
1179
  *
828
- * The widths are Tailwind's own breakpoints, so a Plass grid and an `md:`
829
- * utility change at the same moment.
1180
+ * The widths are Tailwind's own breakpoints `@variant` rather than a written
1181
+ * out `@media`, so a project that moves one in its theme moves this with it.
1182
+ * See "The breakpoint ladder" above.
1183
+ *
1184
+ * `.plass-container`'s measure and `.plass-flex`'s axis ride the same four
1185
+ * blocks, and any responsive prop added later should too. That is the whole
1186
+ * cost of one: a slot in `internal/responsive.ts` and four lines here. CSS has
1187
+ * no loop, so four lines is the floor — which is the reason to keep the number
1188
+ * of responsive props deliberate rather than to make every prop responsive
1189
+ * because it could be.
1190
+ *
1191
+ * The two gutters are declared for `.plass-grid` and `.plass-flex` together.
1192
+ * They are one question asked by two components — the space *between* the
1193
+ * things in a box — and a second copy of the chain is a second place for it to
1194
+ * drift.
830
1195
  * ------------------------------------------------------------------------- */
831
1196
 
832
- .plass-grid {
833
- --p-cols: var(--p-cols-xs, 12);
1197
+ .plass-grid,
1198
+ .plass-flex {
834
1199
  --p-gap-x: var(--p-gap-x-xs, 0px);
835
1200
  --p-gap-y: var(--p-gap-y-xs, 0px);
836
1201
  }
837
1202
 
1203
+ .plass-grid {
1204
+ --p-cols: var(--p-cols-xs, 12);
1205
+ }
1206
+
1207
+ .plass-gallery {
1208
+ --p-cols: var(--p-cols-xs, 2);
1209
+ }
1210
+
1211
+ /*
1212
+ * `PlFlex`'s axis. One slot rather than two, because `reverse` is not
1213
+ * responsive and the direction is: the component folds the two into the four
1214
+ * values `flex-direction` takes, so a breakpoint changes the axis without
1215
+ * having to restate which end it starts from.
1216
+ */
1217
+ .plass-flex {
1218
+ --p-dir: var(--p-dir-xs, row);
1219
+
1220
+ flex-direction: var(--p-dir);
1221
+ }
1222
+
838
1223
  .plass-grid-item {
839
1224
  --p-span: var(--p-span-xs, var(--p-cols, 12));
840
1225
  --p-offset: var(--p-offset-xs, 0);
@@ -853,39 +1238,102 @@
853
1238
  margin-inline-start: calc(var(--p-track) * min(var(--p-offset), var(--p-cols, 12)));
854
1239
  }
855
1240
 
856
- @media (width >= 40rem) {
857
- .plass-grid {
858
- --p-cols: var(--p-cols-sm, var(--p-cols-xs, 12));
1241
+ /*
1242
+ * The measure, and the one thing a container draws.
1243
+ *
1244
+ * A slot rather than five `max-w-*` classes, because a responsive measure would
1245
+ * otherwise be five classes times five rungs. It also takes any length a caller
1246
+ * writes, which the class ladder could not: `maxWidth="72ch"` is a measure in
1247
+ * characters, and a measure in characters is the one a paragraph actually
1248
+ * wants.
1249
+ */
1250
+ .plass-container {
1251
+ --p-maxw: var(--p-maxw-xs, none);
1252
+
1253
+ max-width: var(--p-maxw);
1254
+ }
1255
+
1256
+ @variant sm {
1257
+ .plass-container {
1258
+ --p-maxw: var(--p-maxw-sm, var(--p-maxw-xs, none));
1259
+ }
1260
+
1261
+ .plass-grid,
1262
+ .plass-flex {
859
1263
  --p-gap-x: var(--p-gap-x-sm, var(--p-gap-x-xs, 0px));
860
1264
  --p-gap-y: var(--p-gap-y-sm, var(--p-gap-y-xs, 0px));
861
1265
  }
862
1266
 
1267
+ .plass-grid {
1268
+ --p-cols: var(--p-cols-sm, var(--p-cols-xs, 12));
1269
+ }
1270
+
1271
+ .plass-gallery {
1272
+ --p-cols: var(--p-cols-sm, var(--p-cols-xs, 2));
1273
+ }
1274
+
1275
+ .plass-flex {
1276
+ --p-dir: var(--p-dir-sm, var(--p-dir-xs, row));
1277
+ }
1278
+
863
1279
  .plass-grid-item {
864
1280
  --p-span: var(--p-span-sm, var(--p-span-xs, var(--p-cols, 12)));
865
1281
  --p-offset: var(--p-offset-sm, var(--p-offset-xs, 0));
866
1282
  }
867
1283
  }
868
1284
 
869
- @media (width >= 48rem) {
870
- .plass-grid {
871
- --p-cols: var(--p-cols-md, var(--p-cols-sm, var(--p-cols-xs, 12)));
1285
+ @variant md {
1286
+ .plass-container {
1287
+ --p-maxw: var(--p-maxw-md, var(--p-maxw-sm, var(--p-maxw-xs, none)));
1288
+ }
1289
+
1290
+ .plass-grid,
1291
+ .plass-flex {
872
1292
  --p-gap-x: var(--p-gap-x-md, var(--p-gap-x-sm, var(--p-gap-x-xs, 0px)));
873
1293
  --p-gap-y: var(--p-gap-y-md, var(--p-gap-y-sm, var(--p-gap-y-xs, 0px)));
874
1294
  }
875
1295
 
1296
+ .plass-grid {
1297
+ --p-cols: var(--p-cols-md, var(--p-cols-sm, var(--p-cols-xs, 12)));
1298
+ }
1299
+
1300
+ .plass-gallery {
1301
+ --p-cols: var(--p-cols-md, var(--p-cols-sm, var(--p-cols-xs, 2)));
1302
+ }
1303
+
1304
+ .plass-flex {
1305
+ --p-dir: var(--p-dir-md, var(--p-dir-sm, var(--p-dir-xs, row)));
1306
+ }
1307
+
876
1308
  .plass-grid-item {
877
1309
  --p-span: var(--p-span-md, var(--p-span-sm, var(--p-span-xs, var(--p-cols, 12))));
878
1310
  --p-offset: var(--p-offset-md, var(--p-offset-sm, var(--p-offset-xs, 0)));
879
1311
  }
880
1312
  }
881
1313
 
882
- @media (width >= 64rem) {
883
- .plass-grid {
884
- --p-cols: var(--p-cols-lg, var(--p-cols-md, var(--p-cols-sm, var(--p-cols-xs, 12))));
1314
+ @variant lg {
1315
+ .plass-container {
1316
+ --p-maxw: var(--p-maxw-lg, var(--p-maxw-md, var(--p-maxw-sm, var(--p-maxw-xs, none))));
1317
+ }
1318
+
1319
+ .plass-grid,
1320
+ .plass-flex {
885
1321
  --p-gap-x: var(--p-gap-x-lg, var(--p-gap-x-md, var(--p-gap-x-sm, var(--p-gap-x-xs, 0px))));
886
1322
  --p-gap-y: var(--p-gap-y-lg, var(--p-gap-y-md, var(--p-gap-y-sm, var(--p-gap-y-xs, 0px))));
887
1323
  }
888
1324
 
1325
+ .plass-grid {
1326
+ --p-cols: var(--p-cols-lg, var(--p-cols-md, var(--p-cols-sm, var(--p-cols-xs, 12))));
1327
+ }
1328
+
1329
+ .plass-gallery {
1330
+ --p-cols: var(--p-cols-lg, var(--p-cols-md, var(--p-cols-sm, var(--p-cols-xs, 2))));
1331
+ }
1332
+
1333
+ .plass-flex {
1334
+ --p-dir: var(--p-dir-lg, var(--p-dir-md, var(--p-dir-sm, var(--p-dir-xs, row))));
1335
+ }
1336
+
889
1337
  .plass-grid-item {
890
1338
  --p-span: var(
891
1339
  --p-span-lg,
@@ -895,12 +1343,16 @@
895
1343
  }
896
1344
  }
897
1345
 
898
- @media (width >= 80rem) {
899
- .plass-grid {
900
- --p-cols: var(
901
- --p-cols-xl,
902
- var(--p-cols-lg, var(--p-cols-md, var(--p-cols-sm, var(--p-cols-xs, 12))))
1346
+ @variant xl {
1347
+ .plass-container {
1348
+ --p-maxw: var(
1349
+ --p-maxw-xl,
1350
+ var(--p-maxw-lg, var(--p-maxw-md, var(--p-maxw-sm, var(--p-maxw-xs, none))))
903
1351
  );
1352
+ }
1353
+
1354
+ .plass-grid,
1355
+ .plass-flex {
904
1356
  --p-gap-x: var(
905
1357
  --p-gap-x-xl,
906
1358
  var(--p-gap-x-lg, var(--p-gap-x-md, var(--p-gap-x-sm, var(--p-gap-x-xs, 0px))))
@@ -911,6 +1363,27 @@
911
1363
  );
912
1364
  }
913
1365
 
1366
+ .plass-grid {
1367
+ --p-cols: var(
1368
+ --p-cols-xl,
1369
+ var(--p-cols-lg, var(--p-cols-md, var(--p-cols-sm, var(--p-cols-xs, 12))))
1370
+ );
1371
+ }
1372
+
1373
+ .plass-gallery {
1374
+ --p-cols: var(
1375
+ --p-cols-xl,
1376
+ var(--p-cols-lg, var(--p-cols-md, var(--p-cols-sm, var(--p-cols-xs, 2))))
1377
+ );
1378
+ }
1379
+
1380
+ .plass-flex {
1381
+ --p-dir: var(
1382
+ --p-dir-xl,
1383
+ var(--p-dir-lg, var(--p-dir-md, var(--p-dir-sm, var(--p-dir-xs, row))))
1384
+ );
1385
+ }
1386
+
914
1387
  .plass-grid-item {
915
1388
  --p-span: var(
916
1389
  --p-span-xl,
@@ -960,6 +1433,34 @@
960
1433
  animation-play-state: var(--p-anim-state, running);
961
1434
  }
962
1435
 
1436
+ /*
1437
+ * `timeline="view"`, and the whole of it.
1438
+ *
1439
+ * Two declarations give **every** keyframe in this file a scroll-linked mode:
1440
+ * the effect stops being a thing that happens at a moment and becomes a thing
1441
+ * that tracks where the element is in the scrollport. There is no component for
1442
+ * it and there should not be, because there is nothing a component would add —
1443
+ * an effect already knows what it draws, and this only changes what advances
1444
+ * it.
1445
+ *
1446
+ * `@supports` is not optional. `animation-timeline` is progressively enhanced
1447
+ * and an engine that does not know the property would drop these two lines but
1448
+ * keep the `animation-duration` above, which is the *right* fallback: a clock
1449
+ * plays the effect once and the content arrives. Handing an unsupported browser
1450
+ * a timeline it cannot resolve is what would leave a blank page. Degraded is
1451
+ * allowed; blank is not.
1452
+ *
1453
+ * The slots are only filled when a caller asks for `view`, so the default costs
1454
+ * nothing at all: `auto` is what the property already resolves to, and writing
1455
+ * it into a hundred inline styles would be a hundred copies of the same answer.
1456
+ */
1457
+ @supports (animation-timeline: view()) {
1458
+ .plass-anim {
1459
+ animation-timeline: var(--p-anim-timeline, auto);
1460
+ animation-range: var(--p-anim-range, normal);
1461
+ }
1462
+ }
1463
+
963
1464
  @keyframes plass-anim-fade {
964
1465
  from {
965
1466
  opacity: var(--p-anim-opacity, 0);
@@ -990,6 +1491,36 @@
990
1491
  animation-name: plass-anim-scale;
991
1492
  }
992
1493
 
1494
+ /*
1495
+ * The one entrance that moves nothing and changes no colour.
1496
+ *
1497
+ * `clip-path` rather than a mask or an `overflow` box, and the choice is worth
1498
+ * writing down because the alternatives look equivalent. A mask needs a
1499
+ * gradient that has to be kept in step with the direction; an `overflow`
1500
+ * wrapper puts a second element into the layout, which is exactly what an
1501
+ * effect for something whose *position* is the information must not do. And
1502
+ * `inset(0)` already means "nothing is cut off", so the to-state is the
1503
+ * element's own natural one rather than a number that has to be chosen.
1504
+ *
1505
+ * The opacity slot defaults to `1` here and to `0` everywhere else in this
1506
+ * file. A reveal is not a fade — the whole reason to reach for it is that the
1507
+ * ink does not change — so fading is opt-in rather than something to turn off.
1508
+ */
1509
+ @keyframes plass-anim-reveal {
1510
+ from {
1511
+ opacity: var(--p-anim-opacity, 1);
1512
+ clip-path: var(--p-anim-clip, inset(0 100% 0 0));
1513
+ }
1514
+ to {
1515
+ opacity: 1;
1516
+ clip-path: inset(0);
1517
+ }
1518
+ }
1519
+
1520
+ .plass-anim-reveal {
1521
+ animation-name: plass-anim-reveal;
1522
+ }
1523
+
993
1524
  @keyframes plass-anim-slide {
994
1525
  from {
995
1526
  opacity: var(--p-anim-opacity, 0);
@@ -1038,6 +1569,67 @@
1038
1569
  animation-name: plass-anim-blink;
1039
1570
  }
1040
1571
 
1572
+ /*
1573
+ * A refusal.
1574
+ *
1575
+ * Three shudders either side of home and back to nothing, so an element that
1576
+ * has been shaken is exactly where it was — this is the one effect in the file
1577
+ * that a caller will run over content that is still being typed into, and a
1578
+ * field left a few pixels off its label would be worse than the error it was
1579
+ * reporting.
1580
+ *
1581
+ * Not one of the entrances, and not in `PlassAnimation`, for `plass-anim-float`'s
1582
+ * reason: that union is the set of ways content can *arrive*, and a response to
1583
+ * something a reader did is not an arrival.
1584
+ */
1585
+ @keyframes plass-anim-shake {
1586
+ 0%,
1587
+ 100% {
1588
+ translate: 0 0;
1589
+ }
1590
+ 15%,
1591
+ 45%,
1592
+ 75% {
1593
+ translate: calc(var(--p-anim-x, 6px) * -1) 0;
1594
+ }
1595
+ 30%,
1596
+ 60%,
1597
+ 90% {
1598
+ translate: var(--p-anim-x, 6px) 0;
1599
+ }
1600
+ }
1601
+
1602
+ .plass-anim-shake {
1603
+ animation-name: plass-anim-shake;
1604
+ }
1605
+
1606
+ /*
1607
+ * An endless drift.
1608
+ *
1609
+ * Symmetric like the blink above and for the same reason: however many times it
1610
+ * runs it ends where it started, so a float that was stopped mid-cycle does not
1611
+ * leave the element permanently a few pixels out of place.
1612
+ *
1613
+ * It is **not** one of the entrances, and it is not in `PlassAnimation` either.
1614
+ * That union is the set of ways content can *arrive*, and every component
1615
+ * importing the map that backs it pays for each row whether it uses it or not;
1616
+ * a drift that never finishes is not an arrival and would be a row nothing else
1617
+ * could ever want.
1618
+ */
1619
+ @keyframes plass-anim-float {
1620
+ 0%,
1621
+ 100% {
1622
+ translate: 0 0;
1623
+ }
1624
+ 50% {
1625
+ translate: var(--p-anim-x, 0) var(--p-anim-y, 0);
1626
+ }
1627
+ }
1628
+
1629
+ .plass-anim-float {
1630
+ animation-name: plass-anim-float;
1631
+ }
1632
+
1041
1633
  /*
1042
1634
  * The light travelling around the outside of something.
1043
1635
  *
@@ -1249,6 +1841,499 @@
1249
1841
  animation: plass-anim-caret 1s step-end infinite;
1250
1842
  }
1251
1843
 
1844
+ /* ---------------------------------------------------------------------------
1845
+ * Code blocks
1846
+ *
1847
+ * A `PlCodeBlock` is the one surface in the library that does **not** take the
1848
+ * page's palette. Code is read against a background that was chosen for code,
1849
+ * and a block that turned white because the page did would throw away the only
1850
+ * thing a reader is using to tell a keyword from a string. So the sheet carries
1851
+ * its own slots, `theme` picks which set fills them, and `auto` is the opt-in
1852
+ * for a block that would rather follow the page.
1853
+ *
1854
+ * They are custom properties on the block rather than a stylesheet per theme
1855
+ * for `internal/animate.ts`'s reason: nothing here is generated, the component only
1856
+ * fills slots, and a thirteenth theme is a block of declarations rather than a
1857
+ * second copy of the token map below. That is also why `theme` accepts any
1858
+ * string: a consumer who writes `[data-code-theme='ours']` in their own CSS has
1859
+ * a theme, with nothing to register and nothing to import.
1860
+ *
1861
+ * **Five of the slots are derived and are never written per theme.** `dim`,
1862
+ * `rule` and `hover` are a fixed mix of the ground and the ink, and `mark` and
1863
+ * `mark-edge` are the same for the highlighted-line background. A custom
1864
+ * property resolves its `var()`s on the element that declares it, and every
1865
+ * theme below declares its `fg` and `bg` on that same element — so the derived
1866
+ * five follow whichever theme won without being restated fourteen times.
1867
+ *
1868
+ * The two dark palettes at the top are written twice on purpose — once for
1869
+ * `dark`, once for `auto` inside a dark page — because a media query cannot be
1870
+ * folded into a selector list. It is the same repetition the theme roots at the
1871
+ * top of this file make, for the same reason.
1872
+ *
1873
+ * Every hue in the house themes is solved against its own background rather
1874
+ * than flipped: the light set runs dark and saturated on near-white, the dark
1875
+ * set light and desaturated on near-black. The pairs that have to stay apart
1876
+ * are the ones that sit next to each other in real code — a string beside a
1877
+ * number, a type beside a function name. The eight named themes below them are
1878
+ * ports and keep their own published values, because a Dracula that had been
1879
+ * re-solved would not be Dracula.
1880
+ * ------------------------------------------------------------------------- */
1881
+
1882
+ .plass-code {
1883
+ /* The light set, which is also what `auto` and `light` start from. */
1884
+ --p-code-bg: oklch(98.4% 0.003 262);
1885
+ --p-code-fg: oklch(30% 0.016 262);
1886
+
1887
+ --p-code-comment: oklch(58% 0.022 262);
1888
+ --p-code-keyword: oklch(48% 0.19 322);
1889
+ --p-code-string: oklch(46% 0.12 148);
1890
+ --p-code-number: oklch(50% 0.14 48);
1891
+ --p-code-function: oklch(48% 0.17 264);
1892
+ --p-code-type: oklch(45% 0.1 214);
1893
+ --p-code-variable: oklch(45% 0.12 28);
1894
+ --p-code-tag: oklch(48% 0.18 22);
1895
+ --p-code-attr: oklch(47% 0.13 82);
1896
+ --p-code-meta: oklch(52% 0.05 262);
1897
+ --p-code-add: oklch(45% 0.14 152);
1898
+ --p-code-del: oklch(48% 0.18 25);
1899
+
1900
+ /* The derived five. Declared once here and never in a theme: they are a mix
1901
+ of that theme's own ground and ink, which resolves on this element. */
1902
+ --p-code-dim: color-mix(in oklab, var(--p-code-fg) 58%, var(--p-code-bg));
1903
+ --p-code-rule: color-mix(in oklab, var(--p-code-fg) 14%, transparent);
1904
+ --p-code-hover: color-mix(in oklab, var(--p-code-fg) 9%, transparent);
1905
+
1906
+ /* A marked line is neutral rather than dyed with the page's accent family:
1907
+ the block has deliberately refused the page's palette, and a primary-blue
1908
+ wash over Dracula would be the one colour on it nobody chose. Mixed from
1909
+ the theme's own ink, it is legible on all twelve. */
1910
+ --p-code-mark: color-mix(in oklab, var(--p-code-fg) 10%, transparent);
1911
+ --p-code-mark-edge: color-mix(in oklab, var(--p-code-fg) 45%, transparent);
1912
+ }
1913
+
1914
+ .plass-code[data-code-theme='dark'],
1915
+ :where(.dark, [data-theme='dark']) .plass-code[data-code-theme='auto'] {
1916
+ --p-code-bg: oklch(19.5% 0.014 262);
1917
+ --p-code-fg: oklch(90% 0.012 262);
1918
+
1919
+ --p-code-comment: oklch(60% 0.024 262);
1920
+ --p-code-keyword: oklch(76% 0.13 324);
1921
+ --p-code-string: oklch(80% 0.13 148);
1922
+ --p-code-number: oklch(81% 0.12 62);
1923
+ --p-code-function: oklch(78% 0.12 258);
1924
+ --p-code-type: oklch(82% 0.1 210);
1925
+ --p-code-variable: oklch(82% 0.09 32);
1926
+ --p-code-tag: oklch(77% 0.13 22);
1927
+ --p-code-attr: oklch(85% 0.11 92);
1928
+ --p-code-meta: oklch(70% 0.05 262);
1929
+ --p-code-add: oklch(80% 0.14 152);
1930
+ --p-code-del: oklch(75% 0.15 25);
1931
+ }
1932
+
1933
+ @media (prefers-color-scheme: dark) {
1934
+ :root:not([data-theme='light']) .plass-code[data-code-theme='auto'] {
1935
+ --p-code-bg: oklch(19.5% 0.014 262);
1936
+ --p-code-fg: oklch(90% 0.012 262);
1937
+
1938
+ --p-code-comment: oklch(60% 0.024 262);
1939
+ --p-code-keyword: oklch(76% 0.13 324);
1940
+ --p-code-string: oklch(80% 0.13 148);
1941
+ --p-code-number: oklch(81% 0.12 62);
1942
+ --p-code-function: oklch(78% 0.12 258);
1943
+ --p-code-type: oklch(82% 0.1 210);
1944
+ --p-code-variable: oklch(82% 0.09 32);
1945
+ --p-code-tag: oklch(77% 0.13 22);
1946
+ --p-code-attr: oklch(85% 0.11 92);
1947
+ --p-code-meta: oklch(70% 0.05 262);
1948
+ --p-code-add: oklch(80% 0.14 152);
1949
+ --p-code-del: oklch(75% 0.15 25);
1950
+ }
1951
+ }
1952
+
1953
+ /*
1954
+ * `mono` is the one theme that follows the page, and the only one with no hue
1955
+ * in it at all: the structure is carried by weight and by how far a run is
1956
+ * muted. It is what a block printed on paper, or read by someone who cannot
1957
+ * separate the hues above, is left with — so it has to stay legible on its own
1958
+ * rather than being a degraded copy of a colour theme.
1959
+ */
1960
+ .plass-code[data-code-theme='mono'] {
1961
+ --p-code-bg: color-mix(in oklab, var(--plass-fg) 4%, var(--plass-surface));
1962
+ --p-code-fg: var(--plass-fg);
1963
+
1964
+ --p-code-comment: var(--plass-muted-fg);
1965
+ --p-code-keyword: var(--plass-fg);
1966
+ --p-code-string: var(--plass-muted-fg);
1967
+ --p-code-number: var(--plass-muted-fg);
1968
+ --p-code-function: var(--plass-fg);
1969
+ --p-code-type: var(--plass-fg);
1970
+ --p-code-variable: var(--plass-fg);
1971
+ --p-code-tag: var(--plass-fg);
1972
+ --p-code-attr: var(--plass-muted-fg);
1973
+ --p-code-meta: var(--plass-muted-fg);
1974
+ --p-code-add: var(--plass-fg);
1975
+ --p-code-del: var(--plass-muted-fg);
1976
+ }
1977
+
1978
+ .plass-code[data-code-theme='mono'] .hljs-keyword,
1979
+ .plass-code[data-code-theme='mono'] .hljs-selector-tag,
1980
+ .plass-code[data-code-theme='mono'] .hljs-title,
1981
+ .plass-code[data-code-theme='mono'] .hljs-tag,
1982
+ .plass-code[data-code-theme='mono'] .hljs-type,
1983
+ .plass-code[data-code-theme='mono'] .hljs-built_in {
1984
+ font-weight: 600;
1985
+ }
1986
+
1987
+ /*
1988
+ * The eight ports.
1989
+ *
1990
+ * They exist because a code block is the one component whose colours a reader
1991
+ * already has an opinion about: someone who writes in One Dark all day reads a
1992
+ * Dracula block as a different product's documentation. The published values
1993
+ * are kept exactly, in the hex they were published in, rather than re-solved
1994
+ * into the oklch the rest of this file uses — a Dracula that had been corrected
1995
+ * against Neba's own ground would be a theme nobody recognises and nobody
1996
+ * asked for.
1997
+ *
1998
+ * Six dark and two light, which is the ratio of how they are used. Each is
1999
+ * fourteen declarations, because the muted, the rule, the hover and the two
2000
+ * marked-line slots are all derived from the two at the top of it.
2001
+ */
2002
+ .plass-code[data-code-theme='one-dark'] {
2003
+ --p-code-bg: #282c34;
2004
+ --p-code-fg: #abb2bf;
2005
+
2006
+ --p-code-comment: #5c6370;
2007
+ --p-code-keyword: #c678dd;
2008
+ --p-code-string: #98c379;
2009
+ --p-code-number: #d19a66;
2010
+ --p-code-function: #61afef;
2011
+ --p-code-type: #e5c07b;
2012
+ --p-code-variable: #e06c75;
2013
+ --p-code-tag: #e06c75;
2014
+ --p-code-attr: #d19a66;
2015
+ --p-code-meta: #56b6c2;
2016
+ --p-code-add: #98c379;
2017
+ --p-code-del: #e06c75;
2018
+ }
2019
+
2020
+ .plass-code[data-code-theme='dracula'] {
2021
+ --p-code-bg: #282a36;
2022
+ --p-code-fg: #f8f8f2;
2023
+
2024
+ --p-code-comment: #6272a4;
2025
+ --p-code-keyword: #ff79c6;
2026
+ --p-code-string: #f1fa8c;
2027
+ --p-code-number: #bd93f9;
2028
+ --p-code-function: #50fa7b;
2029
+ --p-code-type: #8be9fd;
2030
+ --p-code-variable: #f8f8f2;
2031
+ --p-code-tag: #ff79c6;
2032
+ --p-code-attr: #50fa7b;
2033
+ --p-code-meta: #6272a4;
2034
+ --p-code-add: #50fa7b;
2035
+ --p-code-del: #ff5555;
2036
+ }
2037
+
2038
+ .plass-code[data-code-theme='monokai'] {
2039
+ --p-code-bg: #272822;
2040
+ --p-code-fg: #f8f8f2;
2041
+
2042
+ --p-code-comment: #75715e;
2043
+ --p-code-keyword: #f92672;
2044
+ --p-code-string: #e6db74;
2045
+ --p-code-number: #ae81ff;
2046
+ --p-code-function: #a6e22e;
2047
+ --p-code-type: #66d9ef;
2048
+ --p-code-variable: #f8f8f2;
2049
+ --p-code-tag: #f92672;
2050
+ --p-code-attr: #a6e22e;
2051
+ --p-code-meta: #75715e;
2052
+ --p-code-add: #a6e22e;
2053
+ --p-code-del: #f92672;
2054
+ }
2055
+
2056
+ .plass-code[data-code-theme='nord'] {
2057
+ --p-code-bg: #2e3440;
2058
+ --p-code-fg: #d8dee9;
2059
+
2060
+ --p-code-comment: #616e88;
2061
+ --p-code-keyword: #81a1c1;
2062
+ --p-code-string: #a3be8c;
2063
+ --p-code-number: #b48ead;
2064
+ --p-code-function: #88c0d0;
2065
+ --p-code-type: #8fbcbb;
2066
+ --p-code-variable: #d8dee9;
2067
+ --p-code-tag: #81a1c1;
2068
+ --p-code-attr: #8fbcbb;
2069
+ --p-code-meta: #5e81ac;
2070
+ --p-code-add: #a3be8c;
2071
+ --p-code-del: #bf616a;
2072
+ }
2073
+
2074
+ .plass-code[data-code-theme='night-owl'] {
2075
+ --p-code-bg: #011627;
2076
+ --p-code-fg: #d6deeb;
2077
+
2078
+ --p-code-comment: #637777;
2079
+ --p-code-keyword: #c792ea;
2080
+ --p-code-string: #ecc48d;
2081
+ --p-code-number: #f78c6c;
2082
+ --p-code-function: #82aaff;
2083
+ --p-code-type: #ffcb8b;
2084
+ --p-code-variable: #addb67;
2085
+ --p-code-tag: #7fdbca;
2086
+ --p-code-attr: #addb67;
2087
+ --p-code-meta: #82aaff;
2088
+ --p-code-add: #addb67;
2089
+ --p-code-del: #ef5350;
2090
+ }
2091
+
2092
+ .plass-code[data-code-theme='gruvbox'] {
2093
+ --p-code-bg: #282828;
2094
+ --p-code-fg: #ebdbb2;
2095
+
2096
+ --p-code-comment: #928374;
2097
+ --p-code-keyword: #fb4934;
2098
+ --p-code-string: #b8bb26;
2099
+ --p-code-number: #d3869b;
2100
+ --p-code-function: #b8bb26;
2101
+ --p-code-type: #fabd2f;
2102
+ --p-code-variable: #83a598;
2103
+ --p-code-tag: #8ec07c;
2104
+ --p-code-attr: #fabd2f;
2105
+ --p-code-meta: #928374;
2106
+ --p-code-add: #b8bb26;
2107
+ --p-code-del: #fb4934;
2108
+ }
2109
+
2110
+ .plass-code[data-code-theme='github'] {
2111
+ --p-code-bg: #ffffff;
2112
+ --p-code-fg: #24292f;
2113
+
2114
+ --p-code-comment: #6e7781;
2115
+ --p-code-keyword: #cf222e;
2116
+ --p-code-string: #0a3069;
2117
+ --p-code-number: #0550ae;
2118
+ --p-code-function: #8250df;
2119
+ --p-code-type: #953800;
2120
+ --p-code-variable: #953800;
2121
+ --p-code-tag: #116329;
2122
+ --p-code-attr: #0550ae;
2123
+ --p-code-meta: #6e7781;
2124
+ --p-code-add: #116329;
2125
+ --p-code-del: #82071e;
2126
+ }
2127
+
2128
+ .plass-code[data-code-theme='solarized-light'] {
2129
+ --p-code-bg: #fdf6e3;
2130
+ --p-code-fg: #657b83;
2131
+
2132
+ --p-code-comment: #93a1a1;
2133
+ --p-code-keyword: #859900;
2134
+ --p-code-string: #2aa198;
2135
+ --p-code-number: #d33682;
2136
+ --p-code-function: #268bd2;
2137
+ --p-code-type: #b58900;
2138
+ --p-code-variable: #268bd2;
2139
+ --p-code-tag: #268bd2;
2140
+ --p-code-attr: #b58900;
2141
+ --p-code-meta: #cb4b16;
2142
+ --p-code-add: #859900;
2143
+ --p-code-del: #dc322f;
2144
+ }
2145
+
2146
+ /*
2147
+ * A line, and the two things in front of it that are not code.
2148
+ *
2149
+ * The number and the prompt are generated content off a `data-*` attribute, not
2150
+ * text nodes, and that is the whole point: a `$` a reader drags across and
2151
+ * pastes into their shell is a `$` their shell chokes on. Generated content
2152
+ * cannot be selected, cannot be found by find-in-page and never reaches the
2153
+ * clipboard — `user-select: none` is only *usually* true of all three. The
2154
+ * `order` is what lets one pseudo-element sit in front of the other and both in
2155
+ * front of the code, since `::after` would otherwise draw last.
2156
+ *
2157
+ * `min-height` keeps a blank line a line high. A flex row with nothing in it is
2158
+ * zero pixels tall, and a code block that closed up its own paragraph breaks
2159
+ * would be reflowing the reader's file.
2160
+ */
2161
+ .plass-code-line {
2162
+ display: flex;
2163
+ min-height: 1.5em;
2164
+ min-height: 1lh;
2165
+ /*
2166
+ * Transparent on every line, coloured on a marked one. A border rather than
2167
+ * an inset `box-shadow` because `box-shadow` has no logical form and this one
2168
+ * has to sit on the *start* edge in both writing directions; drawn on all of
2169
+ * them so marking a line does not shift its text two pixels sideways.
2170
+ */
2171
+ border-inline-start: 2px solid transparent;
2172
+ }
2173
+
2174
+ /*
2175
+ * A marked line, and the reason its horizontal padding is on the line rather
2176
+ * than on the box that scrolls it.
2177
+ *
2178
+ * A highlight that stopped at the padding would be a stripe floating inside the
2179
+ * block instead of a marked row. With the padding here the line box *is* the
2180
+ * row, so the tint reaches both edges — and because the lines sit in a
2181
+ * `w-max min-w-full` block, every one of them reaches the same edge whether the
2182
+ * code is narrower than the block or scrolled sideways within it.
2183
+ */
2184
+ .plass-code-line[data-mark] {
2185
+ background: var(--p-code-mark);
2186
+ border-inline-start-color: var(--p-code-mark-edge);
2187
+ }
2188
+
2189
+ .plass-code-line[data-line]::before {
2190
+ content: attr(data-line);
2191
+ order: 0;
2192
+ flex: none;
2193
+ width: var(--p-code-gutter, 2ch);
2194
+ margin-inline-end: 1.25em;
2195
+ text-align: end;
2196
+ color: var(--p-code-dim);
2197
+ -webkit-user-select: none;
2198
+ user-select: none;
2199
+ }
2200
+
2201
+ .plass-code-line[data-prompt]::after {
2202
+ content: attr(data-prompt);
2203
+ order: 1;
2204
+ flex: none;
2205
+ margin-inline-end: 0.75em;
2206
+ color: var(--p-code-dim);
2207
+ -webkit-user-select: none;
2208
+ user-select: none;
2209
+ }
2210
+
2211
+ .plass-code-line > code {
2212
+ order: 2;
2213
+ min-width: 0;
2214
+ font: inherit;
2215
+ background: none;
2216
+ padding: 0;
2217
+ white-space: pre;
2218
+ }
2219
+
2220
+ .plass-code[data-code-wrap='true'] .plass-code-line > code {
2221
+ white-space: pre-wrap;
2222
+ overflow-wrap: anywhere;
2223
+ }
2224
+
2225
+ /*
2226
+ * highlight.js's scopes, mapped onto the sixteen slots.
2227
+ *
2228
+ * Grouped by what a run *is* rather than by what highlight.js calls it, because
2229
+ * the names are the union of a hundred and ninety grammars and half of them are
2230
+ * one language's word for another language's idea — `selector-tag` and `tag`
2231
+ * and `name` are all "the thing being declared". The point of the mapping is
2232
+ * that the same idea gets the same colour whatever file it appears in.
2233
+ */
2234
+ .plass-code .hljs-comment,
2235
+ .plass-code .hljs-quote {
2236
+ color: var(--p-code-comment);
2237
+ font-style: italic;
2238
+ }
2239
+
2240
+ .plass-code .hljs-keyword,
2241
+ .plass-code .hljs-literal,
2242
+ .plass-code .hljs-selector-tag,
2243
+ .plass-code .hljs-operator,
2244
+ .plass-code .hljs-doctag,
2245
+ .plass-code .hljs-formula {
2246
+ color: var(--p-code-keyword);
2247
+ }
2248
+
2249
+ .plass-code .hljs-string,
2250
+ .plass-code .hljs-regexp,
2251
+ .plass-code .hljs-char,
2252
+ .plass-code .hljs-link {
2253
+ color: var(--p-code-string);
2254
+ }
2255
+
2256
+ .plass-code .hljs-number,
2257
+ .plass-code .hljs-symbol,
2258
+ .plass-code .hljs-bullet {
2259
+ color: var(--p-code-number);
2260
+ }
2261
+
2262
+ .plass-code .hljs-title,
2263
+ .plass-code .hljs-section,
2264
+ .plass-code .hljs-name,
2265
+ .plass-code .hljs-selector-id,
2266
+ .plass-code .hljs-selector-class {
2267
+ color: var(--p-code-function);
2268
+ }
2269
+
2270
+ .plass-code .hljs-type,
2271
+ .plass-code .hljs-built_in,
2272
+ .plass-code .hljs-class {
2273
+ color: var(--p-code-type);
2274
+ }
2275
+
2276
+ .plass-code .hljs-variable,
2277
+ .plass-code .hljs-template-variable,
2278
+ .plass-code .hljs-params,
2279
+ .plass-code .hljs-subst {
2280
+ color: var(--p-code-variable);
2281
+ }
2282
+
2283
+ .plass-code .hljs-tag,
2284
+ .plass-code .hljs-template-tag {
2285
+ color: var(--p-code-tag);
2286
+ }
2287
+
2288
+ .plass-code .hljs-attr,
2289
+ .plass-code .hljs-attribute,
2290
+ .plass-code .hljs-property,
2291
+ .plass-code .hljs-selector-attr,
2292
+ .plass-code .hljs-selector-pseudo {
2293
+ color: var(--p-code-attr);
2294
+ }
2295
+
2296
+ .plass-code .hljs-meta,
2297
+ .plass-code .hljs-punctuation {
2298
+ color: var(--p-code-meta);
2299
+ }
2300
+
2301
+ .plass-code .hljs-addition {
2302
+ color: var(--p-code-add);
2303
+ }
2304
+
2305
+ .plass-code .hljs-deletion {
2306
+ color: var(--p-code-del);
2307
+ }
2308
+
2309
+ .plass-code .hljs-emphasis {
2310
+ font-style: italic;
2311
+ }
2312
+
2313
+ .plass-code .hljs-strong {
2314
+ font-weight: 700;
2315
+ }
2316
+
2317
+ /* ---------------------------------------------------------------------------
2318
+ * The gallery
2319
+ *
2320
+ * `PlGallery` rides the same `--p-cols` chain `PlGrid` does, one block above,
2321
+ * with a default of two rather than twelve: a wall of photographs is counted in
2322
+ * tiles across and a layout grid is counted in tracks, and two is the narrowest
2323
+ * arrangement that still reads as a set.
2324
+ *
2325
+ * The three lines below are what the slot is *for*. A grid and a quilt lay out
2326
+ * in CSS Grid off `--p-cols`; a masonry deals its items into that many lanes in
2327
+ * JavaScript, because which lane an item lands in changes the DOM and no
2328
+ * stylesheet can do that; and a justified row is flexbox, which needs no count
2329
+ * at all — it fills to the edge with whatever fits.
2330
+ * ------------------------------------------------------------------------- */
2331
+
2332
+ .plass-gallery-grid,
2333
+ .plass-gallery-quilted {
2334
+ grid-template-columns: repeat(var(--p-cols, 2), minmax(0, 1fr));
2335
+ }
2336
+
1252
2337
  /* ---------------------------------------------------------------------------
1253
2338
  * Reduced motion
1254
2339
  *