react-cheminfo 0.7.0 → 0.9.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 (308) hide show
  1. package/README.md +60 -2
  2. package/bin/check-tokens.mjs +105 -0
  3. package/lib/about/core/about.d.ts +95 -0
  4. package/lib/about/core/about.d.ts.map +1 -0
  5. package/lib/about/core/about.js +78 -0
  6. package/lib/about/core/about.js.map +1 -0
  7. package/lib/about/core/index.d.ts +3 -0
  8. package/lib/about/core/index.d.ts.map +1 -0
  9. package/lib/about/core/index.js +2 -0
  10. package/lib/about/core/index.js.map +1 -0
  11. package/lib/about/ui/AboutCitations.d.ts +14 -0
  12. package/lib/about/ui/AboutCitations.d.ts.map +1 -0
  13. package/lib/about/ui/AboutCitations.js +40 -0
  14. package/lib/about/ui/AboutCitations.js.map +1 -0
  15. package/lib/about/ui/AboutPage.d.ts +32 -0
  16. package/lib/about/ui/AboutPage.d.ts.map +1 -0
  17. package/lib/about/ui/AboutPage.js +70 -0
  18. package/lib/about/ui/AboutPage.js.map +1 -0
  19. package/lib/about/ui/AboutSection.d.ts +23 -0
  20. package/lib/about/ui/AboutSection.d.ts.map +1 -0
  21. package/lib/about/ui/AboutSection.js +28 -0
  22. package/lib/about/ui/AboutSection.js.map +1 -0
  23. package/lib/about/ui/index.d.ts +7 -0
  24. package/lib/about/ui/index.d.ts.map +1 -0
  25. package/lib/about/ui/index.js +4 -0
  26. package/lib/about/ui/index.js.map +1 -0
  27. package/lib/chrome/ui/index.d.ts +1 -0
  28. package/lib/chrome/ui/index.d.ts.map +1 -1
  29. package/lib/chrome/ui/index.js +3 -0
  30. package/lib/chrome/ui/index.js.map +1 -1
  31. package/lib/citation/core/index.d.ts +1 -0
  32. package/lib/citation/core/index.d.ts.map +1 -1
  33. package/lib/citation/core/index.js +1 -0
  34. package/lib/citation/core/index.js.map +1 -1
  35. package/lib/citation/core/teachingPaper.d.ts +15 -0
  36. package/lib/citation/core/teachingPaper.d.ts.map +1 -0
  37. package/lib/citation/core/teachingPaper.js +32 -0
  38. package/lib/citation/core/teachingPaper.js.map +1 -0
  39. package/lib/clipboard/ui/CodeBlock.d.ts.map +1 -1
  40. package/lib/clipboard/ui/CodeBlock.js +4 -1
  41. package/lib/clipboard/ui/CodeBlock.js.map +1 -1
  42. package/lib/color/ui/ColorScaleLegend.js +1 -1
  43. package/lib/color/ui/ColorScaleLegend.js.map +1 -1
  44. package/lib/core.d.ts +3 -0
  45. package/lib/core.d.ts.map +1 -1
  46. package/lib/core.js +5 -0
  47. package/lib/core.js.map +1 -1
  48. package/lib/credits/core/credits.d.ts +36 -0
  49. package/lib/credits/core/credits.d.ts.map +1 -1
  50. package/lib/credits/core/credits.js +42 -0
  51. package/lib/credits/core/credits.js.map +1 -1
  52. package/lib/credits/ui/CreditsList.js +1 -1
  53. package/lib/credits/ui/CreditsList.js.map +1 -1
  54. package/lib/delimited/ui/DelimitedTextPanel.js +1 -1
  55. package/lib/delimited/ui/DelimitedTextPanel.js.map +1 -1
  56. package/lib/ecosystem/core/sites.d.ts +1 -1
  57. package/lib/ecosystem/core/sites.d.ts.map +1 -1
  58. package/lib/ecosystem/core/sites.js +10 -0
  59. package/lib/ecosystem/core/sites.js.map +1 -1
  60. package/lib/ecosystem/core/tokens.d.ts.map +1 -1
  61. package/lib/ecosystem/core/tokens.js +1 -0
  62. package/lib/ecosystem/core/tokens.js.map +1 -1
  63. package/lib/ecosystem/ui/EcosystemLinks.js +2 -2
  64. package/lib/ecosystem/ui/EcosystemLinks.js.map +1 -1
  65. package/lib/ecosystem/ui/EcosystemMenu.js +1 -1
  66. package/lib/ecosystem/ui/EcosystemMenu.js.map +1 -1
  67. package/lib/ecosystem/ui/SiteTile.d.ts.map +1 -1
  68. package/lib/ecosystem/ui/SiteTile.js +5 -5
  69. package/lib/ecosystem/ui/SiteTile.js.map +1 -1
  70. package/lib/ecosystem/ui/glyphs.d.ts.map +1 -1
  71. package/lib/ecosystem/ui/glyphs.js +3 -0
  72. package/lib/ecosystem/ui/glyphs.js.map +1 -1
  73. package/lib/orbital/core/index.d.ts +1 -1
  74. package/lib/orbital/core/index.d.ts.map +1 -1
  75. package/lib/orbital/core/index.js +1 -1
  76. package/lib/orbital/core/index.js.map +1 -1
  77. package/lib/orbital/core/realHarmonics.d.ts +5 -2
  78. package/lib/orbital/core/realHarmonics.d.ts.map +1 -1
  79. package/lib/orbital/core/realHarmonics.js.map +1 -1
  80. package/lib/orbital/ui/AtomicOrbitalCanvas.d.ts +18 -0
  81. package/lib/orbital/ui/AtomicOrbitalCanvas.d.ts.map +1 -1
  82. package/lib/orbital/ui/AtomicOrbitalCanvas.js +84 -7
  83. package/lib/orbital/ui/AtomicOrbitalCanvas.js.map +1 -1
  84. package/lib/orbital/ui/AtomicOrbitalViewer.d.ts +13 -0
  85. package/lib/orbital/ui/AtomicOrbitalViewer.d.ts.map +1 -1
  86. package/lib/orbital/ui/AtomicOrbitalViewer.js +1 -1
  87. package/lib/orbital/ui/AtomicOrbitalViewer.js.map +1 -1
  88. package/lib/orbital/ui/camera.d.ts +15 -0
  89. package/lib/orbital/ui/camera.d.ts.map +1 -1
  90. package/lib/orbital/ui/camera.js +68 -0
  91. package/lib/orbital/ui/camera.js.map +1 -1
  92. package/lib/orbital/ui/renderVolume.d.ts.map +1 -1
  93. package/lib/orbital/ui/renderVolume.js +8 -1
  94. package/lib/orbital/ui/renderVolume.js.map +1 -1
  95. package/lib/orbital/ui/serial.d.ts +25 -0
  96. package/lib/orbital/ui/serial.d.ts.map +1 -0
  97. package/lib/orbital/ui/serial.js +25 -0
  98. package/lib/orbital/ui/serial.js.map +1 -0
  99. package/lib/orbital/ui/viewer.d.ts +23 -0
  100. package/lib/orbital/ui/viewer.d.ts.map +1 -1
  101. package/lib/orbital/ui/viewer.js +70 -17
  102. package/lib/orbital/ui/viewer.js.map +1 -1
  103. package/lib/pedagogy/ui/ExerciseProgressHeader.js +1 -1
  104. package/lib/pedagogy/ui/ExerciseProgressHeader.js.map +1 -1
  105. package/lib/pedagogy/ui/GlossaryText.js +2 -2
  106. package/lib/pedagogy/ui/GlossaryText.js.map +1 -1
  107. package/lib/pedagogy/ui/ReferenceSectionBlock.js +5 -2
  108. package/lib/pedagogy/ui/ReferenceSectionBlock.js.map +1 -1
  109. package/lib/pedagogy/ui/SyntaxTooltip.js +2 -2
  110. package/lib/pedagogy/ui/SyntaxTooltip.js.map +1 -1
  111. package/lib/pedagogy/ui/TutorialStepStrip.d.ts +15 -2
  112. package/lib/pedagogy/ui/TutorialStepStrip.d.ts.map +1 -1
  113. package/lib/pedagogy/ui/TutorialStepStrip.js +19 -5
  114. package/lib/pedagogy/ui/TutorialStepStrip.js.map +1 -1
  115. package/lib/pedagogy/ui/index.d.ts +1 -1
  116. package/lib/pedagogy/ui/index.d.ts.map +1 -1
  117. package/lib/pedagogy/ui/index.js.map +1 -1
  118. package/lib/periodic/ui/CategoryLegend.js +1 -1
  119. package/lib/periodic/ui/CategoryLegend.js.map +1 -1
  120. package/lib/periodic/ui/PeriodicTableChrome.js +2 -2
  121. package/lib/periodic/ui/PeriodicTableChrome.js.map +1 -1
  122. package/lib/seo/vite/ogCard.d.ts.map +1 -1
  123. package/lib/seo/vite/ogCard.js +1 -0
  124. package/lib/seo/vite/ogCard.js.map +1 -1
  125. package/lib/share/ui/ShareDialogContent.d.ts.map +1 -1
  126. package/lib/share/ui/ShareDialogContent.js +5 -2
  127. package/lib/share/ui/ShareDialogContent.js.map +1 -1
  128. package/lib/share/ui/SharePartOptions.js +1 -1
  129. package/lib/share/ui/SharePartOptions.js.map +1 -1
  130. package/lib/slides/core/demoLinks.d.ts +43 -0
  131. package/lib/slides/core/demoLinks.d.ts.map +1 -0
  132. package/lib/slides/core/demoLinks.js +104 -0
  133. package/lib/slides/core/demoLinks.js.map +1 -0
  134. package/lib/slides/core/index.d.ts +13 -0
  135. package/lib/slides/core/index.d.ts.map +1 -0
  136. package/lib/slides/core/index.js +7 -0
  137. package/lib/slides/core/index.js.map +1 -0
  138. package/lib/slides/core/sectionHeading.d.ts +19 -0
  139. package/lib/slides/core/sectionHeading.d.ts.map +1 -0
  140. package/lib/slides/core/sectionHeading.js +19 -0
  141. package/lib/slides/core/sectionHeading.js.map +1 -0
  142. package/lib/slides/core/slideNavigation.d.ts +38 -0
  143. package/lib/slides/core/slideNavigation.d.ts.map +1 -0
  144. package/lib/slides/core/slideNavigation.js +65 -0
  145. package/lib/slides/core/slideNavigation.js.map +1 -0
  146. package/lib/slides/core/talk.d.ts +82 -0
  147. package/lib/slides/core/talk.d.ts.map +1 -0
  148. package/lib/slides/core/talk.js +134 -0
  149. package/lib/slides/core/talk.js.map +1 -0
  150. package/lib/slides/core/talkManifest.d.ts +90 -0
  151. package/lib/slides/core/talkManifest.d.ts.map +1 -0
  152. package/lib/slides/core/talkManifest.js +109 -0
  153. package/lib/slides/core/talkManifest.js.map +1 -0
  154. package/lib/slides/core/talkOrigin.d.ts +50 -0
  155. package/lib/slides/core/talkOrigin.d.ts.map +1 -0
  156. package/lib/slides/core/talkOrigin.js +62 -0
  157. package/lib/slides/core/talkOrigin.js.map +1 -0
  158. package/lib/slides/ui/BackToSlides.d.ts +26 -0
  159. package/lib/slides/ui/BackToSlides.d.ts.map +1 -0
  160. package/lib/slides/ui/BackToSlides.js +24 -0
  161. package/lib/slides/ui/BackToSlides.js.map +1 -0
  162. package/lib/slides/ui/DemoLink.d.ts +42 -0
  163. package/lib/slides/ui/DemoLink.d.ts.map +1 -0
  164. package/lib/slides/ui/DemoLink.js +17 -0
  165. package/lib/slides/ui/DemoLink.js.map +1 -0
  166. package/lib/slides/ui/EmbedSlide.d.ts +19 -0
  167. package/lib/slides/ui/EmbedSlide.d.ts.map +1 -0
  168. package/lib/slides/ui/EmbedSlide.js +56 -0
  169. package/lib/slides/ui/EmbedSlide.js.map +1 -0
  170. package/lib/slides/ui/SectionSlide.d.ts +18 -0
  171. package/lib/slides/ui/SectionSlide.d.ts.map +1 -0
  172. package/lib/slides/ui/SectionSlide.js +18 -0
  173. package/lib/slides/ui/SectionSlide.js.map +1 -0
  174. package/lib/slides/ui/Slide.d.ts +52 -0
  175. package/lib/slides/ui/Slide.d.ts.map +1 -0
  176. package/lib/slides/ui/Slide.js +58 -0
  177. package/lib/slides/ui/Slide.js.map +1 -0
  178. package/lib/slides/ui/SlideBody.d.ts +32 -0
  179. package/lib/slides/ui/SlideBody.d.ts.map +1 -0
  180. package/lib/slides/ui/SlideBody.js +27 -0
  181. package/lib/slides/ui/SlideBody.js.map +1 -0
  182. package/lib/slides/ui/Slideshow.d.ts +93 -0
  183. package/lib/slides/ui/Slideshow.d.ts.map +1 -0
  184. package/lib/slides/ui/Slideshow.js +122 -0
  185. package/lib/slides/ui/Slideshow.js.map +1 -0
  186. package/lib/slides/ui/SlideshowBar.d.ts +33 -0
  187. package/lib/slides/ui/SlideshowBar.d.ts.map +1 -0
  188. package/lib/slides/ui/SlideshowBar.js +20 -0
  189. package/lib/slides/ui/SlideshowBar.js.map +1 -0
  190. package/lib/slides/ui/TalkList.d.ts +37 -0
  191. package/lib/slides/ui/TalkList.d.ts.map +1 -0
  192. package/lib/slides/ui/TalkList.js +68 -0
  193. package/lib/slides/ui/TalkList.js.map +1 -0
  194. package/lib/slides/ui/index.d.ts +19 -0
  195. package/lib/slides/ui/index.d.ts.map +1 -0
  196. package/lib/slides/ui/index.js +10 -0
  197. package/lib/slides/ui/index.js.map +1 -0
  198. package/lib/slides/vite/index.d.ts +3 -0
  199. package/lib/slides/vite/index.d.ts.map +1 -0
  200. package/lib/slides/vite/index.js +2 -0
  201. package/lib/slides/vite/index.js.map +1 -0
  202. package/lib/slides/vite/talks.d.ts +50 -0
  203. package/lib/slides/vite/talks.d.ts.map +1 -0
  204. package/lib/slides/vite/talks.js +87 -0
  205. package/lib/slides/vite/talks.js.map +1 -0
  206. package/lib/slides.d.ts +3 -0
  207. package/lib/slides.d.ts.map +1 -0
  208. package/lib/slides.js +3 -0
  209. package/lib/slides.js.map +1 -0
  210. package/lib/structure/ui/StructureEditor.js +2 -2
  211. package/lib/structure/ui/StructureEditor.js.map +1 -1
  212. package/lib/structure/ui/StructurePlaceholder.js +1 -1
  213. package/lib/structure/ui/StructurePlaceholder.js.map +1 -1
  214. package/lib/tokens/core/checkTokens.d.ts +51 -0
  215. package/lib/tokens/core/checkTokens.d.ts.map +1 -0
  216. package/lib/tokens/core/checkTokens.js +188 -0
  217. package/lib/tokens/core/checkTokens.js.map +1 -0
  218. package/lib/tokens/core/colors.d.ts +42 -0
  219. package/lib/tokens/core/colors.d.ts.map +1 -0
  220. package/lib/tokens/core/colors.js +119 -0
  221. package/lib/tokens/core/colors.js.map +1 -0
  222. package/lib/tokens/core/index.d.ts +3 -0
  223. package/lib/tokens/core/index.d.ts.map +1 -0
  224. package/lib/tokens/core/index.js +2 -0
  225. package/lib/tokens/core/index.js.map +1 -0
  226. package/lib/tokens/core/rules.d.ts +23 -0
  227. package/lib/tokens/core/rules.d.ts.map +1 -0
  228. package/lib/tokens/core/rules.js +90 -0
  229. package/lib/tokens/core/rules.js.map +1 -0
  230. package/lib/ui.d.ts +1 -0
  231. package/lib/ui.d.ts.map +1 -1
  232. package/lib/ui.js +1 -0
  233. package/lib/ui.js.map +1 -1
  234. package/lib/vite.d.ts +1 -0
  235. package/lib/vite.d.ts.map +1 -1
  236. package/lib/vite.js +1 -0
  237. package/lib/vite.js.map +1 -1
  238. package/package.json +11 -3
  239. package/src/about/core/about.ts +176 -0
  240. package/src/about/core/index.ts +2 -0
  241. package/src/about/ui/AboutCitations.tsx +79 -0
  242. package/src/about/ui/AboutPage.tsx +177 -0
  243. package/src/about/ui/AboutSection.tsx +56 -0
  244. package/src/about/ui/index.ts +6 -0
  245. package/src/chrome/ui/index.ts +3 -0
  246. package/src/citation/core/index.ts +1 -0
  247. package/src/citation/core/teachingPaper.ts +36 -0
  248. package/src/clipboard/ui/CodeBlock.tsx +4 -1
  249. package/src/color/ui/ColorScaleLegend.tsx +1 -1
  250. package/src/core.ts +5 -0
  251. package/src/credits/core/credits.ts +42 -0
  252. package/src/credits/ui/CreditsList.tsx +1 -1
  253. package/src/delimited/ui/DelimitedTextPanel.tsx +1 -1
  254. package/src/ecosystem/core/sites.ts +12 -0
  255. package/src/ecosystem/core/tokens.ts +1 -0
  256. package/src/ecosystem/ui/EcosystemLinks.tsx +2 -2
  257. package/src/ecosystem/ui/EcosystemMenu.tsx +1 -1
  258. package/src/ecosystem/ui/SiteTile.tsx +7 -5
  259. package/src/ecosystem/ui/glyphs.tsx +40 -0
  260. package/src/orbital/core/index.ts +4 -1
  261. package/src/orbital/core/realHarmonics.ts +5 -2
  262. package/src/orbital/ui/AtomicOrbitalCanvas.tsx +126 -4
  263. package/src/orbital/ui/AtomicOrbitalViewer.tsx +14 -1
  264. package/src/orbital/ui/camera.ts +81 -0
  265. package/src/orbital/ui/renderVolume.ts +8 -1
  266. package/src/orbital/ui/serial.ts +35 -0
  267. package/src/orbital/ui/viewer.ts +72 -13
  268. package/src/pedagogy/ui/ExerciseProgressHeader.tsx +1 -1
  269. package/src/pedagogy/ui/GlossaryText.tsx +2 -2
  270. package/src/pedagogy/ui/ReferenceSectionBlock.tsx +5 -2
  271. package/src/pedagogy/ui/SyntaxTooltip.tsx +2 -2
  272. package/src/pedagogy/ui/TutorialStepStrip.tsx +39 -10
  273. package/src/pedagogy/ui/index.ts +4 -1
  274. package/src/periodic/ui/CategoryLegend.tsx +1 -1
  275. package/src/periodic/ui/PeriodicTableChrome.tsx +2 -2
  276. package/src/seo/vite/ogCard.ts +1 -0
  277. package/src/share/ui/ShareDialogContent.tsx +5 -2
  278. package/src/share/ui/SharePartOptions.tsx +1 -1
  279. package/src/slides/core/demoLinks.ts +113 -0
  280. package/src/slides/core/index.ts +22 -0
  281. package/src/slides/core/sectionHeading.ts +29 -0
  282. package/src/slides/core/slideNavigation.ts +77 -0
  283. package/src/slides/core/talk.ts +203 -0
  284. package/src/slides/core/talkManifest.ts +158 -0
  285. package/src/slides/core/talkOrigin.ts +83 -0
  286. package/src/slides/ui/BackToSlides.tsx +49 -0
  287. package/src/slides/ui/DemoLink.tsx +67 -0
  288. package/src/slides/ui/EmbedSlide.tsx +85 -0
  289. package/src/slides/ui/SectionSlide.tsx +44 -0
  290. package/src/slides/ui/Slide.tsx +143 -0
  291. package/src/slides/ui/SlideBody.tsx +64 -0
  292. package/src/slides/ui/Slideshow.tsx +282 -0
  293. package/src/slides/ui/SlideshowBar.tsx +83 -0
  294. package/src/slides/ui/TalkList.tsx +146 -0
  295. package/src/slides/ui/index.ts +18 -0
  296. package/src/slides/vite/index.ts +2 -0
  297. package/src/slides/vite/talks.ts +126 -0
  298. package/src/slides.ts +2 -0
  299. package/src/structure/ui/StructureEditor.tsx +2 -2
  300. package/src/structure/ui/StructurePlaceholder.tsx +1 -1
  301. package/src/tokens/core/checkTokens.ts +242 -0
  302. package/src/tokens/core/colors.ts +122 -0
  303. package/src/tokens/core/index.ts +6 -0
  304. package/src/tokens/core/rules.ts +103 -0
  305. package/src/ui.ts +1 -0
  306. package/src/vite.ts +1 -0
  307. package/styles/chrome.css +1 -0
  308. package/styles/slides.css +667 -0
