simplex-web 0.2.0__py3-none-any.whl

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 (91) hide show
  1. simplex/README.md +32 -0
  2. simplex/cli/README.md +13 -0
  3. simplex/cli/__init__.py +5 -0
  4. simplex/cli/commands.py +384 -0
  5. simplex/deck/README.md +19 -0
  6. simplex/deck/__init__.py +7 -0
  7. simplex/deck/_template/assets/.gitkeep +0 -0
  8. simplex/deck/_template/assets/code/.gitkeep +0 -0
  9. simplex/deck/_template/assets/figures/.gitkeep +0 -0
  10. simplex/deck/_template/deck.toml +11 -0
  11. simplex/deck/_template/manim.cfg +3 -0
  12. simplex/deck/_template/notes.md +27 -0
  13. simplex/deck/_template/refs.bib +12 -0
  14. simplex/deck/_template/slides/__init__.py +7 -0
  15. simplex/deck/_template/slides/intro.py +21 -0
  16. simplex/deck/config.py +207 -0
  17. simplex/deck/registry.py +110 -0
  18. simplex/deck/scaffold.py +86 -0
  19. simplex/deck/section.py +40 -0
  20. simplex/engine/README.md +9 -0
  21. simplex/render/README.md +46 -0
  22. simplex/render/__init__.py +1 -0
  23. simplex/render/html.py +132 -0
  24. simplex/render/pdf.py +32 -0
  25. simplex/render/pptx.py +32 -0
  26. simplex/render/reconcile.py +350 -0
  27. simplex/render/runner.py +116 -0
  28. simplex/render/thumbnail.py +374 -0
  29. simplex/slides/README.md +9 -0
  30. simplex/slides/components/README.md +9 -0
  31. simplex/theme/README.md +9 -0
  32. simplex/web/README.md +33 -0
  33. simplex/web/__init__.py +1 -0
  34. simplex/web/bibliography.py +248 -0
  35. simplex/web/bibtex.py +129 -0
  36. simplex/web/builder.py +321 -0
  37. simplex/web/callouts.py +134 -0
  38. simplex/web/citations.py +118 -0
  39. simplex/web/equations.py +79 -0
  40. simplex/web/notes.py +135 -0
  41. simplex/web/refs.py +60 -0
  42. simplex/web/sidenotes.py +76 -0
  43. simplex/web/site_config.py +71 -0
  44. simplex/web/slide_ref.py +54 -0
  45. simplex/web/static/.gitkeep +0 -0
  46. simplex/web/static/README.md +23 -0
  47. simplex/web/static/fonts/lato/lato-latin-400-italic.woff2 +0 -0
  48. simplex/web/static/fonts/lato/lato-latin-400-normal.woff2 +0 -0
  49. simplex/web/static/fonts/lato/lato-latin-700-italic.woff2 +0 -0
  50. simplex/web/static/fonts/lato/lato-latin-700-normal.woff2 +0 -0
  51. simplex/web/static/fonts/lato/lato-latin-900-normal.woff2 +0 -0
  52. simplex/web/static/fonts/merriweather/merriweather-latin-400-italic.woff2 +0 -0
  53. simplex/web/static/fonts/merriweather/merriweather-latin-400-normal.woff2 +0 -0
  54. simplex/web/static/fonts/merriweather/merriweather-latin-700-italic.woff2 +0 -0
  55. simplex/web/static/fonts/merriweather/merriweather-latin-700-normal.woff2 +0 -0
  56. simplex/web/static/fonts/merriweather/merriweather-latin-900-normal.woff2 +0 -0
  57. simplex/web/static/htmx.min.js +1 -0
  58. simplex/web/static/katex/auto-render.min.js +1 -0
  59. simplex/web/static/katex/fonts/KaTeX_AMS-Regular.woff2 +0 -0
  60. simplex/web/static/katex/fonts/KaTeX_Main-Bold.woff2 +0 -0
  61. simplex/web/static/katex/fonts/KaTeX_Main-Regular.woff2 +0 -0
  62. simplex/web/static/katex/fonts/KaTeX_Math-BoldItalic.woff2 +0 -0
  63. simplex/web/static/katex/fonts/KaTeX_Math-Italic.woff2 +0 -0
  64. simplex/web/static/katex/fonts/KaTeX_Size1-Regular.woff2 +0 -0
  65. simplex/web/static/katex/fonts/KaTeX_Size2-Regular.woff2 +0 -0
  66. simplex/web/static/katex/fonts/KaTeX_Size3-Regular.woff2 +0 -0
  67. simplex/web/static/katex/fonts/KaTeX_Size4-Regular.woff2 +0 -0
  68. simplex/web/static/katex/katex.min.css +1 -0
  69. simplex/web/static/katex/katex.min.js +1 -0
  70. simplex/web/static/lucide/README.md +7 -0
  71. simplex/web/static/lucide/lucide.min.js +12 -0
  72. simplex/web/static/notes.js +68 -0
  73. simplex/web/static/reveal.js/reset.css +30 -0
  74. simplex/web/static/reveal.js/reveal.css +8 -0
  75. simplex/web/static/reveal.js/reveal.js +9 -0
  76. simplex/web/static/simplex.css +1870 -0
  77. simplex/web/static/tailwind.js +64 -0
  78. simplex/web/static/viewer.js +428 -0
  79. simplex/web/templates/README.md +19 -0
  80. simplex/web/templates/_carousel.html +117 -0
  81. simplex/web/templates/base.html +110 -0
  82. simplex/web/templates/deck.html +149 -0
  83. simplex/web/templates/index.html +20 -0
  84. simplex/web/templates/revealjs.html.j2 +374 -0
  85. simplex/web/templates/section.html +74 -0
  86. simplex/web/vendor.py +148 -0
  87. simplex_web-0.2.0.dist-info/METADATA +166 -0
  88. simplex_web-0.2.0.dist-info/RECORD +91 -0
  89. simplex_web-0.2.0.dist-info/WHEEL +4 -0
  90. simplex_web-0.2.0.dist-info/entry_points.txt +2 -0
  91. simplex_web-0.2.0.dist-info/licenses/LICENSE +21 -0