@@ -0,0 +1,667 @@
1
+ /*
2
+ * The slideshow player, the deck it draws and the list of talks around it.
3
+ *
4
+ * A slide is authored on a fixed 1920x1080 canvas — every size below is a
5
+ * design pixel — and the canvas is transform-scaled to fit the stage, so a
6
+ * deck renders identically on a laptop, a beamer or a 4K screen.
7
+ *
8
+ * Every colour comes from the family tokens, so a deck played on any site
9
+ * takes that site's two colours. The fallbacks are the family neutrals, for a
10
+ * page that imports this file without `chrome.css`.
11
+ */
12
+
13
+ .slideshow,
14
+ .talk-list,
15
+ .back-to-slides {
16
+ --slide-bg: var(--surface-sunken, #f5f7fa);
17
+ --slide-surface: var(--surface, #ffffff);
18
+ --slide-ink: var(--text, #16202c);
19
+ --slide-ink-soft: color-mix(in oklab, var(--text, #16202c) 82%, white);
20
+ --slide-muted: var(--text-muted, #5b6875);
21
+ --slide-line: var(--border, #dfe3e8);
22
+ --slide-accent: var(--accent, var(--brand, #4338ca));
23
+ --slide-accent-soft: color-mix(in oklab, var(--slide-accent) 10%, white);
24
+ --slide-answer: var(--brand-alt-text, var(--brand-alt, #be123c));
25
+ --slide-radius: var(--radius, 10px);
26
+ }
27
+
28
+ /* ── The player ──────────────────────────────────────────────────────────── */
29
+
30
+ .slideshow {
31
+ display: flex;
32
+ overflow: hidden;
33
+ flex-direction: column;
34
+ border: 1px solid var(--slide-line);
35
+ border-radius: var(--slide-radius);
36
+ background: var(--slide-bg);
37
+ color-scheme: light;
38
+ }
39
+
40
+ /* Presenting covers the whole screen, so the deck loses the card it sits in. */
41
+ .slideshow:fullscreen {
42
+ min-height: 0;
43
+ border: none;
44
+ border-radius: 0;
45
+ }
46
+
47
+ /* Off fullscreen the stage keeps the slide's 16:9 ratio, so the canvas fills
48
+ it edge to edge instead of floating letterboxed in a viewport-tall card. The
49
+ cap keeps the control bar on screen on a short window. */
50
+ .slideshow-stage {
51
+ position: relative;
52
+ display: flex;
53
+ overflow: hidden;
54
+ min-height: 0;
55
+ flex: none;
56
+ align-items: center;
57
+ justify-content: center;
58
+ padding: 16px;
59
+ aspect-ratio: 16 / 9;
60
+ max-height: calc(100dvh - 180px);
61
+ width: 100%;
62
+ }
63
+
64
+ .slideshow:fullscreen .slideshow-stage {
65
+ flex: 1 1 auto;
66
+ aspect-ratio: auto;
67
+ max-height: none;
68
+ }
69
+
70
+ .slide-canvas {
71
+ display: flex;
72
+ width: 1920px;
73
+ height: 1080px;
74
+ flex: none;
75
+ padding: 72px 96px;
76
+ transform-origin: center center;
77
+ }
78
+
79
+ /* Blank screen (b, w), to take the room's attention off the slide. Clicking it,
80
+ or any navigation, brings the slide back. */
81
+ .slideshow-blank {
82
+ position: absolute;
83
+ z-index: 30;
84
+ inset: 0;
85
+ cursor: pointer;
86
+ }
87
+
88
+ .slideshow-blank--black {
89
+ background: #000000;
90
+ }
91
+
92
+ .slideshow-blank--white {
93
+ background: #ffffff;
94
+ }
95
+
96
+ /* ── The control bar ─────────────────────────────────────────────────────── */
97
+
98
+ .slideshow-bar {
99
+ display: flex;
100
+ align-items: center;
101
+ padding: 8px 12px;
102
+ border-top: 1px solid var(--slide-line);
103
+ background: var(--slide-surface);
104
+ gap: 12px;
105
+ }
106
+
107
+ .slideshow-title {
108
+ overflow: hidden;
109
+ min-width: 0;
110
+ flex: 1 1 auto;
111
+ color: var(--slide-muted);
112
+ font-size: 0.9rem;
113
+ text-overflow: ellipsis;
114
+ white-space: nowrap;
115
+ }
116
+
117
+ .slideshow-controls {
118
+ display: flex;
119
+ flex: 0 0 auto;
120
+ align-items: center;
121
+ gap: 4px;
122
+ }
123
+
124
+ .slideshow-counter {
125
+ min-width: 3.5em;
126
+ color: var(--slide-ink-soft);
127
+ font-size: 0.9rem;
128
+ font-variant-numeric: tabular-nums;
129
+ text-align: center;
130
+ }
131
+
132
+ .slideshow-progress {
133
+ width: var(--progress, 0%);
134
+ height: 3px;
135
+ background: var(--slide-accent);
136
+ transition: width 0.2s ease;
137
+ }
138
+
139
+ /* The presenter's own notes, under the stage, on a key nobody presses by
140
+ accident. */
141
+ .slideshow-notes {
142
+ max-height: 30vh;
143
+ padding: 12px 16px;
144
+ border-top: 1px solid var(--slide-line);
145
+ background: var(--slide-surface);
146
+ color: var(--slide-ink-soft);
147
+ font-size: 0.95rem;
148
+ line-height: 1.5;
149
+ overflow-y: auto;
150
+ white-space: pre-wrap;
151
+ }
152
+
153
+ /* ── One slide ───────────────────────────────────────────────────────────── */
154
+
155
+ .slide {
156
+ width: 100%;
157
+ margin: auto;
158
+ color: var(--slide-ink);
159
+ }
160
+
161
+ .slide-content {
162
+ font-size: 45px;
163
+ line-height: 1.5;
164
+ }
165
+
166
+ .slide-content h1 {
167
+ margin: 0 0 0.3em;
168
+ font-size: 108px;
169
+ letter-spacing: -0.02em;
170
+ line-height: 1.05;
171
+ }
172
+
173
+ .slide-content h2 {
174
+ margin: 0 0 0.6em;
175
+ font-size: 72px;
176
+ letter-spacing: -0.01em;
177
+ line-height: 1.1;
178
+ }
179
+
180
+ .slide-content h3 {
181
+ margin: 0.8em 0 0.4em;
182
+ font-size: 54px;
183
+ letter-spacing: -0.01em;
184
+ line-height: 1.2;
185
+ }
186
+
187
+ .slide-content p {
188
+ margin: 0.5em 0;
189
+ }
190
+
191
+ .slide-content ul,
192
+ .slide-content ol {
193
+ display: flex;
194
+ flex-direction: column;
195
+ padding-left: 1.1em;
196
+ margin: 0.4em 0;
197
+ gap: 0.5em;
198
+ }
199
+
200
+ .slide-content li::marker {
201
+ color: var(--slide-accent);
202
+ }
203
+
204
+ .slide-content code {
205
+ padding: 0.1em 0.35em;
206
+ border-radius: 6px;
207
+ background: var(--slide-accent-soft);
208
+ color: var(--slide-answer);
209
+ font-family: var(--font-mono, ui-monospace, SFMono-Regular, Menlo, monospace);
210
+ /* A formula moves to the next line whole, never split at a hyphen. */
211
+ white-space: nowrap;
212
+ }
213
+
214
+ .slide-content pre {
215
+ overflow-x: auto;
216
+ padding: 0.9em 1.1em;
217
+ border-radius: var(--slide-radius);
218
+ margin: 0.5em 0;
219
+ background: var(--slide-accent-soft);
220
+ color: var(--slide-ink);
221
+ font-family: var(--font-mono, ui-monospace, SFMono-Regular, Menlo, monospace);
222
+ font-size: 0.34em;
223
+ line-height: 1.45;
224
+ }
225
+
226
+ .slide-content pre code {
227
+ padding: 0;
228
+ border-radius: 0;
229
+ background: none;
230
+ color: inherit;
231
+ white-space: pre;
232
+ }
233
+
234
+ .slide-content a {
235
+ color: var(--slide-accent);
236
+ }
237
+
238
+ .slide-content blockquote {
239
+ padding: 0.1em 0 0.1em 0.8em;
240
+ border-left: 6px solid var(--slide-accent);
241
+ margin: 0.6em 0;
242
+ color: var(--slide-ink-soft);
243
+ font-size: 0.62em;
244
+ line-height: 1.45;
245
+ }
246
+
247
+ .slide-content img {
248
+ display: block;
249
+ max-width: 100%;
250
+ max-height: 368px;
251
+ margin: 0.5em auto 0;
252
+ }
253
+
254
+ /* ── Content and thanks: title pinned to the top, demos sunk to the bottom ── */
255
+
256
+ .slide--content,
257
+ .slide--thanks {
258
+ display: flex;
259
+ align-self: stretch;
260
+ flex-direction: column;
261
+ margin: 0 auto;
262
+ }
263
+
264
+ .slide--content .slide-content,
265
+ .slide--thanks .slide-content {
266
+ display: flex;
267
+ flex: 1 1 auto;
268
+ flex-direction: column;
269
+ }
270
+
271
+ /* The heading carries a left accent rail and sits in the same place on every
272
+ slide of the deck. */
273
+ .slide--content .slide-content > h2:first-child,
274
+ .slide--thanks .slide-content > h1:first-child {
275
+ padding: 0.02em 0 0.06em 0.55em;
276
+ border-left: 8px solid var(--slide-accent);
277
+ margin-bottom: 0.85em;
278
+ }
279
+
280
+ /* The body centres in the room left between the pinned heading and the demo
281
+ line: these auto margins share the leftover space, so a short slide leaves no
282
+ dead bottom half. On a full slide they collapse to zero. */
283
+ .slide--content .slide-content > h2:first-child + * {
284
+ margin-top: auto;
285
+ }
286
+
287
+ .slide--content .slide-content > :last-child:not(.slide-demos) {
288
+ margin-bottom: auto;
289
+ }
290
+
291
+ /* ── Title ───────────────────────────────────────────────────────────────── */
292
+
293
+ .slide--title {
294
+ display: flex;
295
+ min-height: 100%;
296
+ align-items: center;
297
+ text-align: center;
298
+ }
299
+
300
+ .slide--title .slide-content {
301
+ width: 100%;
302
+ }
303
+
304
+ .slide--title h2 {
305
+ color: var(--slide-muted);
306
+ }
307
+
308
+ /* The author list: bold marks the speaker, underlined by convention. */
309
+ .slide--title p strong {
310
+ font-weight: inherit;
311
+ text-decoration: underline;
312
+ text-underline-offset: 0.15em;
313
+ }
314
+
315
+ /* Affiliation lines. */
316
+ .slide--title p em {
317
+ color: var(--slide-muted);
318
+ font-size: 0.72em;
319
+ }
320
+
321
+ .slide-logos {
322
+ display: flex;
323
+ align-items: center;
324
+ justify-content: center;
325
+ margin-top: 40px;
326
+ gap: 68px;
327
+ }
328
+
329
+ /* Out-specifies the screenshot sizing of `.slide-content img`. */
330
+ .slide-content img.slide-logo {
331
+ width: auto;
332
+ height: 84px;
333
+ max-height: none;
334
+ margin: 0;
335
+ }
336
+
337
+ /* ── Section divider: the ghost numeral, then the title beside it ────────── */
338
+
339
+ .slide--section {
340
+ display: flex;
341
+ align-self: stretch;
342
+ align-items: center;
343
+ }
344
+
345
+ .section-slide {
346
+ display: flex;
347
+ width: 100%;
348
+ align-items: center;
349
+ gap: 96px;
350
+ }
351
+
352
+ .section-number {
353
+ flex: none;
354
+ color: color-mix(in oklab, var(--slide-accent) 18%, transparent);
355
+ font-size: 368px;
356
+ font-weight: 800;
357
+ letter-spacing: -0.04em;
358
+ line-height: 0.72;
359
+ }
360
+
361
+ .section-body {
362
+ display: flex;
363
+ min-width: 0;
364
+ flex-direction: column;
365
+ align-items: flex-start;
366
+ }
367
+
368
+ .section-title {
369
+ margin: 0;
370
+ font-size: 100px;
371
+ letter-spacing: -0.02em;
372
+ line-height: 1.03;
373
+ text-wrap: balance;
374
+ }
375
+
376
+ .section-rule {
377
+ width: 210px;
378
+ height: 5px;
379
+ border: 0;
380
+ margin: 39px 0;
381
+ background: var(--slide-accent);
382
+ }
383
+
384
+ .section-sub {
385
+ color: var(--slide-muted);
386
+ font-size: 44px;
387
+ line-height: 1.3;
388
+ }
389
+
390
+ .section-sub h2 {
391
+ margin: 0;
392
+ color: var(--slide-ink-soft);
393
+ font-size: inherit;
394
+ font-weight: 600;
395
+ letter-spacing: -0.01em;
396
+ }
397
+
398
+ .section-sub p {
399
+ margin: 0.5em 0 0;
400
+ font-size: 0.82em;
401
+ }
402
+
403
+ /* ── Quote ───────────────────────────────────────────────────────────────── */
404
+
405
+ .slide--quote {
406
+ display: flex;
407
+ min-height: 100%;
408
+ align-items: center;
409
+ }
410
+
411
+ .slide--quote .slide-content {
412
+ width: 100%;
413
+ }
414
+
415
+ /* The quote is the slide, so it drops the rail its inline form carries and is
416
+ set at the size a room reads from the back. */
417
+ .slide--quote .slide-content blockquote {
418
+ padding: 0;
419
+ border: 0;
420
+ margin: 0;
421
+ color: var(--slide-ink);
422
+ font-size: 1.15em;
423
+ line-height: 1.25;
424
+ text-wrap: balance;
425
+ }
426
+
427
+ /* The attribution under the quote. */
428
+ .slide--quote .slide-content blockquote + p,
429
+ .slide--quote .slide-content blockquote > p:last-child em {
430
+ color: var(--slide-muted);
431
+ font-size: 0.62em;
432
+ font-style: normal;
433
+ }
434
+
435
+ /* ── Thanks ──────────────────────────────────────────────────────────────── */
436
+
437
+ /* The credits read as cards: the group is a small accent label, the people are
438
+ large. */
439
+ .slide--thanks .slide-content ul {
440
+ display: grid;
441
+ padding: 0;
442
+ margin: 0;
443
+ gap: 30px 36px;
444
+ grid-template-columns: 1fr 1fr;
445
+ list-style: none;
446
+ }
447
+
448
+ .slide--thanks .slide-content li {
449
+ display: flex;
450
+ flex-direction: column;
451
+ justify-content: flex-start;
452
+ padding: 27px 39px;
453
+ border: 1px solid var(--slide-line);
454
+ border-left: 6px solid var(--slide-accent);
455
+ border-radius: 18px;
456
+ background: var(--slide-surface);
457
+ font-size: 39px;
458
+ font-weight: 600;
459
+ line-height: 1.35;
460
+ }
461
+
462
+ .slide--thanks .slide-content li:last-child {
463
+ grid-column: 1 / -1;
464
+ }
465
+
466
+ .slide--thanks .slide-content li > strong {
467
+ display: block;
468
+ margin-bottom: 0.25em;
469
+ color: var(--slide-accent);
470
+ font-size: 24px;
471
+ letter-spacing: 0.07em;
472
+ text-transform: uppercase;
473
+ }
474
+
475
+ .slide--thanks .slide-content li em {
476
+ display: block;
477
+ margin-top: 0.2em;
478
+ color: var(--slide-muted);
479
+ font-size: 26px;
480
+ font-style: normal;
481
+ font-weight: 400;
482
+ }
483
+
484
+ /* The closing line sits quietly at the bottom. */
485
+ .slide--thanks .slide-content > p:last-child {
486
+ padding-top: 0.7em;
487
+ border-top: 1px solid var(--slide-line);
488
+ margin: auto 0 0;
489
+ color: var(--slide-ink-soft);
490
+ font-size: 0.73em;
491
+ }
492
+
493
+ /* ── Demo links ──────────────────────────────────────────────────────────── */
494
+
495
+ /* One quiet caption line pinned to the bottom of the slide. */
496
+ .slide-demos {
497
+ display: flex;
498
+ flex-wrap: wrap;
499
+ align-items: baseline;
500
+ margin-top: auto;
501
+ color: var(--slide-muted);
502
+ font-size: 0.46em;
503
+ font-weight: 600;
504
+ gap: 0.5em;
505
+ }
506
+
507
+ .slide-demos-separator {
508
+ color: var(--slide-line);
509
+ }
510
+
511
+ .slide-demo.slide-demo {
512
+ display: inline;
513
+ padding: 0;
514
+ border: 0;
515
+ margin: 0;
516
+ background: none;
517
+ color: var(--slide-accent);
518
+ cursor: pointer;
519
+ font: inherit;
520
+ text-decoration: none;
521
+ }
522
+
523
+ /* The caption already reads "Live demos:", so a per-link arrow is redundant
524
+ there; a link inside the body keeps its arrow. */
525
+ .slide-demos .slide-demo .slide-demo-arrow {
526
+ display: none;
527
+ }
528
+
529
+ .slide-demo.slide-demo:hover .slide-demo-label {
530
+ text-decoration: underline;
531
+ text-underline-offset: 3px;
532
+ }
533
+
534
+ /* ── The list of talks ───────────────────────────────────────────────────── */
535
+
536
+ .talk-list {
537
+ display: flex;
538
+ flex-direction: column;
539
+ gap: 32px;
540
+ }
541
+
542
+ .talk-list-site {
543
+ margin: 0 0 12px;
544
+ color: var(--slide-muted);
545
+ font-size: 0.85rem;
546
+ font-weight: 700;
547
+ letter-spacing: 0.06em;
548
+ text-transform: uppercase;
549
+ }
550
+
551
+ .talk-grid {
552
+ display: grid;
553
+ gap: 16px;
554
+ grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
555
+ }
556
+
557
+ .talk-card {
558
+ display: block;
559
+ padding: 18px 20px;
560
+ border: 1px solid var(--slide-line);
561
+ border-radius: var(--radius-lg, 16px);
562
+ background: var(--slide-surface);
563
+ color: inherit;
564
+ text-decoration: none;
565
+ transition:
566
+ border-color 0.15s ease,
567
+ transform 0.15s ease,
568
+ box-shadow 0.15s ease;
569
+ }
570
+
571
+ .talk-card:hover {
572
+ border-color: var(--slide-accent);
573
+ box-shadow: var(--shadow-md, 0 4px 14px rgb(16 32 48 / 10%));
574
+ color: inherit;
575
+ text-decoration: none;
576
+ transform: translateY(-2px);
577
+ }
578
+
579
+ .talk-card-title {
580
+ margin-bottom: 6px;
581
+ font-size: 1.15rem;
582
+ font-weight: 600;
583
+ }
584
+
585
+ .talk-card-subtitle {
586
+ margin-bottom: 6px;
587
+ color: var(--slide-ink-soft);
588
+ font-size: 0.95rem;
589
+ }
590
+
591
+ .talk-card-meta {
592
+ color: var(--slide-muted);
593
+ font-size: 0.9rem;
594
+ }
595
+
596
+ .talk-card-count {
597
+ margin-top: 12px;
598
+ color: var(--slide-accent);
599
+ font-size: 0.8rem;
600
+ font-weight: 600;
601
+ letter-spacing: 0.04em;
602
+ text-transform: uppercase;
603
+ }
604
+
605
+ /* ── Back to slides ──────────────────────────────────────────────────────── */
606
+
607
+ /* The way back to the exact slide, floating over whichever tool the demo link
608
+ opened, so a talk stays one click from where it left off. */
609
+ .back-to-slides.back-to-slides {
610
+ position: fixed;
611
+ z-index: 30;
612
+ bottom: 20px;
613
+ left: 20px;
614
+ display: inline-flex;
615
+ align-items: center;
616
+ padding: 0.5rem 0.9rem;
617
+ border: 0;
618
+ border-radius: 999px;
619
+ background: var(--slide-accent);
620
+ box-shadow: var(--shadow-md, 0 4px 14px rgb(16 32 48 / 10%));
621
+ color: #ffffff;
622
+ cursor: pointer;
623
+ font-size: 0.875rem;
624
+ font-weight: 600;
625
+ gap: 0.4rem;
626
+ text-decoration: none;
627
+ }
628
+
629
+ .back-to-slides.back-to-slides:hover {
630
+ color: #ffffff;
631
+ filter: brightness(1.08);
632
+ text-decoration: none;
633
+ }
634
+
635
+ /* ── A slide that is the tool itself ─────────────────────── */
636
+ /* The frame takes the whole slide under the heading: an embedded tool that is
637
+ 200 px tall on a beamer teaches nobody anything. */
638
+ .slide--embed {
639
+ display: flex;
640
+ height: 100%;
641
+ flex-direction: column;
642
+ }
643
+
644
+ .slide--embed .slide-content {
645
+ display: flex;
646
+ height: 100%;
647
+ flex-direction: column;
648
+ gap: 24px;
649
+ }
650
+
651
+ .slide-embed-frame {
652
+ width: 100%;
653
+ flex: 1 1 auto;
654
+ border: 1px solid var(--slide-line);
655
+ border-radius: var(--slide-radius);
656
+ background: var(--slide-surface);
657
+ }
658
+
659
+ .slide-embed-missing {
660
+ color: var(--slide-muted);
661
+ font-style: italic;
662
+ }
663
+
664
+ .talk-list-empty {
665
+ margin: 0;
666
+ color: var(--slide-muted);
667
+ }