@@ -0,0 +1,1870 @@
1
+ /* Simplex site-specific styles.
2
+ *
3
+ * Layered on top of vendored Tailwind. Keep selectors low-specificity so
4
+ * utility classes in templates still win.
5
+ *
6
+ * Typography stack (academic):
7
+ * - Body / notes: Merriweather (serif), justified, hyphenated.
8
+ * - Headings / chrome: Lato (clean sans, ties to the Francis-Bach reference).
9
+ * - Math: KaTeX vendored woff2 (handled by katex.min.css).
10
+ *
11
+ * CSS variables in `:root` are tied to the `dastimator_dark` theme palette
12
+ * in src/simplex/theme/presets.py. Notes use a *light* surface inside the
13
+ * dark chrome -- closer to a physical paper / journal page, easier to read.
14
+ */
15
+
16
+ /* ------------------------------------------------------------------ */
17
+ /* Fonts (vendored under /static/fonts/* by web/vendor.py) */
18
+ /* ------------------------------------------------------------------ */
19
+
20
+ @font-face {
21
+ font-family: "Lato";
22
+ font-style: normal;
23
+ font-weight: 400;
24
+ font-display: swap;
25
+ src: url("fonts/lato/lato-latin-400-normal.woff2") format("woff2");
26
+ }
27
+ @font-face {
28
+ font-family: "Lato";
29
+ font-style: italic;
30
+ font-weight: 400;
31
+ font-display: swap;
32
+ src: url("fonts/lato/lato-latin-400-italic.woff2") format("woff2");
33
+ }
34
+ @font-face {
35
+ font-family: "Lato";
36
+ font-style: normal;
37
+ font-weight: 700;
38
+ font-display: swap;
39
+ src: url("fonts/lato/lato-latin-700-normal.woff2") format("woff2");
40
+ }
41
+ @font-face {
42
+ font-family: "Lato";
43
+ font-style: italic;
44
+ font-weight: 700;
45
+ font-display: swap;
46
+ src: url("fonts/lato/lato-latin-700-italic.woff2") format("woff2");
47
+ }
48
+ @font-face {
49
+ font-family: "Lato";
50
+ font-style: normal;
51
+ font-weight: 900;
52
+ font-display: swap;
53
+ src: url("fonts/lato/lato-latin-900-normal.woff2") format("woff2");
54
+ }
55
+
56
+ @font-face {
57
+ font-family: "Merriweather";
58
+ font-style: normal;
59
+ font-weight: 400;
60
+ font-display: swap;
61
+ src: url("fonts/merriweather/merriweather-latin-400-normal.woff2") format("woff2");
62
+ }
63
+ @font-face {
64
+ font-family: "Merriweather";
65
+ font-style: italic;
66
+ font-weight: 400;
67
+ font-display: swap;
68
+ src: url("fonts/merriweather/merriweather-latin-400-italic.woff2") format("woff2");
69
+ }
70
+ @font-face {
71
+ font-family: "Merriweather";
72
+ font-style: normal;
73
+ font-weight: 700;
74
+ font-display: swap;
75
+ src: url("fonts/merriweather/merriweather-latin-700-normal.woff2") format("woff2");
76
+ }
77
+ @font-face {
78
+ font-family: "Merriweather";
79
+ font-style: italic;
80
+ font-weight: 700;
81
+ font-display: swap;
82
+ src: url("fonts/merriweather/merriweather-latin-700-italic.woff2") format("woff2");
83
+ }
84
+ @font-face {
85
+ font-family: "Merriweather";
86
+ font-style: normal;
87
+ font-weight: 900;
88
+ font-display: swap;
89
+ src: url("fonts/merriweather/merriweather-latin-900-normal.woff2") format("woff2");
90
+ }
91
+
92
+ :root {
93
+ --site-bg: #2b2b2b;
94
+ --site-surface: rgba(28, 30, 31, 0.82);
95
+ --site-surface-solid: #1c1e1f;
96
+ --site-surface-hover: #25282a;
97
+ --site-elevated: #151617;
98
+ --canvas-text: #f5f7f8;
99
+ --canvas-muted: #b8c0c4;
100
+ --site-text: #f5f7f8;
101
+ --site-muted: #b8c0c4;
102
+ --site-dim: #788185;
103
+ --site-border: rgba(255, 255, 255, 0.11);
104
+ --site-accent: #f4c84a;
105
+ --site-blue: #1058c2;
106
+ --site-control: #585f62;
107
+ --bg: var(--site-bg);
108
+ --bg-card: var(--site-surface-solid);
109
+ --bg-card-hover: var(--site-surface-hover);
110
+ --fg: var(--site-text);
111
+ --fg-muted: var(--site-muted);
112
+ --fg-dim: var(--site-dim);
113
+ --accent: var(--site-accent);
114
+ --border: var(--site-border);
115
+ --radius-card: 8px;
116
+ --shadow-card: 0 16px 36px -22px rgba(0, 0, 0, 0.95);
117
+ --shadow-nav: 0 18px 50px -30px rgba(0, 0, 0, 0.85);
118
+
119
+ /* Notes surface -- a paper-like reading pane within the dark chrome. */
120
+ --notes-bg: #fdfaf3;
121
+ --notes-fg: #1d1c1a;
122
+ --notes-fg-soft: #3b3a36;
123
+ --notes-fg-dim: #6c6a64;
124
+ --notes-rule: #e3ddcd;
125
+ --notes-accent: #8a5a00;
126
+ --notes-link: #1e4f8a;
127
+ --notes-blockquote-bg: #f3eedd;
128
+ --notes-code-bg: #f3efe2;
129
+ --notes-pre-bg: #1c1d1f;
130
+ --notes-pre-fg: #d4d4d4;
131
+ --notes-sidenote-bg: #fbf6e6;
132
+
133
+ --font-sans: "Lato", -apple-system, BlinkMacSystemFont, "Segoe UI",
134
+ Roboto, "Helvetica Neue", Arial, sans-serif;
135
+ --font-serif: "Merriweather", "Iowan Old Style", "Apple Garamond",
136
+ "Palatino Linotype", "Georgia", "Times New Roman", serif;
137
+ --font-mono: ui-monospace, "JetBrains Mono", "SFMono-Regular", Menlo,
138
+ Consolas, "Liberation Mono", monospace;
139
+ }
140
+
141
+ [data-theme="light"] {
142
+ --site-bg: #f3f5f7;
143
+ --site-surface: rgba(255, 255, 255, 0.86);
144
+ --site-surface-solid: #ffffff;
145
+ --site-surface-hover: #edf1f5;
146
+ --site-elevated: #ffffff;
147
+ --canvas-text: #15191c;
148
+ --canvas-muted: #50606a;
149
+ --site-text: #15191c;
150
+ --site-muted: #50606a;
151
+ --site-dim: #77858d;
152
+ --site-border: rgba(24, 34, 42, 0.13);
153
+ --site-accent: #9b6b00;
154
+ --site-control: #58636a;
155
+ --shadow-card: 0 18px 38px -28px rgba(21, 31, 40, 0.34);
156
+ --shadow-nav: 0 18px 42px -30px rgba(21, 31, 40, 0.38);
157
+ }
158
+
159
+ html {
160
+ background: var(--site-bg);
161
+ font-family: var(--font-sans);
162
+ }
163
+
164
+ /* Site chrome owns the page colors. Deck palettes only provide
165
+ * ``--simplex-*`` tokens for slide/chrome accents, never the body
166
+ * background; keep this as the single source of truth for the portal page. */
167
+ body {
168
+ margin: 0;
169
+ background: var(--site-bg);
170
+ color: var(--canvas-text);
171
+ font-family: var(--simplex-font-sans, var(--font-sans));
172
+ overflow-x: hidden;
173
+ }
174
+
175
+ .icon-fallback {
176
+ display: inline-flex;
177
+ align-items: center;
178
+ justify-content: center;
179
+ font: inherit;
180
+ line-height: 1;
181
+ }
182
+ .icon-fallback.is-hidden {
183
+ display: none !important;
184
+ }
185
+
186
+ .skip-link {
187
+ position: absolute;
188
+ left: -9999px;
189
+ top: 0.5rem;
190
+ background: var(--bg-card);
191
+ color: var(--fg);
192
+ padding: 0.5rem 0.75rem;
193
+ border-radius: 6px;
194
+ z-index: 100;
195
+ }
196
+ .skip-link:focus {
197
+ left: 0.5rem;
198
+ outline: 2px solid var(--accent);
199
+ }
200
+
201
+ :focus-visible {
202
+ outline: 2px solid var(--accent);
203
+ outline-offset: 2px;
204
+ }
205
+
206
+ /* ------------------------------------------------------------------ */
207
+ /* Shared chrome */
208
+ /* ------------------------------------------------------------------ */
209
+
210
+ .site-nav-wrap {
211
+ position: sticky;
212
+ top: 0;
213
+ z-index: 80;
214
+ padding: 0.85rem clamp(1rem, 4vw, 2.25rem) 0.55rem;
215
+ pointer-events: none;
216
+ }
217
+ .site-navbar {
218
+ width: min(1180px, 100%);
219
+ box-sizing: border-box;
220
+ margin: 0 auto;
221
+ min-height: 3.45rem;
222
+ display: flex;
223
+ align-items: center;
224
+ gap: 0.65rem;
225
+ padding: 0.45rem;
226
+ border: 1px solid var(--site-border);
227
+ border-radius: 999px;
228
+ background: var(--site-surface);
229
+ box-shadow: var(--shadow-nav);
230
+ backdrop-filter: blur(18px) saturate(1.3);
231
+ pointer-events: auto;
232
+ }
233
+ .site-brand,
234
+ .site-nav-link,
235
+ .site-resource-link,
236
+ .theme-toggle {
237
+ min-height: 2.45rem;
238
+ display: inline-flex;
239
+ align-items: center;
240
+ justify-content: center;
241
+ gap: 0.45rem;
242
+ color: var(--site-text);
243
+ text-decoration: none;
244
+ border-radius: 999px;
245
+ line-height: 1;
246
+ white-space: nowrap;
247
+ }
248
+ .site-brand {
249
+ padding: 0 0.85rem 0 0.75rem;
250
+ font-weight: 800;
251
+ }
252
+ .site-brand svg,
253
+ .site-nav-link svg,
254
+ .site-resource-link svg,
255
+ .theme-toggle svg,
256
+ .site-footer svg {
257
+ width: 1rem;
258
+ height: 1rem;
259
+ flex: 0 0 auto;
260
+ }
261
+ .github-square-icon {
262
+ position: relative;
263
+ width: 2rem;
264
+ height: 2rem;
265
+ flex: 0 0 auto;
266
+ display: inline-block;
267
+ border-radius: 4px;
268
+ background: currentColor;
269
+ }
270
+ .github-square-icon::before {
271
+ content: "";
272
+ position: absolute;
273
+ inset: 0.3rem;
274
+ background: var(--site-surface-solid);
275
+ -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82A7.65 7.65 0 0 1 8 4.42c.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.19 0 .21.15.46.55.38A8.013 8.013 0 0 0 16 8c0-4.42-3.58-8-8-8z'/%3E%3C/svg%3E") center / contain no-repeat;
276
+ mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82A7.65 7.65 0 0 1 8 4.42c.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.19 0 .21.15.46.55.38A8.013 8.013 0 0 0 16 8c0-4.42-3.58-8-8-8z'/%3E%3C/svg%3E") center / contain no-repeat;
277
+ }
278
+ .pdf-file-icon {
279
+ position: relative;
280
+ width: 1rem;
281
+ height: 1.22rem;
282
+ flex: 0 0 auto;
283
+ display: inline-flex;
284
+ align-items: end;
285
+ justify-content: center;
286
+ padding-bottom: 0.14rem;
287
+ border: 1.6px solid currentColor;
288
+ border-radius: 2px;
289
+ background: rgba(255, 255, 255, 0.06);
290
+ line-height: 1;
291
+ }
292
+ .pdf-file-icon::after {
293
+ content: "";
294
+ position: absolute;
295
+ top: -1.6px;
296
+ right: -1.6px;
297
+ width: 0.34rem;
298
+ height: 0.34rem;
299
+ border-left: 1.6px solid currentColor;
300
+ border-bottom: 1.6px solid currentColor;
301
+ background: var(--site-surface-solid);
302
+ clip-path: polygon(0 0, 100% 100%, 0 100%);
303
+ }
304
+ .pdf-file-icon > span {
305
+ color: #e53935;
306
+ font-size: 0.34rem;
307
+ font-weight: 900;
308
+ letter-spacing: 0;
309
+ }
310
+ .site-nav-links {
311
+ display: flex;
312
+ align-items: center;
313
+ gap: 0.25rem;
314
+ min-width: 0;
315
+ }
316
+ .site-nav-link,
317
+ .site-resource-link {
318
+ padding: 0 0.72rem;
319
+ color: var(--site-muted);
320
+ font-size: 0.9rem;
321
+ transition: background 150ms ease, color 150ms ease;
322
+ }
323
+ .site-nav-link-icon-only {
324
+ width: 3rem;
325
+ padding: 0;
326
+ }
327
+ .site-nav-link:hover,
328
+ .site-resource-link:hover {
329
+ background: var(--site-surface-hover);
330
+ color: var(--site-text);
331
+ }
332
+ .site-nav-actions {
333
+ margin-left: auto;
334
+ display: flex;
335
+ align-items: center;
336
+ gap: 0.35rem;
337
+ min-width: max-content;
338
+ width: max-content;
339
+ flex: 0 0 auto;
340
+ }
341
+ .site-resource-link {
342
+ background: rgba(255, 255, 255, 0.06);
343
+ border: 1px solid var(--site-border);
344
+ }
345
+ [data-theme="light"] .site-resource-link {
346
+ background: rgba(16, 88, 194, 0.08);
347
+ }
348
+ .theme-toggle {
349
+ position: relative;
350
+ width: 2.45rem;
351
+ padding: 0;
352
+ border: 0;
353
+ background: var(--site-surface-hover);
354
+ color: var(--site-text);
355
+ cursor: pointer;
356
+ }
357
+ .theme-toggle-fallback {
358
+ font-size: 1.05rem;
359
+ color: currentColor;
360
+ }
361
+ .theme-icon {
362
+ position: absolute;
363
+ transition: opacity 150ms ease, transform 150ms ease;
364
+ }
365
+ [data-theme="dark"] .theme-icon-sun,
366
+ [data-theme="light"] .theme-icon-moon {
367
+ opacity: 1;
368
+ transform: scale(1);
369
+ }
370
+ [data-theme="dark"] .theme-icon-moon,
371
+ [data-theme="light"] .theme-icon-sun {
372
+ opacity: 0;
373
+ transform: scale(0.65);
374
+ }
375
+ .site-footer {
376
+ width: min(1180px, calc(100vw - 2rem));
377
+ margin: 3rem auto 1.5rem;
378
+ display: flex;
379
+ align-items: center;
380
+ justify-content: space-between;
381
+ gap: 1rem;
382
+ color: var(--canvas-muted);
383
+ font-size: 0.78rem;
384
+ }
385
+ .site-footer a {
386
+ display: inline-flex;
387
+ align-items: center;
388
+ gap: 0.35rem;
389
+ color: var(--canvas-muted);
390
+ text-decoration: none;
391
+ }
392
+ .site-footer a:hover { color: var(--canvas-text); }
393
+ @media (max-width: 760px) {
394
+ .site-nav-wrap {
395
+ width: 100vw;
396
+ box-sizing: border-box;
397
+ padding: 0.75rem 0.5rem 0.45rem;
398
+ }
399
+ .site-navbar {
400
+ display: flex;
401
+ flex-wrap: nowrap;
402
+ width: 100%;
403
+ max-width: 100%;
404
+ min-height: 3rem;
405
+ border-radius: 999px;
406
+ align-items: center;
407
+ gap: 0.25rem;
408
+ padding: 0.35rem;
409
+ }
410
+ .site-brand {
411
+ flex: 0 1 auto;
412
+ min-width: 0;
413
+ padding: 0 0.65rem;
414
+ justify-content: flex-start;
415
+ }
416
+ .site-nav-links {
417
+ flex: 0 1 auto;
418
+ width: auto;
419
+ overflow: visible;
420
+ padding: 0;
421
+ }
422
+ .site-nav-actions {
423
+ flex: 0 0 auto;
424
+ width: auto;
425
+ justify-content: flex-end;
426
+ margin-left: 0;
427
+ }
428
+ .site-resource-link {
429
+ width: 2.45rem;
430
+ padding: 0;
431
+ }
432
+ .site-resource-link > span:not(.pdf-file-icon) { display: none; }
433
+ .site-resource-link .pdf-file-icon { display: inline-flex; }
434
+ }
435
+
436
+ @media (max-width: 480px) {
437
+ .site-nav-link:not(.site-nav-link-icon-only) {
438
+ width: 2.45rem;
439
+ padding: 0;
440
+ }
441
+ .site-nav-link:not(.site-nav-link-icon-only) > span:not(.icon-fallback) {
442
+ display: none;
443
+ }
444
+ }
445
+
446
+ @media (max-width: 380px) {
447
+ .site-brand {
448
+ padding: 0 0.55rem;
449
+ }
450
+ }
451
+
452
+ /* ------------------------------------------------------------------ */
453
+ /* Carousel */
454
+ /* ------------------------------------------------------------------ */
455
+
456
+ .carousel-section { scroll-margin-top: 4rem; }
457
+
458
+ .carousel-track {
459
+ display: flex;
460
+ gap: 1rem;
461
+ overflow-x: auto;
462
+ overflow-y: hidden;
463
+ scroll-snap-type: x mandatory;
464
+ scroll-behavior: smooth;
465
+ padding: 0.25rem 0 1.5rem 0;
466
+ margin: 0;
467
+ list-style: none;
468
+ scrollbar-color: var(--fg-dim) transparent;
469
+ }
470
+ .carousel-track::-webkit-scrollbar { height: 6px; }
471
+ .carousel-track::-webkit-scrollbar-thumb {
472
+ background: var(--fg-dim);
473
+ border-radius: 4px;
474
+ }
475
+
476
+ .carousel-card-wrap {
477
+ flex: 0 0 320px;
478
+ scroll-snap-align: start;
479
+ }
480
+ @media (min-width: 768px) {
481
+ .carousel-card-wrap { flex-basis: 380px; }
482
+ }
483
+
484
+ .carousel-card {
485
+ display: block;
486
+ background: var(--bg-card);
487
+ border-radius: var(--radius-card);
488
+ overflow: hidden;
489
+ text-decoration: none;
490
+ color: inherit;
491
+ position: relative;
492
+ transition: transform 200ms ease, box-shadow 200ms ease;
493
+ isolation: isolate;
494
+ }
495
+ .carousel-card:hover,
496
+ .carousel-card:focus-visible {
497
+ transform: translateY(-2px) scale(1.01);
498
+ box-shadow: var(--shadow-card);
499
+ }
500
+ .carousel-card::before {
501
+ content: "";
502
+ position: absolute;
503
+ inset: 0 auto 0 0;
504
+ width: 0;
505
+ background: var(--accent);
506
+ transition: width 200ms ease;
507
+ z-index: 2;
508
+ }
509
+ .carousel-card:hover::before,
510
+ .carousel-card:focus-visible::before { width: 4px; }
511
+
512
+ .carousel-thumb {
513
+ position: relative;
514
+ aspect-ratio: 16 / 9;
515
+ background: #111;
516
+ overflow: hidden;
517
+ }
518
+ .carousel-thumb img,
519
+ .carousel-thumb-empty {
520
+ width: 100%; height: 100%;
521
+ object-fit: cover;
522
+ display: block;
523
+ }
524
+ .carousel-thumb-empty {
525
+ display: flex;
526
+ align-items: center; justify-content: center;
527
+ background: linear-gradient(135deg, #2a2a2a, #1a1a1a);
528
+ color: var(--fg-dim);
529
+ font-size: 3rem;
530
+ }
531
+
532
+ .carousel-overlay {
533
+ position: absolute;
534
+ inset: auto 0 0 0;
535
+ padding: 1rem;
536
+ background: linear-gradient(
537
+ 180deg,
538
+ rgba(36, 36, 36, 0) 0%,
539
+ rgba(20, 20, 20, 0.92) 75%
540
+ );
541
+ opacity: 0;
542
+ transform: translateY(8px);
543
+ transition: opacity 200ms ease, transform 200ms ease;
544
+ display: flex;
545
+ justify-content: space-between;
546
+ align-items: flex-end;
547
+ }
548
+ .carousel-card:hover .carousel-overlay,
549
+ .carousel-card:focus-visible .carousel-overlay {
550
+ opacity: 1;
551
+ transform: translateY(0);
552
+ }
553
+
554
+ .carousel-meta {
555
+ display: flex; gap: 0.5rem; align-items: center;
556
+ font-size: 0.75rem;
557
+ }
558
+ .carousel-badge {
559
+ background: var(--accent);
560
+ color: #1a1a1a;
561
+ padding: 0.15rem 0.5rem;
562
+ border-radius: 999px;
563
+ font-weight: 600;
564
+ }
565
+ .carousel-duration { color: var(--fg-muted); }
566
+ .carousel-cta {
567
+ color: var(--fg);
568
+ font-size: 0.85rem;
569
+ font-weight: 500;
570
+ }
571
+
572
+ .carousel-text { padding: 0.85rem 1rem 1.1rem 1rem; }
573
+ .carousel-title {
574
+ font-size: 1.05rem;
575
+ font-weight: 600;
576
+ letter-spacing: -0.01em;
577
+ }
578
+ .carousel-sub {
579
+ color: var(--fg-muted);
580
+ font-size: 0.85rem;
581
+ margin-top: 0.25rem;
582
+ display: -webkit-box;
583
+ -webkit-line-clamp: 2;
584
+ -webkit-box-orient: vertical;
585
+ overflow: hidden;
586
+ }
587
+
588
+ .carousel-arrow {
589
+ position: absolute;
590
+ top: 35%;
591
+ width: 40px; height: 40px;
592
+ border-radius: 999px;
593
+ background: rgba(0, 0, 0, 0.65);
594
+ color: var(--fg);
595
+ border: 1px solid var(--border);
596
+ display: flex;
597
+ align-items: center; justify-content: center;
598
+ cursor: pointer;
599
+ z-index: 5;
600
+ font-size: 1.1rem;
601
+ transition: background 150ms ease, opacity 150ms ease;
602
+ }
603
+ .carousel-arrow:hover { background: rgba(0, 0, 0, 0.85); }
604
+ .carousel-arrow-prev { left: -10px; }
605
+ .carousel-arrow-next { right: -10px; }
606
+ .carousel-arrow[hidden] { display: none; }
607
+ @media (hover: none) {
608
+ .carousel-arrow { display: none; }
609
+ }
610
+
611
+ /* ------------------------------------------------------------------ */
612
+ /* Deck page */
613
+ /* ------------------------------------------------------------------ */
614
+
615
+ /* Three areas: viewer (slides + controls), sidebar (slide list), notes.
616
+ Narrow layout: viewer -> sidebar -> notes. Wide layout: viewer + sidebar
617
+ on top row, notes underneath the viewer with the sidebar still anchored
618
+ right alongside. */
619
+ .deck-grid {
620
+ display: grid;
621
+ gap: 1.25rem;
622
+ grid-template-columns: minmax(0, 1fr);
623
+ grid-template-areas:
624
+ "viewer"
625
+ "sidebar"
626
+ "notes";
627
+ }
628
+ .deck-viewer { grid-area: viewer; min-width: 0; }
629
+ .deck-sidebar { grid-area: sidebar; min-width: 0; }
630
+ .deck-notes { grid-area: notes; min-width: 0; }
631
+
632
+ @media (min-width: 1024px) {
633
+ .deck-grid {
634
+ grid-template-columns: minmax(0, 7fr) minmax(280px, 3fr);
635
+ grid-template-areas:
636
+ "viewer sidebar"
637
+ "notes sidebar";
638
+ }
639
+ }
640
+
641
+ .deck-viewer-frame {
642
+ aspect-ratio: 16 / 9;
643
+ background: var(--bg);
644
+ border-radius: var(--radius-card);
645
+ overflow: hidden;
646
+ box-shadow: var(--shadow-card);
647
+ }
648
+ .deck-iframe {
649
+ width: 100%; height: 100%;
650
+ border: 0;
651
+ display: block;
652
+ background: var(--bg);
653
+ }
654
+ .deck-viewer-frame:fullscreen {
655
+ aspect-ratio: auto;
656
+ width: 100vw;
657
+ height: 100vh;
658
+ border-radius: 0;
659
+ }
660
+ .deck-viewer-frame:fullscreen .deck-iframe { height: 100vh; }
661
+
662
+ .deck-controls {
663
+ display: flex;
664
+ justify-content: space-between;
665
+ align-items: center;
666
+ margin-top: 0.6rem;
667
+ padding: 0.45rem 0.6rem;
668
+ background: var(--bg-card);
669
+ border-radius: 10px;
670
+ border: 1px solid var(--border);
671
+ flex-wrap: wrap;
672
+ gap: 0.4rem;
673
+ }
674
+ .deck-controls-left,
675
+ .deck-controls-right {
676
+ display: flex;
677
+ gap: 0.35rem;
678
+ align-items: center;
679
+ }
680
+ .deck-ctl-btn {
681
+ background: transparent;
682
+ color: var(--fg);
683
+ border: 1px solid transparent;
684
+ border-radius: 8px;
685
+ padding: 0.4rem;
686
+ cursor: pointer;
687
+ display: inline-flex;
688
+ align-items: center;
689
+ justify-content: center;
690
+ width: 2.2rem;
691
+ height: 2.2rem;
692
+ line-height: 0;
693
+ transition: background 150ms ease, color 150ms ease, border-color 150ms ease,
694
+ transform 80ms ease;
695
+ }
696
+ .deck-ctl-btn svg { width: 1.15rem; height: 1.15rem; }
697
+ .deck-ctl-btn:hover {
698
+ background: var(--bg-card-hover);
699
+ border-color: var(--border);
700
+ }
701
+ .deck-ctl-btn:active { transform: scale(0.94); }
702
+ .deck-ctl-play {
703
+ background: var(--accent);
704
+ color: #1a1a1a;
705
+ width: 2.6rem;
706
+ height: 2.6rem;
707
+ }
708
+ .deck-ctl-play:hover {
709
+ background: #ffe44d;
710
+ border-color: transparent;
711
+ color: #1a1a1a;
712
+ }
713
+ .deck-ctl-play .deck-ctl-icon-pause { display: none; }
714
+ .deck-ctl-play[data-state="playing"] .deck-ctl-icon-play { display: none; }
715
+ .deck-ctl-play[data-state="playing"] .deck-ctl-icon-pause { display: inline; }
716
+ .deck-counter {
717
+ font-variant-numeric: tabular-nums;
718
+ color: var(--fg-muted);
719
+ padding: 0 0.6rem;
720
+ font-size: 0.85rem;
721
+ }
722
+
723
+ .deck-sidebar {
724
+ background: var(--bg-card);
725
+ border-radius: var(--radius-card);
726
+ border: 1px solid var(--border);
727
+ padding: 0.9rem;
728
+ }
729
+ @media (min-width: 1024px) {
730
+ .deck-sidebar {
731
+ height: fit-content;
732
+ max-height: calc(100vh - 6rem);
733
+ overflow-y: auto;
734
+ position: sticky;
735
+ top: 1rem;
736
+ }
737
+ }
738
+ .deck-sidebar-title {
739
+ font-size: 0.7rem;
740
+ text-transform: uppercase;
741
+ letter-spacing: 0.1em;
742
+ color: var(--fg-dim);
743
+ margin: 0 0 0.7rem 0;
744
+ }
745
+
746
+ /* Wide: vertical stack of cards. Narrow: horizontal scrollable row. */
747
+ .deck-slide-list {
748
+ list-style: none;
749
+ margin: 0; padding: 0;
750
+ display: flex;
751
+ flex-direction: column;
752
+ gap: 0.6rem;
753
+ }
754
+ @media (max-width: 1023px) {
755
+ .deck-slide-list {
756
+ flex-direction: row;
757
+ overflow-x: auto;
758
+ overflow-y: hidden;
759
+ scroll-snap-type: x mandatory;
760
+ padding-bottom: 0.4rem;
761
+ scrollbar-color: var(--fg-dim) transparent;
762
+ }
763
+ .deck-slide-list::-webkit-scrollbar { height: 6px; }
764
+ .deck-slide-list::-webkit-scrollbar-thumb {
765
+ background: var(--fg-dim);
766
+ border-radius: 4px;
767
+ }
768
+ .deck-slide-list > li {
769
+ flex: 0 0 220px;
770
+ scroll-snap-align: start;
771
+ }
772
+ }
773
+
774
+ .deck-slide-card {
775
+ display: flex;
776
+ flex-direction: column;
777
+ width: 100%;
778
+ background: var(--bg);
779
+ border: 1px solid var(--border);
780
+ border-radius: 10px;
781
+ padding: 0;
782
+ overflow: hidden;
783
+ text-align: left;
784
+ color: inherit;
785
+ cursor: pointer;
786
+ transition: background 150ms ease, border-color 150ms ease,
787
+ transform 100ms ease;
788
+ }
789
+ .deck-slide-card:hover {
790
+ background: var(--bg-card-hover);
791
+ border-color: #3a3a3a;
792
+ transform: translateY(-1px);
793
+ }
794
+ .deck-slide-card[aria-current="true"] {
795
+ border-color: var(--accent);
796
+ box-shadow: 0 0 0 1px var(--accent) inset;
797
+ }
798
+
799
+ .deck-slide-head {
800
+ display: flex;
801
+ align-items: center;
802
+ justify-content: space-between;
803
+ gap: 0.5rem;
804
+ padding: 0.45rem 0.6rem;
805
+ background: var(--bg-card);
806
+ border-bottom: 1px solid var(--border);
807
+ min-width: 0;
808
+ }
809
+ .deck-slide-title {
810
+ font-size: 0.82rem;
811
+ font-weight: 500;
812
+ color: var(--fg);
813
+ white-space: nowrap;
814
+ overflow: hidden;
815
+ text-overflow: ellipsis;
816
+ min-width: 0;
817
+ flex: 1 1 auto;
818
+ }
819
+ .deck-slide-duration {
820
+ font-size: 0.72rem;
821
+ color: var(--fg-dim);
822
+ font-variant-numeric: tabular-nums;
823
+ flex: 0 0 auto;
824
+ }
825
+ .deck-slide-card[aria-current="true"] .deck-slide-head {
826
+ background: rgba(255, 215, 0, 0.08);
827
+ }
828
+
829
+ .deck-slide-thumb {
830
+ position: relative;
831
+ aspect-ratio: 16 / 9;
832
+ overflow: hidden;
833
+ background: var(--bg);
834
+ width: 100%;
835
+ }
836
+ .deck-slide-thumb img,
837
+ .deck-slide-thumb-empty {
838
+ width: 100%; height: 100%;
839
+ object-fit: cover;
840
+ display: block;
841
+ }
842
+ .deck-slide-thumb-empty {
843
+ background: linear-gradient(135deg, #2a2a2a, #161616);
844
+ }
845
+
846
+ /* ------------------------------------------------------------------ */
847
+ /* Academic notes pane */
848
+ /* ------------------------------------------------------------------ */
849
+ /*
850
+ * The notes pane is a paper-like reading surface. Layout reserves a 35%
851
+ * right margin on wide screens (>= 1280px) where Tufte-style sidenotes
852
+ * float; on narrower viewports the margin collapses and sidenotes inline
853
+ * via a CSS-only "click the number" toggle.
854
+ */
855
+
856
+ .deck-notes {
857
+ margin-top: 0.25rem;
858
+ background: var(--notes-bg);
859
+ color: var(--notes-fg);
860
+ border-radius: var(--radius-card);
861
+ box-shadow: var(--shadow-card);
862
+ padding: 2.5rem clamp(1.25rem, 4vw, 3rem);
863
+ font-family: var(--font-serif);
864
+ font-size: 1.05rem;
865
+ line-height: 1.75;
866
+ /* `text-align: justify` with hyphens makes dense technical prose read
867
+ like a typeset journal page; without hyphens it would leave rivers. */
868
+ text-align: justify;
869
+ text-justify: inter-word;
870
+ hyphens: auto;
871
+ -webkit-hyphens: auto;
872
+ position: relative;
873
+ overflow-wrap: break-word;
874
+ }
875
+
876
+ @media (min-width: 1280px) {
877
+ .deck-notes {
878
+ /* Reserve a margin for sidenotes. The padding-right reservation,
879
+ combined with `.sidenote { right: 0; width: 32%; }`, places the
880
+ note in the gutter without overlapping body text. */
881
+ padding-right: clamp(2rem, 35%, 22rem);
882
+ }
883
+ }
884
+
885
+ .deck-notes h1,
886
+ .deck-notes h2,
887
+ .deck-notes h3,
888
+ .deck-notes h4,
889
+ .deck-notes h5,
890
+ .deck-notes h6 {
891
+ font-family: var(--font-sans);
892
+ color: var(--notes-fg);
893
+ font-weight: 700;
894
+ letter-spacing: -0.005em;
895
+ line-height: 1.25;
896
+ margin: 1.8em 0 0.55em;
897
+ text-align: left;
898
+ hyphens: manual;
899
+ }
900
+ .deck-notes h1 {
901
+ font-size: 2.1rem;
902
+ font-weight: 900;
903
+ margin-top: 0;
904
+ border-bottom: 1px solid var(--notes-rule);
905
+ padding-bottom: 0.45em;
906
+ }
907
+ .deck-notes h2 {
908
+ font-size: 1.55rem;
909
+ border-bottom: 1px solid var(--notes-rule);
910
+ padding-bottom: 0.3em;
911
+ }
912
+ .deck-notes h3 { font-size: 1.22rem; }
913
+ .deck-notes h4 { font-size: 1.08rem; color: var(--notes-fg-soft); }
914
+
915
+ .deck-notes p,
916
+ .deck-notes li {
917
+ color: var(--notes-fg);
918
+ line-height: 1.75;
919
+ }
920
+ .deck-notes p { margin: 0.9em 0; }
921
+ .deck-notes a {
922
+ color: var(--notes-link);
923
+ text-decoration: underline;
924
+ text-decoration-thickness: 1px;
925
+ text-underline-offset: 0.18em;
926
+ }
927
+ .deck-notes a:hover { text-decoration-thickness: 2px; }
928
+
929
+ .deck-notes ul,
930
+ .deck-notes ol {
931
+ padding-left: 1.6rem;
932
+ margin: 0.6em 0;
933
+ }
934
+ .deck-notes ul li::marker { color: var(--notes-fg-dim); }
935
+
936
+ .deck-notes table {
937
+ width: 100%;
938
+ border-collapse: collapse;
939
+ margin: 1.2em 0;
940
+ font-family: var(--font-sans);
941
+ font-size: 0.95rem;
942
+ }
943
+ .deck-notes th,
944
+ .deck-notes td {
945
+ border-top: 1px solid var(--notes-rule);
946
+ border-bottom: 1px solid var(--notes-rule);
947
+ padding: 0.5rem 0.7rem;
948
+ text-align: left;
949
+ }
950
+ .deck-notes th {
951
+ background: var(--notes-blockquote-bg);
952
+ color: var(--notes-fg);
953
+ font-weight: 700;
954
+ }
955
+
956
+ .deck-notes code {
957
+ background: var(--notes-code-bg);
958
+ color: var(--notes-fg);
959
+ padding: 0.12em 0.4em;
960
+ border-radius: 4px;
961
+ font-size: 0.88em;
962
+ font-family: var(--font-mono);
963
+ }
964
+ .deck-notes pre {
965
+ background: var(--notes-pre-bg);
966
+ color: var(--notes-pre-fg);
967
+ border: 1px solid #111;
968
+ border-radius: 8px;
969
+ padding: 0.9rem 1.1rem;
970
+ overflow-x: auto;
971
+ margin: 1.2em 0;
972
+ font-size: 0.9rem;
973
+ line-height: 1.55;
974
+ text-align: left;
975
+ hyphens: manual;
976
+ font-family: var(--font-mono);
977
+ }
978
+ .deck-notes pre code {
979
+ background: transparent;
980
+ padding: 0;
981
+ border-radius: 0;
982
+ color: inherit;
983
+ }
984
+
985
+ .deck-notes blockquote {
986
+ margin: 1.4em 0;
987
+ padding: 0.9em 1.2em;
988
+ border-left: 4px solid var(--notes-accent);
989
+ background: var(--notes-blockquote-bg);
990
+ color: var(--notes-fg-soft);
991
+ font-style: normal;
992
+ border-radius: 0 6px 6px 0;
993
+ hyphens: manual;
994
+ }
995
+ .deck-notes blockquote p:first-child { margin-top: 0; }
996
+ .deck-notes blockquote p:last-child { margin-bottom: 0; }
997
+
998
+ .deck-notes hr {
999
+ border: 0;
1000
+ border-top: 1px solid var(--notes-rule);
1001
+ margin: 2em 0;
1002
+ }
1003
+
1004
+ /* Display math.
1005
+ *
1006
+ * Default to `overflow-x: auto` so very wide formulas stay readable. The
1007
+ * `notes.js` shim measures each `.katex-display` after KaTeX renders and
1008
+ * applies a `transform: scale(...)` (capped at MIN_SCALE) when the
1009
+ * equation only slightly overflows -- so the reader gets a fitted
1010
+ * formula instead of a scrollbar for the common "just a touch too wide"
1011
+ * case.
1012
+ *
1013
+ * `text-align: center` is the KaTeX default; we keep it because justified
1014
+ * text reading doesn't apply to standalone display math. */
1015
+ .deck-notes .katex-display {
1016
+ margin: 1.4em 0;
1017
+ overflow-x: auto;
1018
+ overflow-y: hidden;
1019
+ text-align: center;
1020
+ max-width: 100%;
1021
+ }
1022
+ .deck-notes .katex { font-size: 1.05em; }
1023
+ /* When notes.js has fitted the equation, lock visual flow to the scaled
1024
+ * size: no scroll, no horizontal overflow, no leftover blank band. */
1025
+ .deck-notes .katex-display.katex-fitted {
1026
+ overflow: visible;
1027
+ text-align: left;
1028
+ }
1029
+ .deck-notes .katex-display.katex-fitted > .katex {
1030
+ margin: 0;
1031
+ }
1032
+
1033
+ /* Display-equation container.
1034
+ *
1035
+ * `web/equations.py` pulls `\tag{X}` out of the math content and emits a
1036
+ * <span class="eq-tag"> sibling so the tag never overlaps the formula
1037
+ * (KaTeX's own tag is `position: absolute; right: 0` and rides inside
1038
+ * the scaled box when `notes.js` fits a wide equation).
1039
+ *
1040
+ * Grid: math column shrinks to available width (`minmax(0, 1fr)`), tag
1041
+ * stays at its natural size in the right column. */
1042
+ .deck-notes .equation {
1043
+ display: grid;
1044
+ grid-template-columns: minmax(0, 1fr) auto;
1045
+ align-items: center;
1046
+ gap: 1.5em;
1047
+ margin: 1.4em 0;
1048
+ scroll-margin-top: 4rem;
1049
+ }
1050
+ .deck-notes .equation > .math.block {
1051
+ margin: 0;
1052
+ min-width: 0;
1053
+ }
1054
+ .deck-notes .equation > .math.block .katex-display {
1055
+ margin: 0;
1056
+ }
1057
+ .deck-notes .eq-tag {
1058
+ font-family: var(--font-sans);
1059
+ font-weight: 700;
1060
+ color: var(--notes-fg-dim);
1061
+ white-space: nowrap;
1062
+ font-variant-numeric: tabular-nums;
1063
+ }
1064
+ .deck-notes .equation:target {
1065
+ outline: 2px solid var(--notes-link);
1066
+ outline-offset: 4px;
1067
+ border-radius: 4px;
1068
+ }
1069
+
1070
+ /* ------------------------------------------------------------------ */
1071
+ /* Theorem / definition / remark callouts */
1072
+ /* ------------------------------------------------------------------ */
1073
+ /*
1074
+ * Each callout type carries its own accent. Variables let us layer
1075
+ * `--callout-accent` and `--callout-tint` once and reuse them for the
1076
+ * left border, tag colour, target highlight, and tinted background.
1077
+ */
1078
+
1079
+ .callout {
1080
+ --callout-accent: var(--notes-accent);
1081
+ --callout-tint: var(--notes-blockquote-bg);
1082
+ --callout-tag-fg: var(--notes-accent);
1083
+
1084
+ display: block;
1085
+ margin: 1.6em 0;
1086
+ padding: 0.9em 1.2em;
1087
+ background: var(--callout-tint);
1088
+ border-left: 4px solid var(--callout-accent);
1089
+ border-radius: 0 6px 6px 0;
1090
+ color: var(--notes-fg);
1091
+ hyphens: manual;
1092
+ scroll-margin-top: 4rem;
1093
+ position: relative;
1094
+ }
1095
+ .callout > p:first-child { margin-top: 0; }
1096
+ .callout > p:last-child { margin-bottom: 0; }
1097
+ .callout:target {
1098
+ outline: 2px solid var(--callout-accent);
1099
+ outline-offset: 2px;
1100
+ }
1101
+
1102
+ .callout-tag {
1103
+ font-family: var(--font-sans);
1104
+ font-weight: 700;
1105
+ color: var(--callout-tag-fg);
1106
+ margin-right: 0.45em;
1107
+ }
1108
+
1109
+ /* Per-type palettes. Backgrounds are tinted versions of the accent so a
1110
+ * mid-paragraph callout reads at a glance without overwhelming the
1111
+ * Merriweather body around it. */
1112
+ .callout-theorem {
1113
+ --callout-accent: #1f4f8a;
1114
+ --callout-tint: #eaf1fa;
1115
+ --callout-tag-fg: #163f73;
1116
+ }
1117
+ .callout-lemma {
1118
+ --callout-accent: #0d7b6e;
1119
+ --callout-tint: #e3f4f1;
1120
+ --callout-tag-fg: #08594f;
1121
+ }
1122
+ .callout-proposition {
1123
+ --callout-accent: #3a4cb8;
1124
+ --callout-tint: #eaedfa;
1125
+ --callout-tag-fg: #2b3a93;
1126
+ }
1127
+ .callout-corollary {
1128
+ --callout-accent: #5b6ed1;
1129
+ --callout-tint: #eef0fb;
1130
+ --callout-tag-fg: #3f4fa8;
1131
+ }
1132
+ .callout-claim,
1133
+ .callout-fact {
1134
+ --callout-accent: #1f6a8a;
1135
+ --callout-tint: #e7f1f6;
1136
+ --callout-tag-fg: #134f6b;
1137
+ }
1138
+ .callout-definition {
1139
+ --callout-accent: #b06400;
1140
+ --callout-tint: #fbf1de;
1141
+ --callout-tag-fg: #8a4d00;
1142
+ }
1143
+ .callout-example {
1144
+ --callout-accent: #2f7f3f;
1145
+ --callout-tint: #e7f3e7;
1146
+ --callout-tag-fg: #1f5e2c;
1147
+ }
1148
+ .callout-remark,
1149
+ .callout-note,
1150
+ .callout-observation {
1151
+ --callout-accent: #757066;
1152
+ --callout-tint: #f1ede0;
1153
+ --callout-tag-fg: #4a4538;
1154
+ }
1155
+ .callout-proof {
1156
+ --callout-accent: #9d9385;
1157
+ --callout-tint: #f6f2e6;
1158
+ --callout-tag-fg: #5d564a;
1159
+ font-style: italic;
1160
+ }
1161
+ .callout-proof em { font-style: normal; }
1162
+ /* The classic "Q.E.D." marker at the close of a proof. */
1163
+ .callout-proof::after {
1164
+ content: "\220E";
1165
+ float: right;
1166
+ margin-top: -1.6em;
1167
+ color: var(--callout-accent);
1168
+ font-style: normal;
1169
+ font-size: 1.2em;
1170
+ }
1171
+
1172
+ /* `\ref{label}` cross-reference chips. Title-case label, no underline --
1173
+ * the colour alone signals the link. */
1174
+ .ref {
1175
+ color: var(--notes-link);
1176
+ text-decoration: none;
1177
+ font-weight: 600;
1178
+ }
1179
+ .ref:hover {
1180
+ background: rgba(30, 79, 138, 0.10);
1181
+ border-radius: 3px;
1182
+ }
1183
+ .ref-stale { color: #b03030; }
1184
+
1185
+ /* Article-style "drop cap" on the first paragraph after the lead H1. */
1186
+ .deck-notes > p:first-of-type::first-letter,
1187
+ .deck-notes > h1:first-of-type + p::first-letter {
1188
+ font-family: var(--font-sans);
1189
+ font-weight: 900;
1190
+ font-size: 3.3em;
1191
+ float: left;
1192
+ line-height: 0.85;
1193
+ padding: 0.05em 0.12em 0 0;
1194
+ color: var(--notes-accent);
1195
+ }
1196
+
1197
+ /* ------------------------------------------------------------------ */
1198
+ /* Slide-ref + citation inline chips */
1199
+ /* ------------------------------------------------------------------ */
1200
+
1201
+ .slide-ref {
1202
+ display: inline-flex;
1203
+ align-items: center;
1204
+ background: var(--notes-blockquote-bg);
1205
+ border: 1px solid var(--notes-accent);
1206
+ color: var(--notes-accent);
1207
+ padding: 0 0.45rem;
1208
+ border-radius: 4px;
1209
+ font-family: var(--font-sans);
1210
+ font-size: 0.85em;
1211
+ text-decoration: none;
1212
+ cursor: pointer;
1213
+ font-variant-numeric: tabular-nums;
1214
+ white-space: nowrap;
1215
+ }
1216
+ .slide-ref::before {
1217
+ content: "\25B6";
1218
+ margin-right: 0.25rem;
1219
+ font-size: 0.7em;
1220
+ }
1221
+ .slide-ref:hover {
1222
+ background: var(--notes-accent);
1223
+ color: var(--notes-bg);
1224
+ }
1225
+ .slide-ref-stale {
1226
+ border-color: #b03030;
1227
+ color: #b03030;
1228
+ cursor: not-allowed;
1229
+ }
1230
+
1231
+ .cite-group {
1232
+ font-family: var(--font-sans);
1233
+ font-size: 0.9em;
1234
+ white-space: nowrap;
1235
+ }
1236
+ .cite {
1237
+ color: var(--notes-link);
1238
+ text-decoration: none;
1239
+ font-weight: 600;
1240
+ }
1241
+ .cite:hover {
1242
+ background: rgba(30, 79, 138, 0.10);
1243
+ border-radius: 3px;
1244
+ }
1245
+ .cite-stale { color: #b03030; }
1246
+
1247
+ /* ------------------------------------------------------------------ */
1248
+ /* Bibliography */
1249
+ /* ------------------------------------------------------------------ */
1250
+
1251
+ .bibliography {
1252
+ margin-top: 3rem;
1253
+ padding-top: 1.5rem;
1254
+ border-top: 2px solid var(--notes-rule);
1255
+ font-family: var(--font-sans);
1256
+ font-size: 0.95rem;
1257
+ }
1258
+ .bibliography h2 {
1259
+ font-family: var(--font-sans);
1260
+ font-size: 1.35rem;
1261
+ margin: 0 0 0.8em 0;
1262
+ text-align: left;
1263
+ border-bottom: 0;
1264
+ padding-bottom: 0;
1265
+ }
1266
+ .bib-list {
1267
+ padding-left: 0;
1268
+ list-style: none;
1269
+ }
1270
+ .bib-entry {
1271
+ position: relative;
1272
+ padding: 0.55rem 0 0.55rem 4.5rem;
1273
+ border-bottom: 1px solid var(--notes-rule);
1274
+ text-align: left;
1275
+ hyphens: manual;
1276
+ line-height: 1.6;
1277
+ scroll-margin-top: 4rem;
1278
+ }
1279
+ .bib-entry:last-child { border-bottom: 0; }
1280
+ /* Alpha-style marker -- `[KB15]` -- rendered as an inline element from
1281
+ * Python so the printed bullet always matches the inline citation chip. */
1282
+ .bib-marker {
1283
+ position: absolute;
1284
+ left: 0;
1285
+ top: 0.55rem;
1286
+ width: 4rem;
1287
+ color: var(--notes-link);
1288
+ font-weight: 700;
1289
+ font-variant-numeric: tabular-nums;
1290
+ white-space: nowrap;
1291
+ }
1292
+ .bib-entry:target {
1293
+ background: rgba(255, 215, 0, 0.12);
1294
+ border-radius: 4px;
1295
+ }
1296
+ .bib-link {
1297
+ margin-left: 0.4em;
1298
+ color: var(--notes-link);
1299
+ text-decoration: none;
1300
+ font-size: 0.85em;
1301
+ }
1302
+ .bib-link:hover { text-decoration: underline; }
1303
+
1304
+ /* ------------------------------------------------------------------ */
1305
+ /* Tufte sidenotes */
1306
+ /* ------------------------------------------------------------------ */
1307
+ /*
1308
+ * On wide screens (>= 1280px) the .sidenote floats into the right gutter
1309
+ * reserved by `.deck-notes` padding-right. The label (number) stays inline
1310
+ * with the surrounding sentence. On narrow screens, clicking the label
1311
+ * toggles a hidden checkbox that reveals the note inline.
1312
+ */
1313
+
1314
+ .sidenote-toggle {
1315
+ display: none;
1316
+ }
1317
+
1318
+ .sidenote-ref {
1319
+ font-family: var(--font-sans);
1320
+ font-size: 0.78em;
1321
+ font-weight: 700;
1322
+ vertical-align: super;
1323
+ line-height: 1;
1324
+ color: var(--notes-accent);
1325
+ cursor: pointer;
1326
+ padding: 0 0.15em;
1327
+ border-radius: 2px;
1328
+ }
1329
+ .sidenote-ref::before { content: "["; }
1330
+ .sidenote-ref::after { content: "]"; }
1331
+ .sidenote-ref:hover { background: rgba(138, 90, 0, 0.12); }
1332
+
1333
+ .sidenote {
1334
+ display: block;
1335
+ font-family: var(--font-sans);
1336
+ font-size: 0.82rem;
1337
+ line-height: 1.5;
1338
+ text-align: left;
1339
+ hyphens: manual;
1340
+ color: var(--notes-fg-soft);
1341
+ background: var(--notes-sidenote-bg);
1342
+ border-left: 3px solid var(--notes-accent);
1343
+ padding: 0.6rem 0.85rem;
1344
+ margin: 0.8rem 0 1rem;
1345
+ border-radius: 0 4px 4px 0;
1346
+ }
1347
+
1348
+ @media (min-width: 1280px) {
1349
+ .sidenote {
1350
+ float: right;
1351
+ clear: right;
1352
+ width: 32%;
1353
+ /* Push out of the body column into the reserved padding-right gutter. */
1354
+ margin: 0.25rem 0 0.8rem clamp(0.75rem, 2vw, 1.5rem);
1355
+ margin-right: calc(-1 * clamp(2rem, 33%, 21rem));
1356
+ background: transparent;
1357
+ border-left: 1px solid var(--notes-rule);
1358
+ padding: 0 0 0 0.85rem;
1359
+ font-size: 0.78rem;
1360
+ line-height: 1.45;
1361
+ }
1362
+ }
1363
+
1364
+ /* Narrow viewport: collapse the sidenote until the user clicks the number. */
1365
+ @media (max-width: 1279px) {
1366
+ .sidenote { display: none; }
1367
+ .sidenote-toggle:checked + .sidenote { display: block; }
1368
+ .sidenote-toggle:checked + .sidenote::before {
1369
+ content: "Note: ";
1370
+ color: var(--notes-accent);
1371
+ font-weight: 700;
1372
+ }
1373
+ }
1374
+
1375
+ /* ------------------------------------------------------------------ */
1376
+ /* Facelift overrides */
1377
+ /* ------------------------------------------------------------------ */
1378
+
1379
+ .carousel-section {
1380
+ scroll-margin-top: 6rem;
1381
+ margin-bottom: 2.25rem;
1382
+ }
1383
+ .carousel-section:first-child { margin-top: 0.15rem; }
1384
+ .carousel-heading,
1385
+ .section-page-heading {
1386
+ display: flex;
1387
+ align-items: flex-end;
1388
+ justify-content: space-between;
1389
+ gap: 1rem;
1390
+ margin-bottom: 0.8rem;
1391
+ }
1392
+ .carousel-heading-line {
1393
+ display: flex;
1394
+ align-items: center;
1395
+ gap: 0;
1396
+ color: var(--canvas-text);
1397
+ }
1398
+ .carousel-heading-line svg {
1399
+ width: 1.05rem;
1400
+ height: 1.05rem;
1401
+ color: var(--site-accent);
1402
+ }
1403
+ .carousel-heading h2,
1404
+ .section-page-heading h1 {
1405
+ margin: 0;
1406
+ font-size: 1.25rem;
1407
+ line-height: 1.15;
1408
+ font-weight: 800;
1409
+ letter-spacing: 0;
1410
+ }
1411
+ .carousel-heading p,
1412
+ .section-page-heading p {
1413
+ margin: 0.35rem 0 0;
1414
+ max-width: 42rem;
1415
+ color: var(--canvas-muted);
1416
+ font-size: 0.92rem;
1417
+ }
1418
+ .carousel-section-link {
1419
+ display: inline-flex;
1420
+ align-items: center;
1421
+ gap: 0.35rem;
1422
+ color: var(--canvas-muted);
1423
+ text-decoration: none;
1424
+ font-size: 0.88rem;
1425
+ line-height: 1;
1426
+ }
1427
+ .carousel-section-link svg { width: 0.95rem; height: 0.95rem; }
1428
+ .carousel-section-link:hover { color: var(--canvas-text); }
1429
+ .carousel-shell { position: relative; }
1430
+ .carousel-track {
1431
+ gap: 0.8rem;
1432
+ padding: 0.25rem 0 1rem;
1433
+ }
1434
+ .carousel-card-wrap {
1435
+ flex: 0 0 300px;
1436
+ }
1437
+ @media (min-width: 768px) {
1438
+ .carousel-card-wrap { flex-basis: 360px; }
1439
+ }
1440
+ .section-deck-grid {
1441
+ list-style: none;
1442
+ margin: 1.2rem 0 0;
1443
+ padding: 0;
1444
+ display: grid;
1445
+ grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
1446
+ gap: 0.9rem;
1447
+ }
1448
+ .carousel-card {
1449
+ background: transparent;
1450
+ border-radius: var(--radius-card);
1451
+ box-shadow: none;
1452
+ overflow: visible;
1453
+ }
1454
+ .carousel-card::before { display: none; }
1455
+ .carousel-card:hover,
1456
+ .carousel-card:focus-visible {
1457
+ transform: translateY(-3px);
1458
+ box-shadow: none;
1459
+ }
1460
+ .carousel-thumb {
1461
+ border-radius: var(--radius-card);
1462
+ box-shadow: var(--shadow-card);
1463
+ background: #111;
1464
+ }
1465
+ .carousel-thumb img,
1466
+ .carousel-thumb-empty {
1467
+ transform: scale(1.001);
1468
+ transition: transform 240ms ease, filter 240ms ease, opacity 220ms ease;
1469
+ }
1470
+ .carousel-card:hover .carousel-thumb img,
1471
+ .carousel-card:focus-visible .carousel-thumb img,
1472
+ .carousel-card:hover .carousel-thumb-empty,
1473
+ .carousel-card:focus-visible .carousel-thumb-empty {
1474
+ transform: scale(1.055);
1475
+ }
1476
+ .carousel-thumb-empty {
1477
+ background:
1478
+ linear-gradient(135deg, rgba(16, 88, 194, 0.38), rgba(244, 200, 74, 0.28)),
1479
+ #202326;
1480
+ color: rgba(255, 255, 255, 0.78);
1481
+ font-size: 3rem;
1482
+ font-weight: 800;
1483
+ }
1484
+ .carousel-scrim {
1485
+ position: absolute;
1486
+ inset: 0;
1487
+ background:
1488
+ linear-gradient(180deg, rgba(0, 0, 0, 0.1) 0%, rgba(0, 0, 0, 0.18) 38%, rgba(0, 0, 0, 0.82) 100%),
1489
+ linear-gradient(90deg, rgba(0, 0, 0, 0.45), transparent 55%);
1490
+ z-index: 1;
1491
+ }
1492
+ .carousel-card-content {
1493
+ position: absolute;
1494
+ inset: 0;
1495
+ z-index: 2;
1496
+ display: flex;
1497
+ flex-direction: column;
1498
+ justify-content: space-between;
1499
+ padding: 0.8rem;
1500
+ color: white;
1501
+ }
1502
+ .carousel-card-top,
1503
+ .carousel-card-actions {
1504
+ display: flex;
1505
+ align-items: center;
1506
+ justify-content: space-between;
1507
+ gap: 0.5rem;
1508
+ }
1509
+ .carousel-badge,
1510
+ .carousel-created,
1511
+ .carousel-duration {
1512
+ display: inline-flex;
1513
+ align-items: center;
1514
+ gap: 0.3rem;
1515
+ min-height: 1.55rem;
1516
+ padding: 0 0.55rem;
1517
+ border-radius: 999px;
1518
+ background: rgba(0, 0, 0, 0.52);
1519
+ color: rgba(255, 255, 255, 0.88);
1520
+ font-size: 0.74rem;
1521
+ font-weight: 700;
1522
+ backdrop-filter: blur(10px);
1523
+ }
1524
+ .carousel-badge {
1525
+ background: rgba(244, 200, 74, 0.92);
1526
+ color: #151617;
1527
+ }
1528
+ .carousel-created {
1529
+ margin-left: auto;
1530
+ opacity: 0;
1531
+ transform: translateY(-4px);
1532
+ transition: opacity 170ms ease, transform 170ms ease;
1533
+ }
1534
+ .carousel-created svg,
1535
+ .carousel-play svg { width: 0.82rem; height: 0.82rem; }
1536
+ .carousel-card:hover .carousel-created,
1537
+ .carousel-card:focus-visible .carousel-created {
1538
+ opacity: 1;
1539
+ transform: translateY(0);
1540
+ }
1541
+ .carousel-card-bottom h3,
1542
+ .carousel-card-bottom h2 {
1543
+ margin: 0;
1544
+ font-size: 1.05rem;
1545
+ line-height: 1.15;
1546
+ font-weight: 800;
1547
+ letter-spacing: 0;
1548
+ text-shadow: 0 1px 10px rgba(0, 0, 0, 0.5);
1549
+ }
1550
+ .carousel-card-bottom p {
1551
+ max-height: 0;
1552
+ margin: 0;
1553
+ overflow: hidden;
1554
+ color: rgba(255, 255, 255, 0.82);
1555
+ font-size: 0.84rem;
1556
+ line-height: 1.35;
1557
+ opacity: 0;
1558
+ transition: max-height 190ms ease, margin 190ms ease, opacity 190ms ease;
1559
+ }
1560
+ .carousel-card:hover .carousel-card-bottom p,
1561
+ .carousel-card:focus-visible .carousel-card-bottom p {
1562
+ max-height: 3.8rem;
1563
+ margin-top: 0.35rem;
1564
+ opacity: 1;
1565
+ }
1566
+ .carousel-card-actions {
1567
+ margin-top: 0.65rem;
1568
+ justify-content: flex-start;
1569
+ }
1570
+ .carousel-play {
1571
+ display: inline-flex;
1572
+ align-items: center;
1573
+ gap: 0.35rem;
1574
+ min-height: 1.75rem;
1575
+ padding: 0 0.75rem;
1576
+ border-radius: 999px;
1577
+ background: #e50914;
1578
+ color: white;
1579
+ font-size: 0.78rem;
1580
+ font-weight: 800;
1581
+ box-shadow: 0 10px 22px -14px rgba(229, 9, 20, 0.9);
1582
+ }
1583
+ .carousel-arrow {
1584
+ top: calc(50% - 20px);
1585
+ width: 2.35rem;
1586
+ height: 2.35rem;
1587
+ border-radius: 999px;
1588
+ background: rgba(10, 11, 12, 0.75);
1589
+ border: 1px solid rgba(255, 255, 255, 0.18);
1590
+ box-shadow: 0 12px 26px -18px rgba(0, 0, 0, 0.8);
1591
+ }
1592
+ .carousel-arrow svg { width: 1.1rem; height: 1.1rem; }
1593
+ .carousel-arrow:hover { background: rgba(10, 11, 12, 0.95); }
1594
+ .carousel-arrow-prev { left: -0.8rem; }
1595
+ .carousel-arrow-next { right: -0.8rem; }
1596
+
1597
+ .deck-main {
1598
+ width: min(1220px, calc(100vw - clamp(2rem, 12vw, 13rem)));
1599
+ margin: 0.25rem auto 0;
1600
+ }
1601
+ .deck-grid {
1602
+ gap: 1rem;
1603
+ }
1604
+ @media (min-width: 1024px) {
1605
+ .deck-grid {
1606
+ grid-template-columns: minmax(0, 1fr) minmax(200px, 235px);
1607
+ }
1608
+ }
1609
+ .deck-viewer-frame {
1610
+ border-radius: 8px;
1611
+ background: var(--site-bg);
1612
+ box-shadow: 0 16px 45px -26px rgba(0, 0, 0, 0.9);
1613
+ }
1614
+ .deck-iframe {
1615
+ background: var(--site-bg);
1616
+ transition: filter 180ms ease;
1617
+ }
1618
+ .deck-grid.is-grayscale .deck-iframe,
1619
+ .deck-grid.is-grayscale .deck-slide-thumb img {
1620
+ filter: grayscale(1);
1621
+ }
1622
+ .deck-controls {
1623
+ justify-content: space-between;
1624
+ flex-wrap: nowrap;
1625
+ margin-top: 0.55rem;
1626
+ padding: 0;
1627
+ background: transparent;
1628
+ border: 0;
1629
+ border-radius: 0;
1630
+ }
1631
+ .deck-control-group {
1632
+ display: inline-flex;
1633
+ align-items: center;
1634
+ gap: 0.18rem;
1635
+ width: max-content;
1636
+ max-width: 100%;
1637
+ min-height: 2.5rem;
1638
+ padding: 0.25rem;
1639
+ border-radius: 8px;
1640
+ background: var(--site-control);
1641
+ box-shadow: 0 12px 24px -18px rgba(0, 0, 0, 0.8);
1642
+ }
1643
+ .deck-ctl-btn {
1644
+ width: 2.1rem;
1645
+ height: 2.1rem;
1646
+ padding: 0;
1647
+ border: 0;
1648
+ border-radius: 6px;
1649
+ color: white;
1650
+ font-size: 1rem;
1651
+ font-weight: 700;
1652
+ }
1653
+ .deck-ctl-btn svg,
1654
+ .deck-ctl-btn .icon-fallback {
1655
+ width: 1.05rem;
1656
+ height: 1.05rem;
1657
+ }
1658
+ .deck-ctl-btn:hover {
1659
+ background: rgba(255, 255, 255, 0.14);
1660
+ border-color: transparent;
1661
+ }
1662
+ .deck-ctl-play,
1663
+ .deck-ctl-play:hover {
1664
+ width: 2.1rem;
1665
+ height: 2.1rem;
1666
+ background: rgba(255, 255, 255, 0.2);
1667
+ color: white;
1668
+ }
1669
+ .deck-ctl-play .deck-ctl-icon-pause { display: none; }
1670
+ .deck-ctl-play[data-state="playing"] .deck-ctl-icon-play { display: none; }
1671
+ .deck-ctl-play[data-state="playing"] .deck-ctl-icon-pause { display: inline; }
1672
+ .deck-counter {
1673
+ min-width: 3.8rem;
1674
+ color: rgba(255, 255, 255, 0.86);
1675
+ font-size: 0.78rem;
1676
+ text-align: center;
1677
+ }
1678
+ .deck-settings {
1679
+ position: relative;
1680
+ display: inline-flex;
1681
+ }
1682
+ .deck-settings-trigger {
1683
+ display: inline-flex;
1684
+ align-items: center;
1685
+ gap: 0.45rem;
1686
+ min-height: 2.5rem;
1687
+ padding: 0 0.85rem;
1688
+ border: 0;
1689
+ border-radius: 8px;
1690
+ background: var(--site-blue);
1691
+ color: white;
1692
+ font-weight: 800;
1693
+ font-size: 0.82rem;
1694
+ cursor: pointer;
1695
+ box-shadow: 0 12px 24px -18px rgba(16, 88, 194, 0.9);
1696
+ }
1697
+ .deck-settings-trigger svg { width: 1rem; height: 1rem; }
1698
+ .deck-settings-panel {
1699
+ position: absolute;
1700
+ right: 0;
1701
+ top: calc(100% + 0.45rem);
1702
+ z-index: 50;
1703
+ width: 15rem;
1704
+ padding: 0.45rem;
1705
+ border: 1px solid var(--site-border);
1706
+ border-radius: 8px;
1707
+ background: var(--site-surface-solid);
1708
+ box-shadow: var(--shadow-card);
1709
+ }
1710
+ .deck-setting-row {
1711
+ display: flex;
1712
+ align-items: center;
1713
+ justify-content: space-between;
1714
+ gap: 0.75rem;
1715
+ padding: 0.55rem 0.6rem;
1716
+ border-radius: 6px;
1717
+ color: var(--site-text);
1718
+ font-size: 0.85rem;
1719
+ }
1720
+ .deck-setting-row:hover { background: var(--site-surface-hover); }
1721
+ .deck-setting-row span {
1722
+ display: inline-flex;
1723
+ align-items: center;
1724
+ gap: 0.45rem;
1725
+ }
1726
+ .deck-setting-row svg { width: 0.95rem; height: 0.95rem; color: var(--site-blue); }
1727
+ .deck-setting-row input {
1728
+ accent-color: var(--site-blue);
1729
+ width: 1rem;
1730
+ height: 1rem;
1731
+ }
1732
+ .deck-sidebar {
1733
+ background: transparent;
1734
+ border: 0;
1735
+ border-radius: 0;
1736
+ padding: 0;
1737
+ }
1738
+ @media (min-width: 1024px) {
1739
+ .deck-sidebar {
1740
+ max-height: calc(100vh - 6.25rem);
1741
+ top: 5rem;
1742
+ }
1743
+ }
1744
+ .deck-slide-list {
1745
+ gap: 0.65rem;
1746
+ scroll-padding: 50%;
1747
+ }
1748
+ @media (max-width: 1023px) {
1749
+ .deck-slide-list > li {
1750
+ scroll-snap-align: center;
1751
+ }
1752
+ }
1753
+ .deck-slide-card {
1754
+ background: transparent;
1755
+ border: 0;
1756
+ border-radius: 8px;
1757
+ box-shadow: var(--shadow-card);
1758
+ }
1759
+ .deck-slide-card:hover {
1760
+ background: transparent;
1761
+ border-color: transparent;
1762
+ transform: translateY(-1px);
1763
+ }
1764
+ .deck-slide-card[aria-current="true"] {
1765
+ border-color: transparent;
1766
+ box-shadow: var(--shadow-card);
1767
+ }
1768
+ .deck-slide-thumb {
1769
+ border-radius: 8px;
1770
+ background: var(--site-elevated);
1771
+ }
1772
+ .deck-slide-thumb::after {
1773
+ content: "";
1774
+ position: absolute;
1775
+ inset: 0;
1776
+ border: 2px solid transparent;
1777
+ border-radius: 8px;
1778
+ pointer-events: none;
1779
+ }
1780
+ .deck-slide-card[aria-current="true"] .deck-slide-thumb::after {
1781
+ border-color: var(--site-accent);
1782
+ }
1783
+ .deck-slide-overlay {
1784
+ position: absolute;
1785
+ inset: auto 0 0;
1786
+ display: flex;
1787
+ align-items: center;
1788
+ justify-content: space-between;
1789
+ gap: 0.45rem;
1790
+ padding: 0.65rem;
1791
+ background: linear-gradient(180deg, transparent, rgba(0, 0, 0, 0.82));
1792
+ color: white;
1793
+ }
1794
+ .deck-slide-title {
1795
+ color: white;
1796
+ font-size: 0.9rem;
1797
+ font-weight: 500;
1798
+ line-height: 1.2;
1799
+ flex: 1 1 auto;
1800
+ min-width: 0;
1801
+ overflow: hidden;
1802
+ text-overflow: ellipsis;
1803
+ white-space: nowrap;
1804
+ }
1805
+ .deck-slide-duration {
1806
+ color: rgba(255, 255, 255, 0.72);
1807
+ font-size: 0.76rem;
1808
+ font-weight: 500;
1809
+ font-variant-numeric: tabular-nums;
1810
+ flex: 0 0 auto;
1811
+ white-space: nowrap;
1812
+ }
1813
+ @media (max-width: 760px) {
1814
+ .deck-main { width: calc(100vw - 1rem); }
1815
+ .deck-grid { gap: 0.65rem; }
1816
+ .deck-controls {
1817
+ align-items: center;
1818
+ gap: 0.35rem;
1819
+ }
1820
+ .deck-control-group {
1821
+ flex: 0 1 auto;
1822
+ min-width: 0;
1823
+ padding: 0.22rem;
1824
+ }
1825
+ .deck-ctl-btn,
1826
+ .deck-ctl-play,
1827
+ .deck-ctl-play:hover {
1828
+ width: 1.9rem;
1829
+ height: 1.9rem;
1830
+ }
1831
+ .deck-counter {
1832
+ min-width: 3.1rem;
1833
+ padding: 0 0.25rem;
1834
+ font-size: 0.72rem;
1835
+ }
1836
+ .deck-settings {
1837
+ flex: 0 0 auto;
1838
+ }
1839
+ .deck-settings-trigger {
1840
+ width: 2.35rem;
1841
+ min-height: 2.35rem;
1842
+ justify-content: center;
1843
+ padding: 0;
1844
+ }
1845
+ .deck-settings-trigger > span:last-child {
1846
+ display: none;
1847
+ }
1848
+ .deck-settings-panel {
1849
+ left: auto;
1850
+ right: 0;
1851
+ width: min(15rem, calc(100vw - 1rem));
1852
+ }
1853
+ .deck-slide-list {
1854
+ gap: 0.5rem;
1855
+ padding-bottom: 0.15rem;
1856
+ }
1857
+ .deck-slide-list > li {
1858
+ flex-basis: 168px;
1859
+ }
1860
+ }
1861
+
1862
+ /* ------------------------------------------------------------------ */
1863
+ /* Reduced motion */
1864
+ /* ------------------------------------------------------------------ */
1865
+
1866
+ @media (prefers-reduced-motion: reduce) {
1867
+ *, *::before, *::after { transition: none !important; animation: none !important; }
1868
+ .carousel-track { scroll-behavior: auto; }
1869
+ .carousel-card:hover { transform: none; }
1870
+ }