jekyll-slides 0.1.0 → 0.3.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +14 -1
- data/README.md +80 -4
- data/assets/css/presentation.css +1 -1
- data/doc/CHANGELOG.md +14 -1
- data/doc/Jekyll/Slides/Deck.md +40 -0
- data/doc/Jekyll/Slides/DeckAssembler.md +17 -0
- data/doc/Jekyll/Slides/FrontMatter.md +16 -0
- data/doc/Jekyll/Slides/JekyllIntegration.md +0 -3
- data/doc/Jekyll/Slides/SlideFile.md +18 -0
- data/doc/Jekyll/Slides/SlideMetadata.md +6 -0
- data/doc/Jekyll/Slides/Support.md +6 -0
- data/doc/Jekyll/Slides.md +15 -4
- data/doc/Jekyll.md +1 -1
- data/doc/README.md +80 -4
- data/doc/index.csv +19 -1
- data/lib/jekyll/slides/component_renderer.rb +33 -5
- data/lib/jekyll/slides/deck.rb +151 -0
- data/lib/jekyll/slides/deck_assembler.rb +147 -0
- data/lib/jekyll/slides/front_matter.rb +39 -0
- data/lib/jekyll/slides/jekyll_integration.rb +3 -3
- data/lib/jekyll/slides/renderer.rb +14 -0
- data/lib/jekyll/slides/slide_file.rb +55 -0
- data/lib/jekyll/slides/slide_metadata.rb +26 -18
- data/lib/jekyll/slides/support.rb +14 -0
- data/lib/jekyll/slides/version.rb +1 -1
- data/lib/jekyll/slides.rb +14 -2
- data/{llm.txt → llms.txt} +15 -4
- metadata +10 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: a92cf3ca8f9bd4ae944f5059db0bb304736b2771a872ab4d5d79a79303512361
|
|
4
|
+
data.tar.gz: b673bdfebebcdb512f823b2086be1844db79acc98f45ad3a8414f1319515be1a
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 614fd49ac985bcf2c5d37f89dc3f396825ca2a308847dc0eb44706087d04d45acf60a24eb5cec3e527d5fa60fdcc45c6c078d818f5257a0cb5debc9a15189128
|
|
7
|
+
data.tar.gz: 845bb91e87fb783a0a467b9d7329f4c9f7d226e0d273c308170df806e9db47e491b19da6c0b3adfe0f217ed124e7f579f1b318d2bd2d1f0c1baa926522af9ff4
|
data/CHANGELOG.md
CHANGED
|
@@ -2,8 +2,21 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to Jekyll Slides are documented here.
|
|
4
4
|
|
|
5
|
-
##
|
|
5
|
+
## 0.3.0 — 2026-09-10
|
|
6
6
|
|
|
7
|
+
- Add the four Catppuccin flavors as presentation themes: `catppuccin-latte`, `catppuccin-frappe`, `catppuccin-macchiato`, and `catppuccin-mocha`, ported from the palette shared by [catppuccin/ghostty](https://github.com/catppuccin/ghostty). Hues are the published values; lightness is adjusted only where a token cannot otherwise clear the 4.5:1 contrast checked on every code surface.
|
|
8
|
+
- Add a `theme` attribute to editor and terminal blocks, so one window can carry any theme while the deck around it keeps its own. The override repaints that window's surface, title bar, syntax colors, prompt, and body text. An unknown name warns and falls back to the deck theme.
|
|
9
|
+
- Give terminal windows a real title bar. It was previously an empty `::before` bar that could hold neither the window controls nor the title, which floated above it.
|
|
10
|
+
- Center editor and terminal titles inside the title bar, and size the controls and bar with the component `size`.
|
|
11
|
+
- Use the macOS traffic-light colors for the window controls in every theme, the way a real title bar does; only the window surface follows the theme. Themes no longer set `--slide-dot-close`, `--slide-dot-minimize`, or `--slide-dot-maximize`.
|
|
12
|
+
- Rename the generated LLM index from `llm.txt` to `llms.txt`, matching the llmstxt.org convention used across these plugins.
|
|
13
|
+
|
|
14
|
+
## 0.2.0 — 2026-09-06
|
|
15
|
+
|
|
16
|
+
- Add folder decks: author a presentation as one Markdown file per slide, ordered by a numeric filename prefix and alphabetically otherwise, opted into with `slides:` in the entry file's front matter.
|
|
17
|
+
- Add slide file front matter (`layout`, `background`, `class`) as an alternative to the `<!-- ... -->` metadata comment.
|
|
18
|
+
- Fix slides rendering upside down in Safari: the CSS length-division trick used to scale slides to the viewport made Safari compute a negative scale factor, which is a 180 degree rotation.
|
|
19
|
+
- Fix `slides_count` for decks whose slides are generated by Liquid, which previously reported the pre-Liquid slide count.
|
|
7
20
|
- Add `bin/prepare_release` to verify the gem, regenerate Markdown API documentation and `llm.txt`, and build a versioned package with a SHA-256 checksum.
|
|
8
21
|
- Ship generated documentation while keeping YARD and release tools development-only.
|
|
9
22
|
|
data/README.md
CHANGED
|
@@ -59,6 +59,62 @@ class: keynote
|
|
|
59
59
|
-->
|
|
60
60
|
```
|
|
61
61
|
|
|
62
|
+
## Deck folders
|
|
63
|
+
|
|
64
|
+
A deck can also be a folder of Markdown files, one file per slide, instead of one file with `---` separators:
|
|
65
|
+
|
|
66
|
+
```
|
|
67
|
+
talks/my-talk/
|
|
68
|
+
index.md # deck front matter, opts in with `slides: true`
|
|
69
|
+
01-title.md
|
|
70
|
+
02-the-idea.md
|
|
71
|
+
03-code.md
|
|
72
|
+
diagram.png # ordinary static file, untouched
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
The entry file must be named `index.md` and carry the deck's front matter, `layout: presentation`, and `slides: true`:
|
|
76
|
+
|
|
77
|
+
```yaml
|
|
78
|
+
# talks/my-talk/index.md
|
|
79
|
+
---
|
|
80
|
+
layout: presentation
|
|
81
|
+
title: My talk
|
|
82
|
+
slides: true
|
|
83
|
+
---
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
`slides: true` discovers every other Markdown file that is a direct child of the folder (not recursive), skipping names starting with `_` or `.`, and skipping anything Jekyll itself withholds: a file dropped by the site's `exclude:` setting, or one whose front matter sets `published: false`. Naming a withheld file in an explicit list warns and skips it too, so a deck never publishes content the site holds back. Files are ordered by a natural sort of the filename: digit runs compare numerically and sort before letters, so `01-title.md`, `02-the-idea.md`, `10-outro.md`, then any file with no numeric prefix, sorted alphabetically. Each file holds one slide, or several separated by `---`, exactly as in a single-file deck. Body content in `index.md`, if any, becomes the deck's leading slides.
|
|
87
|
+
|
|
88
|
+
A slide file can carry its own YAML front matter with `layout`, `background`, and `class`, as an alternative to the `<!-- ... -->` comment:
|
|
89
|
+
|
|
90
|
+
```markdown
|
|
91
|
+
---
|
|
92
|
+
layout: statement
|
|
93
|
+
background: spotlight
|
|
94
|
+
---
|
|
95
|
+
# A bold claim
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
Front matter in the file applies to every slide it holds; a slide's own comment overrides it key by key.
|
|
99
|
+
|
|
100
|
+
Set `slides:` to a list instead of `true` to turn the entry file into a readable running order, in presentation order:
|
|
101
|
+
|
|
102
|
+
```yaml
|
|
103
|
+
---
|
|
104
|
+
layout: presentation
|
|
105
|
+
title: My talk
|
|
106
|
+
slides:
|
|
107
|
+
- 01-title.md
|
|
108
|
+
- 02-the-idea.md
|
|
109
|
+
# - 03-detour.md
|
|
110
|
+
- 04-code.md
|
|
111
|
+
---
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
Cutting a slide for a shorter time slot is commenting out one line, not moving a file out of the folder.
|
|
115
|
+
|
|
116
|
+
`slides:` is what opts a folder in. Opting in absorbs the whole folder: every Markdown file it absorbs is removed from the site's pages, collection documents, and static files, so none of them is ever published on its own. This holds even for a file commented out of an explicit list; the list controls order and inclusion in the deck, not what gets absorbed. Without `slides:`, a folder holding an `index.md` presentation behaves exactly as it does today, and sibling files are left alone. This matters if the site applies `layout: presentation` through a broad `defaults:` rule, since that alone never triggers absorption.
|
|
117
|
+
|
|
62
118
|
## Editors and terminals
|
|
63
119
|
|
|
64
120
|
Put a kramdown inline attribute list immediately after a fenced block. Attribute values must be quoted; class and ID tokens such as `.editor` and `#order-total` do not need quotes. `.editor` renders a syntax-highlighted editor window; `.terminal` renders a terminal window.
|
|
@@ -80,7 +136,7 @@ ruby 3.4.1
|
|
|
80
136
|
{: .terminal #ruby-version title="terminal" size="sm"}
|
|
81
137
|
````
|
|
82
138
|
|
|
83
|
-
Editor/terminal attributes are `title`, `id` (or `#id`), `size` (`sm`, `md`, `lg`), `line_numbers` (`true`/`false`), `focus`, and `highlight`. Ranges accept comma-separated lines and ranges such as `2,4-6,9`; invalid values fall back safely with a Jekyll warning. Terminal prompts beginning with `$ `, `> `, or `❯ ` are styled separately. Source remains server-rendered and copyable.
|
|
139
|
+
Editor/terminal attributes are `title`, `id` (or `#id`), `size` (`sm`, `md`, `lg`), `theme`, `line_numbers` (`true`/`false`), `focus`, and `highlight`. Ranges accept comma-separated lines and ranges such as `2,4-6,9`; invalid values fall back safely with a Jekyll warning. Terminal prompts beginning with `$ `, `> `, or `❯ ` are styled separately. Source remains server-rendered and copyable.
|
|
84
140
|
|
|
85
141
|
Long editor and terminal blocks scroll within the slide. Blocks over 20 lines produce an advisory build warning; the amount that fits depends on the layout and font size. Split long examples across slides for print, where scrolling is unavailable.
|
|
86
142
|
|
|
@@ -90,7 +146,7 @@ Code remains selectable and copyable with normal browser controls; version 0.1 d
|
|
|
90
146
|
|
|
91
147
|
## Themes and configuration
|
|
92
148
|
|
|
93
|
-
Presentation themes are `minimal-light`, `minimal-dark`, `midnight` (the default), and `
|
|
149
|
+
Presentation themes are `minimal-light`, `minimal-dark`, `midnight` (the default), `ruby`, and the four Catppuccin flavors `catppuccin-latte`, `catppuccin-frappe`, `catppuccin-macchiato`, and `catppuccin-mocha`. These style the slides without replacing the site's Jekyll theme. Configure defaults under `slides:`:
|
|
94
150
|
|
|
95
151
|
```yaml
|
|
96
152
|
slides:
|
|
@@ -106,11 +162,31 @@ The same keys can be overridden per presentation in front matter (`theme`, `aspe
|
|
|
106
162
|
|
|
107
163
|
For a light presentation, set `slides: { theme: minimal-light }` in `_config.yml`, or `theme: minimal-light` in the deck's front matter. The [readability example](https://github.com/lucianghinda/jekyll-slides/blob/main/examples/readability.md) demonstrates the light theme with code, terminal output, tables, and prose.
|
|
108
164
|
|
|
165
|
+
### Terminal themes
|
|
166
|
+
|
|
167
|
+
The Catppuccin flavors are ported from the palette shared by [catppuccin/ghostty](https://github.com/catppuccin/ghostty). Hues are the published values; lightness is adjusted only where a token cannot otherwise clear the 4.5:1 contrast the project checks on every code surface. Latte, the light flavor, needed the most adjustment.
|
|
168
|
+
|
|
169
|
+
Any theme also works on a single editor or terminal block through a `theme` attribute, so one window can carry a different palette from the deck around it:
|
|
170
|
+
|
|
171
|
+
````markdown
|
|
172
|
+
```console
|
|
173
|
+
$ ghostty --version
|
|
174
|
+
ghostty 1.0.1
|
|
175
|
+
```
|
|
176
|
+
{: .terminal title="ghostty" theme="catppuccin-latte"}
|
|
177
|
+
````
|
|
178
|
+
|
|
179
|
+
The override repaints that window completely: surface, title bar, syntax colors, prompt, and body text. Everything outside it keeps the deck theme. An unknown name warns during the build and falls back to the deck theme. The [terminal themes example](https://github.com/lucianghinda/jekyll-slides/blob/main/examples/terminal-themes.md) shows a deck-wide flavor next to per-window overrides.
|
|
180
|
+
|
|
181
|
+
### Window chrome
|
|
182
|
+
|
|
183
|
+
Editors and terminals render the same macOS-style title bar: traffic lights on the left, the `title` centered in the bar, and for editors the language on the right. The traffic lights keep the macOS red, amber, and green in every theme, the way a real title bar does; only the window surface follows the theme. Bar height, control size, and spacing scale with the component `size`.
|
|
184
|
+
|
|
109
185
|
## Typography and readability
|
|
110
186
|
|
|
111
187
|
The gem bundles Atkinson Hyperlegible Next for text and Atkinson Hyperlegible Mono for code, including variable upright and italic faces. Fonts load from the site's own assets and work offline. The font files retain their SIL Open Font License; source revisions, checksums, and notices are in [assets/fonts](https://github.com/lucianghinda/jekyll-slides/blob/main/assets/fonts/README.md).
|
|
112
188
|
|
|
113
|
-
On the 1920×1080 slide canvas, body text is 44px, section headings are 72px, and code sizes `sm`, `md`, and `lg` are 32px, 38px, and 42px. These sizes scale with the slide. Filenames and line numbers remain readable, and focused lines use borders and background color while keeping surrounding code fully visible. All
|
|
189
|
+
On the 1920×1080 slide canvas, body text is 44px, section headings are 72px, and code sizes `sm`, `md`, and `lg` are 32px, 38px, and 42px. These sizes scale with the slide. Filenames and line numbers remain readable, and focused lines use borders and background color while keeping surrounding code fully visible. All eight themes check syntax-token contrast against normal, highlighted, and focused code surfaces, both deck-wide and as a single-window override.
|
|
114
190
|
|
|
115
191
|
Prefer medium or large code and short examples for projection. Long blocks can scroll, but an audience cannot reveal hidden lines independently; split examples when presenting or printing. Screen contrast tests do not replace checking the actual projector and viewing distance.
|
|
116
192
|
|
|
@@ -151,7 +227,7 @@ bundle exec rake docs
|
|
|
151
227
|
```
|
|
152
228
|
|
|
153
229
|
This replaces `doc/` with fresh YARD Markdown, updates the documentation index in
|
|
154
|
-
`doc/Jekyll/Slides.md`, and writes `
|
|
230
|
+
`doc/Jekyll/Slides.md`, and writes `llms.txt` with links relative to the gem root.
|
|
155
231
|
The generated files are checked in and shipped with the gem. Internal plans,
|
|
156
232
|
temporary files, and Node dependencies are excluded. YARD and `yard-markdown`
|
|
157
233
|
are development tools only.
|
data/assets/css/presentation.css
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */
|
|
2
|
-
@layer theme{:root,:host{--font-sans:-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", "Noto Sans", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";--font-mono:ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;--default-font-family:var(--font-sans);--default-mono-font-family:var(--font-mono);--font-slide-sans:"Atkinson Hyperlegible Next", "Avenir Next", "Segoe UI Variable", "Segoe UI", system-ui, sans-serif;--font-slide-mono:"Atkinson Hyperlegible Mono", "JetBrains Mono", "SFMono-Regular", Consolas, monospace;--slide-canvas-width:1920px;--slide-canvas-height:1080px;--slide-radius:28px}}@layer base{*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;tab-size:4;line-height:1.5;font-family:var(--default-font-family,-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", "Noto Sans", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji");font-feature-settings:var(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--default-mono-font-family,ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-variation-settings:var(--default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring:where(:not(iframe)){outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::placeholder{opacity:1}@supports (not ((-webkit-appearance:-apple-pay-button))) or (contain-intrinsic-size:1px){::placeholder{color:currentColor}@supports (color:color-mix(in lab, red, red)){::placeholder{color:color-mix(in oklab, currentcolor 50%, transparent)}}}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit{padding-block:0}::-webkit-datetime-edit-year-field{padding-block:0}::-webkit-datetime-edit-month-field{padding-block:0}::-webkit-datetime-edit-day-field{padding-block:0}::-webkit-datetime-edit-hour-field{padding-block:0}::-webkit-datetime-edit-minute-field{padding-block:0}::-webkit-datetime-edit-second-field{padding-block:0}::-webkit-datetime-edit-millisecond-field{padding-block:0}::-webkit-datetime-edit-meridiem-field{padding-block:0}::-webkit-calendar-picker-indicator{line-height:1}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]){appearance:button}::file-selector-button{appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}}@layer components;@layer utilities{.visible{visibility:visible}.block{display:block}.grid{display:grid}.hidden{display:none}}@font-face{font-family:Atkinson Hyperlegible Next;font-style:normal;font-weight:200 800;font-display:swap;src:url(../fonts/atkinson-hyperlegible-next.woff2)format("woff2")}@font-face{font-family:Atkinson Hyperlegible Next;font-style:italic;font-weight:200 800;font-display:swap;src:url(../fonts/atkinson-hyperlegible-next-italic.woff2)format("woff2")}@font-face{font-family:Atkinson Hyperlegible Mono;font-style:normal;font-weight:200 800;font-display:swap;src:url(../fonts/atkinson-hyperlegible-mono.woff2)format("woff2")}@font-face{font-family:Atkinson Hyperlegible Mono;font-style:italic;font-weight:200 800;font-display:swap;src:url(../fonts/atkinson-hyperlegible-mono-italic.woff2)format("woff2")}:root,[data-theme=midnight]{--slide-bg:#10141d;--slide-fg:#f3f5f8;--slide-muted:#b4bdca;--slide-accent:#ff6b4a;--slide-accent-strong:#ff8a65;--slide-code-surface:#151b26;--slide-code-header:#1c2532;--slide-code-border:#364354;--slide-code-shadow:#0000006b;--slide-syntax-comment:#aab5c5;--slide-syntax-keyword:#ff9e7a;--slide-syntax-string:#b8d98e;--slide-syntax-number:#c6a9ff;--slide-syntax-function:#75c9db;--slide-syntax-operator:#f3f5f8;--slide-syntax-punctuation:#b9c4d2;--slide-syntax-name:#f3f5f8;--slide-syntax-variable:#f3f5f8;--slide-syntax-symbol:#75c9db;--slide-syntax-builtin:#75c9db;--slide-syntax-constant:#c6a9ff;--slide-syntax-error:#ff8675;--slide-highlight:#ff6b4a2b;--slide-focus:#ff9e7a;--slide-selection:#ff6b4a47;--slide-grid-line:#ffffff0e;--slide-spotlight:#ff6b4a26;--slide-gradient-start:#191d2c;--slide-gradient-end:#10141d;--slide-link:#9edbea;--slide-quote:#c8d1dc;--slide-dot-close:#ef806d;--slide-dot-minimize:#e6b566;--slide-dot-maximize:#87c899;--slide-heading-font-size:72px;--slide-title-font-size:108px;--slide-body-font-size:44px;--slide-statement-font-size:88px;--slide-code-font-size:38px;--slide-code-highlight-surface:#ff6b4a1a;--slide-code-highlight-border:#ff6b4a;--slide-code-focus-surface:#ff9e7a1a;--slide-code-inset:#ffffff0f;--slide-surface-shine:#ffffff0f}[data-theme=minimal-light]{--slide-bg:#f4f1eb;--slide-fg:#1c2027;--slide-muted:#4d5660;--slide-accent:#bc3e27;--slide-accent-strong:#8d2919;--slide-code-surface:#e9e6df;--slide-code-header:#dedbd4;--slide-code-border:#c8c4bb;--slide-code-shadow:#302c242e;--slide-syntax-comment:#50564f;--slide-syntax-keyword:#9d3e28;--slide-syntax-string:#325c35;--slide-syntax-number:#6b4ca0;--slide-syntax-function:#12586a;--slide-syntax-operator:#343b45;--slide-syntax-punctuation:#4d5863;--slide-syntax-name:#1c2027;--slide-syntax-variable:#1c2027;--slide-syntax-symbol:#12586a;--slide-syntax-builtin:#12586a;--slide-syntax-constant:#6b4ca0;--slide-syntax-error:#a52121;--slide-highlight:#bc3e2721;--slide-focus:#9d3e28;--slide-selection:#bc3e2733;--slide-grid-line:#1c202714;--slide-spotlight:#bc3e271f;--slide-gradient-start:#fffdf8;--slide-gradient-end:#e9e5dc;--slide-link:#176d82;--slide-quote:#424a54;--slide-dot-close:#cf6753;--slide-dot-minimize:#c09243;--slide-dot-maximize:#579966;--slide-heading-font-size:72px;--slide-title-font-size:96px;--slide-body-font-size:44px;--slide-statement-font-size:88px;--slide-code-font-size:38px;--slide-code-highlight-surface:#bc3e2712;--slide-code-highlight-border:#bc3e27;--slide-code-focus-surface:#9d3e2812;--slide-code-inset:#1c202714;--slide-surface-shine:#ffffff0f}[data-theme=minimal-dark]{--slide-bg:#171717;--slide-fg:#f4f1ea;--slide-muted:#bcb8b0;--slide-accent:#e6b566;--slide-accent-strong:#f2c57a;--slide-code-surface:#202020;--slide-code-header:#2b2b2a;--slide-code-border:#454441;--slide-code-shadow:#00000080;--slide-syntax-comment:#b2afa9;--slide-syntax-keyword:#f0bd75;--slide-syntax-string:#b8d094;--slide-syntax-number:#d1a9e8;--slide-syntax-function:#83ced1;--slide-syntax-operator:#f4f1ea;--slide-syntax-punctuation:#c5c1b9;--slide-syntax-name:#f4f1ea;--slide-syntax-variable:#f4f1ea;--slide-syntax-symbol:#83ced1;--slide-syntax-builtin:#83ced1;--slide-syntax-constant:#d1a9e8;--slide-syntax-error:#f28272;--slide-highlight:#e6b56629;--slide-focus:#f0bd75;--slide-selection:#e6b56640;--slide-grid-line:#ffffff0f;--slide-spotlight:#e6b56621;--slide-gradient-start:#25221e;--slide-gradient-end:#171717;--slide-link:#83ced1;--slide-quote:#d3cec4;--slide-dot-close:#d97762;--slide-dot-minimize:#d4a052;--slide-dot-maximize:#70ad7e;--slide-heading-font-size:72px;--slide-title-font-size:108px;--slide-body-font-size:44px;--slide-statement-font-size:88px;--slide-code-font-size:38px;--slide-code-highlight-surface:#e6b5661a;--slide-code-highlight-border:#e6b566;--slide-code-focus-surface:#f0bd751a;--slide-code-inset:#ffffff0f;--slide-surface-shine:#ffffff0f}[data-theme=ruby]{--slide-bg:#210f18;--slide-fg:#fff4ed;--slide-muted:#dfbcc3;--slide-accent:#ff7a68;--slide-accent-strong:#ffb09a;--slide-code-surface:#2a1520;--slide-code-header:#3a1c2a;--slide-code-border:#613348;--slide-code-shadow:#0a020780;--slide-syntax-comment:#cba8b0;--slide-syntax-keyword:#ff9f80;--slide-syntax-string:#c6e19c;--slide-syntax-number:#d9afff;--slide-syntax-function:#8ed9e0;--slide-syntax-operator:#fff4ed;--slide-syntax-punctuation:#e0bdc3;--slide-syntax-name:#fff4ed;--slide-syntax-variable:#fff4ed;--slide-syntax-symbol:#8ed9e0;--slide-syntax-builtin:#8ed9e0;--slide-syntax-constant:#d9afff;--slide-syntax-error:#ff8176;--slide-highlight:#ff7a682e;--slide-focus:#ffb09a;--slide-selection:#ff7a6847;--slide-grid-line:#ffe5dc11;--slide-spotlight:#ff7a6829;--slide-gradient-start:#3a1828;--slide-gradient-end:#210f18;--slide-link:#8ed9e0;--slide-quote:#f1c7c9;--slide-dot-close:#f07769;--slide-dot-minimize:#dca25a;--slide-dot-maximize:#71b587;--slide-heading-font-size:72px;--slide-title-font-size:108px;--slide-body-font-size:44px;--slide-statement-font-size:88px;--slide-code-font-size:38px;--slide-code-highlight-surface:#ff7a681a;--slide-code-highlight-border:#ff7a68;--slide-code-focus-surface:#ffb09a1a;--slide-code-inset:#ffffff0f;--slide-surface-shine:#ffffff0f}*{box-sizing:border-box}::selection{background:var(--slide-selection);color:var(--slide-fg)}html,body{min-height:100%;margin:0}body{background:var(--slide-bg);color:var(--slide-fg);font-family:var(--font-slide-sans);font-synthesis:none;text-rendering:optimizelegibility;font-weight:400}.presentation-root{background:var(--slide-bg);min-height:100dvh;color:var(--slide-fg)}.presentation-root:not(.js) .slide-deck{flex-direction:column;align-items:center;gap:2rem;width:100%;height:auto;min-height:0;padding:2rem;display:flex;overflow:visible}.presentation-root:not(.js) .slide{width:min(100%, var(--slide-canvas-width));aspect-ratio:16/9;height:auto;position:relative;overflow:visible}.presentation-root:not(.js) .slide-content{height:auto;min-height:0}.presentation-root.js .slide-deck{flex-direction:column;align-items:center;gap:2rem;width:100%;height:auto;min-height:0;padding:2rem;display:flex;overflow:visible}.presentation-root.js .slide{width:min(100%, var(--slide-canvas-width));aspect-ratio:16/9;height:auto;position:relative;overflow:visible}.presentation-root.js .slide-content{height:auto;min-height:0}.slide-deck{isolation:isolate;width:100vw;height:100dvh;min-height:0;position:relative;container-type:size}.slide{width:var(--slide-canvas-width);height:var(--slide-canvas-height);aspect-ratio:16/9;color:var(--slide-fg);background:var(--slide-bg);position:relative;overflow:hidden}@supports (width:1cqw) and (height:1cqh) and (transform:scale(tan(atan2(1px, 1px)))){.presentation-root.js{width:100vw;height:100dvh;min-height:0;overflow:hidden}.presentation-root.js .slide-deck{place-items:center;gap:0;width:100%;height:100%;min-height:0;padding:0;display:grid;overflow:hidden;container-type:size}.presentation-root.js .slide{--slide-scale:min(tan(atan2(100cqw, 1920px)), tan(atan2(100cqh, 1080px)));width:var(--slide-canvas-width);height:var(--slide-canvas-height);transform:translate(-50%, -50%) scale(var(--slide-scale,1));transform-origin:50%;margin:0;position:absolute;inset:50% auto auto 50%;overflow:hidden}.presentation-root.js .slide-content{height:100%}.presentation-root.js:not(.is-overview) .slide:not(.is-active),.presentation-root.js[data-overview-active=false] .slide:not(.is-active){visibility:hidden;pointer-events:none}}.slide-content{z-index:1;flex-direction:column;width:100%;height:100%;padding:108px 132px 100px;display:flex;position:relative}:where(.prose,.layout-split-code .pane){max-width:100%;font-size:var(--slide-body-font-size);letter-spacing:0;line-height:1.4}:where(.prose,.layout-split-code .pane) :where(h1,h2,h3,h4){letter-spacing:-.012em;text-wrap:balance;max-width:16ch;margin:0 0 32px;line-height:1.12}:where(.prose,.layout-split-code .pane) :where(h1,h2){font-size:var(--slide-heading-font-size);font-weight:600}:where(.prose,.layout-split-code .pane) h3{font-size:56px;font-weight:600}:where(.prose,.layout-split-code .pane) h4{font-size:44px;font-weight:600}:where(.prose,.layout-split-code .pane) p{max-width:40ch;margin:0 0 28px}:where(.prose,.layout-split-code .pane) strong{color:var(--slide-accent-strong);font-weight:700}:where(.prose,.layout-split-code .pane) em{color:var(--slide-quote)}:where(.prose,.layout-split-code .pane) a{color:var(--slide-link);text-underline-offset:6px;text-decoration:underline;text-decoration-thickness:3px}:where(.prose,.layout-split-code .pane) :where(ul,ol){max-width:34ch;margin:0 0 28px;padding-inline-start:1.25em}:where(.prose,.layout-split-code .pane) ul{list-style-type:disc}:where(.prose,.layout-split-code .pane) ol{list-style-type:decimal}:where(.prose,.layout-split-code .pane) ul ul{list-style-type:circle}:where(.prose,.layout-split-code .pane) ol ol{list-style-type:lower-alpha}:where(.prose,.layout-split-code .pane) li{margin-block:.25em;padding-inline-start:.2em}:where(.prose,.layout-split-code .pane) li::marker{color:var(--slide-accent)}:where(.prose,.layout-split-code .pane) code:not(pre code){border:1px solid var(--slide-code-border);background:var(--slide-code-surface);color:var(--slide-accent-strong);font-family:var(--font-slide-mono);font-variant-ligatures:none;border-radius:8px;padding:.12em .28em;font-size:.95em}:where(.prose,.layout-split-code .pane) blockquote{border-inline-start:6px solid var(--slide-accent);max-width:34ch;color:var(--slide-quote);margin:0 0 28px;padding:12px 28px;font-style:italic}:where(.prose,.layout-split-code .pane) img{object-fit:contain;border-radius:20px;max-width:100%;max-height:520px;display:block}:where(.prose,.layout-split-code .pane) table{border-collapse:collapse;margin-block:16px 28px;font-size:1em}:where(.prose,.layout-split-code .pane) th,:where(.prose,.layout-split-code .pane) td{border-bottom:2px solid var(--slide-code-border);text-align:start;padding:12px 20px}:where(.prose,.layout-split-code .pane) th{color:var(--slide-accent-strong);font-weight:700}.visually-hidden{clip:rect(0 0 0 0);white-space:nowrap;border:0;width:1px;height:1px;margin:-1px;padding:0;position:absolute;overflow:hidden}.slide{isolation:isolate}.slide:before,.slide:after{content:none;pointer-events:none;position:absolute}.slide:before{z-index:0;background:var(--slide-bg);inset:0}.bg-plain:before{content:"";background:var(--slide-bg)}.bg-gradient:before{content:"";background:linear-gradient(135deg, var(--slide-gradient-start), var(--slide-gradient-end) 64%)}.bg-grid:before{content:"";background-color:var(--slide-bg);background-image:linear-gradient(var(--slide-grid-line) 1px, transparent 1px), linear-gradient(90deg, var(--slide-grid-line) 1px, transparent 1px);background-size:72px 72px}.bg-spotlight:before{content:"";background:radial-gradient(circle at 70% 18%, var(--slide-spotlight), transparent 42%), var(--slide-bg)}.bg-gradient:after,.bg-grid:after,.bg-spotlight:after{content:"";z-index:0;background:var(--slide-spotlight);filter:blur(90px);opacity:.5;border-radius:50%;width:70%;height:70%;top:-28%;right:-12%}.layout-title .slide-content{justify-content:center;padding-inline:180px}.layout-title .prose h1{max-width:12ch;font-size:var(--slide-title-font-size)}.layout-title .prose p{max-width:28ch;color:var(--slide-muted)}.layout-statement .slide-content{justify-content:center;padding-inline:180px}.layout-statement .prose{font-size:var(--slide-statement-font-size);letter-spacing:-.012em;line-height:1.12}.layout-statement .prose :where(h1,h2){font-size:var(--slide-statement-font-size);margin-block-end:36px;line-height:1.12}.layout-statement .prose p{font-size:var(--slide-body-font-size);letter-spacing:0;max-width:20ch;line-height:1.4}.layout-content .slide-content{justify-content:center}.layout-content .prose{max-width:920px}.layout-code .slide-content{justify-content:center;gap:50px}.layout-code .prose{flex:none}.visual,.stack{flex-direction:column;min-height:0;display:flex}.layout-code .visual{width:100%;max-width:none;min-height:0;margin-inline:auto}.layout-code-left .slide-content,.layout-code-right .slide-content,.layout-split-code .slide-content{justify-content:center}.panes{grid-template-rows:minmax(0,1fr);grid-template-columns:minmax(0,1fr) minmax(0,1fr);align-items:center;gap:72px;width:100%;min-height:0;display:grid}.layout-code-left .panes{grid-template-columns:minmax(0,1.55fr) minmax(0,1fr)}.layout-code-right .panes{grid-template-columns:minmax(0,1fr) minmax(0,1.55fr)}.pane{min-width:0;min-height:0;max-height:100%}.pane.prose{max-width:640px}.layout-split-code .panes{align-items:stretch}.layout-split-code .pane{flex-direction:column;min-width:0;display:flex}.layout-split-code .pane>ul>li::marker{color:var(--slide-accent)}.layout-split-code .pane>ol>li::marker{color:var(--slide-accent)}.layout-code-result .slide-content{justify-content:center;gap:24px}.layout-code-result .prose{flex:none}.layout-code-result .prose :where(h1,h2){max-width:24ch}.layout-code-result .prose p{margin-bottom:16px}.layout-code-result .stack{flex-direction:column;gap:24px;min-height:0;display:flex}.stack{min-width:0}@media (max-width:900px){.presentation-root:not(.js) .slide-content{padding:clamp(24px,6vw,56px)}.presentation-root:not(.js) :is(.prose,.pane) :where(h1,h2){font-size:clamp(32px,7vw,64px)}.presentation-root:not(.js) :is(.prose,.pane) :where(h3,h4){font-size:clamp(26px,5vw,44px)}.presentation-root:not(.js) .prose{font-size:clamp(22px,4vw,40px)}.presentation-root:not(.js) .layout-code-left .panes,.presentation-root:not(.js) .layout-code-right .panes,.presentation-root:not(.js) .layout-split-code .panes{grid-template-columns:1fr;gap:40px}}@supports not ((width:1cqw) and (height:1cqh) and (transform:scale(tan(atan2(1px, 1px))))){@media (max-width:900px){.presentation-root.js .slide-content{padding:56px}.presentation-root.js .prose h1{font-size:clamp(48px,9vw,88px)}.presentation-root.js .prose{font-size:clamp(22px,4vw,40px)}.presentation-root.js .layout-code-left .panes,.presentation-root.js .layout-code-right .panes,.presentation-root.js .layout-split-code .panes{grid-template-columns:1fr;gap:40px}}}@supports (width:1cqw) and (height:1cqh) and (transform:scale(tan(atan2(1px, 1px)))){.presentation-root.js.is-overview .slide-deck,.presentation-root.js[data-overview-active=true] .slide-deck{grid-template-columns:repeat(auto-fit,minmax(min(360px,42vw),1fr));grid-auto-rows:max-content;align-content:start;align-items:start;gap:32px;padding:112px 48px 56px;display:grid;overflow:auto}.presentation-root.js.is-overview .slide,.presentation-root.js[data-overview-active=true] .slide{aspect-ratio:16/9;visibility:visible;border:2px solid var(--slide-code-border);width:100%;min-width:0;height:auto;box-shadow:0 12px 28px var(--slide-code-shadow);cursor:pointer;border-radius:16px;margin:0;position:relative;inset:auto;overflow:hidden;transform:none;container-type:inline-size}.presentation-root.js.is-overview .slide.is-active,.presentation-root.js[data-overview-active=true] .slide.is-active{border-color:var(--slide-accent);box-shadow:0 0 0 4px var(--slide-highlight), 0 12px 28px var(--slide-code-shadow)}.presentation-root.js.is-overview .slide-content,.presentation-root.js[data-overview-active=true] .slide-content{--overview-slide-scale:tan(atan2(100cqw, 1920px));width:1920px;height:1080px;transform:scale(var(--overview-slide-scale,1));transform-origin:0 0;padding:108px 132px 100px}.presentation-root.js.is-overview .slide:focus-visible,.presentation-root.js[data-overview-active=true] .slide:focus-visible{outline:5px solid var(--slide-focus);outline-offset:6px}}.code-window,.terminal-window{border:2px solid var(--slide-code-border);min-width:0;min-height:0;max-height:100%;position:relative;overflow:hidden}@supports (color:color-mix(in lab, red, red)){.code-window,.terminal-window{border:2px solid color-mix(in srgb, var(--slide-code-border), transparent 15%)}}.code-window,.terminal-window{border-radius:var(--slide-radius);background:var(--slide-code-surface);box-shadow:0 24px 60px var(--slide-code-shadow), inset 0 1px 0 var(--slide-code-inset);font-family:var(--font-slide-mono);font-size:var(--slide-code-font-size);font-variant-ligatures:none;flex-direction:column;font-weight:450;line-height:1.45;display:flex}.code-window figcaption,.terminal-window figcaption{z-index:2;max-width:70%;color:var(--slide-muted);font-family:var(--font-slide-sans);letter-spacing:.015em;text-overflow:ellipsis;white-space:nowrap;font-size:28px;font-weight:500;position:absolute;top:16px;left:50%;overflow:hidden;transform:translate(-50%)}.code-window-header,.terminal-window:before{border-bottom:2px solid var(--slide-code-border);background:var(--slide-code-header);flex:0 0 72px;align-items:center;height:72px;padding:0 28px;display:flex}.code-window-controls{gap:10px;display:flex}.code-window-controls i{background:var(--slide-muted);opacity:.65;border-radius:50%;width:14px;height:14px;display:block}.code-window-controls i:first-child{background:var(--slide-dot-close)}.code-window-controls i:nth-child(2){background:var(--slide-dot-minimize)}.code-window-controls i:last-child{background:var(--slide-dot-maximize)}.code-window figcaption{max-width:min(50%,max(0px,100% - 224px))}.code-window-language{max-width:max(0px,25% - 40px);color:var(--slide-muted);letter-spacing:.04em;text-overflow:ellipsis;text-transform:uppercase;white-space:nowrap;margin-inline-start:auto;font-size:24px;overflow:hidden}.code-window pre,.terminal-window pre{tab-size:2;scrollbar-width:thin;scrollbar-color:var(--slide-muted) transparent;min-height:0;margin:0;padding:32px 34px 36px;font-family:inherit;overflow:auto}.code-window code,.terminal-window code{color:var(--slide-fg);font:inherit;display:block}.code-window .line{white-space:pre;border-inline-start:4px solid #0000;min-height:1.45em;padding-inline:16px 20px;display:block}.code-window .line:before{content:attr(data-line-number);width:2.2em;color:var(--slide-muted);text-align:end;-webkit-user-select:none;user-select:none;margin-inline-end:.8em;font-size:.8em;display:inline-block}.code-window .line:not([data-line-number]):before{content:none}.code-window .line.is-highlighted{border-inline-start-color:var(--slide-code-highlight-border);background:var(--slide-code-highlight-surface)}.code-window.has-focus .line.is-focused{border-inline-start-color:var(--slide-focus);background:var(--slide-code-focus-surface);opacity:1}.code-window .hll,.code-window .highlight{background:var(--slide-code-highlight-surface)}.code-window .c,.code-window .ch,.code-window .cm,.code-window .c1,.code-window .cs{color:var(--slide-syntax-comment)}.code-window .k,.code-window .kd,.code-window .kn,.code-window .kp,.code-window .kr,.code-window .kt{color:var(--slide-syntax-keyword)}.code-window .s,.code-window .sa,.code-window .sb,.code-window .sc,.code-window .dl,.code-window .sd,.code-window .s1,.code-window .s2{color:var(--slide-syntax-string)}.code-window .m,.code-window .mb,.code-window .mf,.code-window .mh,.code-window .mi,.code-window .mo{color:var(--slide-syntax-number)}.code-window .nf,.code-window .fm,.code-window .nd{color:var(--slide-syntax-function)}:is(.highlighter-rouge,figure.highlight) .c,:is(.highlighter-rouge,figure.highlight) .ch,:is(.highlighter-rouge,figure.highlight) .cm,:is(.highlighter-rouge,figure.highlight) .c1,:is(.highlighter-rouge,figure.highlight) .cs{color:var(--slide-syntax-comment)}:is(.highlighter-rouge,figure.highlight) .k,:is(.highlighter-rouge,figure.highlight) .kd,:is(.highlighter-rouge,figure.highlight) .kn,:is(.highlighter-rouge,figure.highlight) .kp,:is(.highlighter-rouge,figure.highlight) .kr,:is(.highlighter-rouge,figure.highlight) .kt{color:var(--slide-syntax-keyword)}:is(.highlighter-rouge,figure.highlight) .s,:is(.highlighter-rouge,figure.highlight) .sa,:is(.highlighter-rouge,figure.highlight) .sb,:is(.highlighter-rouge,figure.highlight) .sc,:is(.highlighter-rouge,figure.highlight) .dl,:is(.highlighter-rouge,figure.highlight) .sd,:is(.highlighter-rouge,figure.highlight) .s1,:is(.highlighter-rouge,figure.highlight) .s2{color:var(--slide-syntax-string)}:is(.highlighter-rouge,figure.highlight) .m,:is(.highlighter-rouge,figure.highlight) .mb,:is(.highlighter-rouge,figure.highlight) .mf,:is(.highlighter-rouge,figure.highlight) .mh,:is(.highlighter-rouge,figure.highlight) .mi,:is(.highlighter-rouge,figure.highlight) .mo{color:var(--slide-syntax-number)}:is(.highlighter-rouge,figure.highlight) .nf,:is(.highlighter-rouge,figure.highlight) .fm,:is(.highlighter-rouge,figure.highlight) .nd{color:var(--slide-syntax-function)}.code-window .o,.code-window .ow,:is(.highlighter-rouge,figure.highlight) .o,:is(.highlighter-rouge,figure.highlight) .ow{color:var(--slide-syntax-operator)}.code-window .p,:is(.highlighter-rouge,figure.highlight) .p{color:var(--slide-syntax-punctuation)}.code-window .n,.code-window .na,.code-window .nv,.code-window .vc,.code-window .vg,.code-window .vi,.code-window .py,:is(.highlighter-rouge,figure.highlight) .n,:is(.highlighter-rouge,figure.highlight) .na,:is(.highlighter-rouge,figure.highlight) .nv,:is(.highlighter-rouge,figure.highlight) .vc,:is(.highlighter-rouge,figure.highlight) .vg,:is(.highlighter-rouge,figure.highlight) .vi,:is(.highlighter-rouge,figure.highlight) .py{color:var(--slide-syntax-name)}.code-window .nv,.code-window .vc,.code-window .vg,.code-window .vi,:is(.highlighter-rouge,figure.highlight) .nv,:is(.highlighter-rouge,figure.highlight) .vc,:is(.highlighter-rouge,figure.highlight) .vg,:is(.highlighter-rouge,figure.highlight) .vi{color:var(--slide-syntax-variable)}.code-window .x,.code-window .sx,.code-window .ni,.code-window .nl,.code-window .nt,:is(.highlighter-rouge,figure.highlight) .x,:is(.highlighter-rouge,figure.highlight) .sx,:is(.highlighter-rouge,figure.highlight) .ni,:is(.highlighter-rouge,figure.highlight) .nl,:is(.highlighter-rouge,figure.highlight) .nt,.code-window .ss,.code-window .sh,.code-window .si,.code-window .sr,:is(.highlighter-rouge,figure.highlight) .ss,:is(.highlighter-rouge,figure.highlight) .sh,:is(.highlighter-rouge,figure.highlight) .si,:is(.highlighter-rouge,figure.highlight) .sr{color:var(--slide-syntax-symbol)}.code-window .kv,.code-window .kc,.code-window .cp,.code-window .cd,.code-window .pi,:is(.highlighter-rouge,figure.highlight) .kv,:is(.highlighter-rouge,figure.highlight) .kc,:is(.highlighter-rouge,figure.highlight) .cp,:is(.highlighter-rouge,figure.highlight) .cd,:is(.highlighter-rouge,figure.highlight) .pi{color:var(--slide-syntax-keyword)}.code-window .il,:is(.highlighter-rouge,figure.highlight) .il{color:var(--slide-syntax-number)}.code-window .nb,.code-window .bp,:is(.highlighter-rouge,figure.highlight) .nb,:is(.highlighter-rouge,figure.highlight) .bp{color:var(--slide-syntax-builtin)}.code-window .nc,.code-window .no,.code-window .ne,.code-window .nn,.code-window .nx,:is(.highlighter-rouge,figure.highlight) .nc,:is(.highlighter-rouge,figure.highlight) .no,:is(.highlighter-rouge,figure.highlight) .ne,:is(.highlighter-rouge,figure.highlight) .nn,:is(.highlighter-rouge,figure.highlight) .nx{color:var(--slide-syntax-constant)}.code-window .err,:is(.highlighter-rouge,figure.highlight) .err{color:var(--slide-syntax-error);-webkit-text-decoration:wavy underline var(--slide-syntax-error);-webkit-text-decoration:wavy underline var(--slide-syntax-error);text-decoration:wavy underline var(--slide-syntax-error);text-underline-offset:4px}.highlighter-rouge,figure.highlight{min-width:0;font-family:var(--font-slide-mono)}.highlighter-rouge .highlight,figure.highlight{border:1px solid var(--slide-code-border);background:var(--slide-code-surface);box-shadow:inset 0 1px 0 var(--slide-code-inset);font-size:var(--slide-code-font-size);font-variant-ligatures:none;scrollbar-width:thin;scrollbar-color:var(--slide-muted) transparent;border-radius:16px;font-weight:450;line-height:1.45;overflow:auto}.highlighter-rouge pre,figure.highlight pre{margin:0;padding:28px 32px}.highlighter-rouge code,figure.highlight code{color:var(--slide-fg);font:inherit}.code-window.size-sm,.terminal-window.size-sm{font-size:32px}.code-window.size-md,.terminal-window.size-md{font-size:38px}.code-window.size-lg,.terminal-window.size-lg{font-size:42px}.code-window.size-sm .code-window-header,.terminal-window.size-sm:before{flex-basis:62px;height:62px}.code-window.size-lg .code-window-header,.terminal-window.size-lg:before{flex-basis:82px;height:82px}.terminal-window{background:var(--slide-code-surface)}.terminal-window:before{content:"";background:var(--slide-code-header)}.terminal-window pre{padding-top:28px}.terminal-window .tline{white-space:pre-wrap;min-height:1.45em;display:block}.terminal-window .prompt{color:var(--slide-accent-strong);font-weight:700}.terminal-window .cmd{color:var(--slide-link)}.terminal-window .tline:not(:has(.prompt)):not(:has(.cmd)){color:var(--slide-fg)}.presentation-chrome{z-index:20;color:var(--slide-muted);pointer-events:none;position:fixed;inset:0}.presentation-root:not(.js) .presentation-chrome{visibility:hidden;pointer-events:none}.slide-controls{pointer-events:auto;background:0 0;border:1px solid #0000;border-radius:12px;align-items:center;gap:8px;padding:8px;transition:background .2s,border-color .2s;display:flex;position:absolute;bottom:16px;right:24px}.slide-controls:hover,.slide-controls:focus-within{border-color:var(--slide-code-border);background:var(--slide-bg)}@supports (color:color-mix(in lab, red, red)){.slide-controls:hover,.slide-controls:focus-within{background:color-mix(in srgb, var(--slide-bg), transparent 12%)}}.slide-controls:hover,.slide-controls:focus-within{-webkit-backdrop-filter:blur(18px);backdrop-filter:blur(18px)}.slide-control{border:1px solid var(--slide-code-border);width:46px;height:38px;color:var(--slide-fg);cursor:pointer;font:inherit;opacity:0;pointer-events:none;background:0 0;border-radius:9px;place-items:center;line-height:1;transition:background .2s,color .2s,border-color .2s,opacity .2s,transform .2s;display:inline-grid;transform:translateY(4px)}.slide-controls:hover .slide-control,.slide-controls:focus-within .slide-control{opacity:1;pointer-events:auto;transform:none}.slide-control:hover{border-color:var(--slide-accent);background:var(--slide-highlight);color:var(--slide-accent-strong)}.slide-controls:hover .slide-control:disabled,.slide-controls:focus-within .slide-control:disabled{opacity:.35;cursor:default}.slide-counter{font-family:var(--font-slide-mono);letter-spacing:.04em;margin:0;font-size:17px}.slide-progress{width:100%;height:4px;accent-color:var(--slide-accent);opacity:.58;pointer-events:auto;position:absolute;bottom:0;left:0;right:0}.slide-progress::-webkit-progress-bar{background:var(--slide-code-border);border-radius:99px}.slide-progress::-webkit-progress-value{background:var(--slide-accent);border-radius:99px}.overview-hint{z-index:25;border:1px solid var(--slide-code-border);background:var(--slide-code-surface);color:var(--slide-muted);font-family:var(--font-slide-mono);border-radius:999px;margin:0;padding:10px 18px;font-size:14px;position:fixed;top:82px;left:50%;transform:translate(-50%)}.overview-hint[hidden]{display:none}.presentation-root.js.is-fullscreen .presentation-chrome,.presentation-root.js[data-fullscreen-active=true] .presentation-chrome{opacity:0;transition:opacity .35s}.presentation-root.js.is-fullscreen .presentation-chrome:hover,.presentation-root.js.is-fullscreen .presentation-chrome:focus-within,.presentation-root.js[data-fullscreen-active=true] .presentation-chrome:hover,.presentation-root.js[data-fullscreen-active=true] .presentation-chrome:focus-within{opacity:1}.slide-control:focus-visible,.slide-progress:focus-visible{outline:4px solid var(--slide-focus);outline-offset:4px}@media (prefers-reduced-motion:reduce){*,:before,:after{scroll-behavior:auto!important;transition-duration:0s!important;animation-duration:0s!important;animation-iteration-count:1!important}}.presentation-root.is-reduced-motion .presentation-chrome,.presentation-root[data-reduced-motion=true] .presentation-chrome{transition:none}@page{size:13.333in 7.5in;margin:0}@media print{*,:before,:after{transition:none!important;animation:none!important}html,body{width:13.333in;min-width:13.333in;background:var(--slide-bg)!important}body{-webkit-print-color-adjust:exact;print-color-adjust:exact}.presentation-root,.presentation-root.js{width:13.333in!important;height:auto!important;min-height:0!important;overflow:visible!important}.presentation-chrome,.slide-progress,.overview-hint{display:none!important}.slide-deck,.presentation-root.js .slide-deck,.presentation-root.js.is-overview .slide-deck{width:13.333in!important;height:auto!important;min-height:0!important;padding:0!important;display:block!important;position:static!important;overflow:visible!important}.slide,.presentation-root.js .slide,.presentation-root.js.is-overview .slide{break-after:page;page-break-after:always;min-height:0;visibility:visible!important;width:13.333in!important;height:7.5in!important;box-shadow:none!important;cursor:default!important;border:0!important;border-radius:0!important;margin:0!important;display:block!important;position:relative!important;inset:auto!important;overflow:hidden!important;transform:none!important}.slide:last-child{break-after:auto;page-break-after:auto}.slide-content,.presentation-root.js.is-overview .slide-content{transform-origin:0 0;width:1920px!important;height:1080px!important;transform:scale(.66665)!important}.code-window .line,.terminal-window .tline{opacity:1!important}}
|
|
2
|
+
@layer theme{:root,:host{--font-sans:-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", "Noto Sans", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";--font-mono:ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;--default-font-family:var(--font-sans);--default-mono-font-family:var(--font-mono);--font-slide-sans:"Atkinson Hyperlegible Next", "Avenir Next", "Segoe UI Variable", "Segoe UI", system-ui, sans-serif;--font-slide-mono:"Atkinson Hyperlegible Mono", "JetBrains Mono", "SFMono-Regular", Consolas, monospace;--slide-canvas-width:1920px;--slide-canvas-height:1080px;--slide-radius:28px}}@layer base{*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;tab-size:4;line-height:1.5;font-family:var(--default-font-family,-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", "Noto Sans", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji");font-feature-settings:var(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--default-mono-font-family,ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-variation-settings:var(--default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring:where(:not(iframe)){outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::placeholder{opacity:1}@supports (not ((-webkit-appearance:-apple-pay-button))) or (contain-intrinsic-size:1px){::placeholder{color:currentColor}@supports (color:color-mix(in lab, red, red)){::placeholder{color:color-mix(in oklab, currentcolor 50%, transparent)}}}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit{padding-block:0}::-webkit-datetime-edit-year-field{padding-block:0}::-webkit-datetime-edit-month-field{padding-block:0}::-webkit-datetime-edit-day-field{padding-block:0}::-webkit-datetime-edit-hour-field{padding-block:0}::-webkit-datetime-edit-minute-field{padding-block:0}::-webkit-datetime-edit-second-field{padding-block:0}::-webkit-datetime-edit-millisecond-field{padding-block:0}::-webkit-datetime-edit-meridiem-field{padding-block:0}::-webkit-calendar-picker-indicator{line-height:1}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]){appearance:button}::file-selector-button{appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}}@layer components;@layer utilities{.visible{visibility:visible}.block{display:block}.grid{display:grid}.hidden{display:none}}@font-face{font-family:Atkinson Hyperlegible Next;font-style:normal;font-weight:200 800;font-display:swap;src:url(../fonts/atkinson-hyperlegible-next.woff2)format("woff2")}@font-face{font-family:Atkinson Hyperlegible Next;font-style:italic;font-weight:200 800;font-display:swap;src:url(../fonts/atkinson-hyperlegible-next-italic.woff2)format("woff2")}@font-face{font-family:Atkinson Hyperlegible Mono;font-style:normal;font-weight:200 800;font-display:swap;src:url(../fonts/atkinson-hyperlegible-mono.woff2)format("woff2")}@font-face{font-family:Atkinson Hyperlegible Mono;font-style:italic;font-weight:200 800;font-display:swap;src:url(../fonts/atkinson-hyperlegible-mono-italic.woff2)format("woff2")}:root{--slide-dot-close:#ff5f57;--slide-dot-minimize:#febc2e;--slide-dot-maximize:#28c840;--slide-dot-rim:#00000029;--slide-dot-gloss:#ffffff42}:root,[data-theme=midnight],[data-code-theme=midnight]{--slide-fg:#f3f5f8;--slide-muted:#b4bdca;--slide-accent:#ff6b4a;--slide-accent-strong:#ff8a65;--slide-code-surface:#151b26;--slide-code-header:#1c2532;--slide-code-border:#364354;--slide-code-shadow:#0000006b;--slide-syntax-comment:#aab5c5;--slide-syntax-keyword:#ff9e7a;--slide-syntax-string:#b8d98e;--slide-syntax-number:#c6a9ff;--slide-syntax-function:#75c9db;--slide-syntax-operator:#f3f5f8;--slide-syntax-punctuation:#b9c4d2;--slide-syntax-name:#f3f5f8;--slide-syntax-variable:#f3f5f8;--slide-syntax-symbol:#75c9db;--slide-syntax-builtin:#75c9db;--slide-syntax-constant:#c6a9ff;--slide-syntax-error:#ff8675;--slide-highlight:#ff6b4a2b;--slide-focus:#ff9e7a;--slide-link:#9edbea;--slide-code-font-size:38px;--slide-code-highlight-surface:#ff6b4a1a;--slide-code-highlight-border:#ff6b4a;--slide-code-focus-surface:#ff9e7a1a;--slide-code-inset:#ffffff0f;--slide-surface-shine:#ffffff0f}:root,[data-theme=midnight]{--slide-bg:#10141d;--slide-selection:#ff6b4a47;--slide-grid-line:#ffffff0e;--slide-spotlight:#ff6b4a26;--slide-gradient-start:#191d2c;--slide-gradient-end:#10141d;--slide-quote:#c8d1dc;--slide-heading-font-size:72px;--slide-title-font-size:108px;--slide-body-font-size:44px;--slide-statement-font-size:88px}[data-theme=minimal-light],[data-code-theme=minimal-light]{--slide-fg:#1c2027;--slide-muted:#4d5660;--slide-accent:#bc3e27;--slide-accent-strong:#8d2919;--slide-code-surface:#e9e6df;--slide-code-header:#dedbd4;--slide-code-border:#c8c4bb;--slide-code-shadow:#302c242e;--slide-syntax-comment:#50564f;--slide-syntax-keyword:#9d3e28;--slide-syntax-string:#325c35;--slide-syntax-number:#6b4ca0;--slide-syntax-function:#12586a;--slide-syntax-operator:#343b45;--slide-syntax-punctuation:#4d5863;--slide-syntax-name:#1c2027;--slide-syntax-variable:#1c2027;--slide-syntax-symbol:#12586a;--slide-syntax-builtin:#12586a;--slide-syntax-constant:#6b4ca0;--slide-syntax-error:#a52121;--slide-highlight:#bc3e2721;--slide-focus:#9d3e28;--slide-link:#176d82;--slide-code-font-size:38px;--slide-code-highlight-surface:#bc3e2712;--slide-code-highlight-border:#bc3e27;--slide-code-focus-surface:#9d3e2812;--slide-code-inset:#1c202714;--slide-surface-shine:#ffffff0f}[data-theme=minimal-light]{--slide-bg:#f4f1eb;--slide-selection:#bc3e2733;--slide-grid-line:#1c202714;--slide-spotlight:#bc3e271f;--slide-gradient-start:#fffdf8;--slide-gradient-end:#e9e5dc;--slide-quote:#424a54;--slide-heading-font-size:72px;--slide-title-font-size:96px;--slide-body-font-size:44px;--slide-statement-font-size:88px}[data-theme=minimal-dark],[data-code-theme=minimal-dark]{--slide-fg:#f4f1ea;--slide-muted:#bcb8b0;--slide-accent:#e6b566;--slide-accent-strong:#f2c57a;--slide-code-surface:#202020;--slide-code-header:#2b2b2a;--slide-code-border:#454441;--slide-code-shadow:#00000080;--slide-syntax-comment:#b2afa9;--slide-syntax-keyword:#f0bd75;--slide-syntax-string:#b8d094;--slide-syntax-number:#d1a9e8;--slide-syntax-function:#83ced1;--slide-syntax-operator:#f4f1ea;--slide-syntax-punctuation:#c5c1b9;--slide-syntax-name:#f4f1ea;--slide-syntax-variable:#f4f1ea;--slide-syntax-symbol:#83ced1;--slide-syntax-builtin:#83ced1;--slide-syntax-constant:#d1a9e8;--slide-syntax-error:#f28272;--slide-highlight:#e6b56629;--slide-focus:#f0bd75;--slide-link:#83ced1;--slide-code-font-size:38px;--slide-code-highlight-surface:#e6b5661a;--slide-code-highlight-border:#e6b566;--slide-code-focus-surface:#f0bd751a;--slide-code-inset:#ffffff0f;--slide-surface-shine:#ffffff0f}[data-theme=minimal-dark]{--slide-bg:#171717;--slide-selection:#e6b56640;--slide-grid-line:#ffffff0f;--slide-spotlight:#e6b56621;--slide-gradient-start:#25221e;--slide-gradient-end:#171717;--slide-quote:#d3cec4;--slide-heading-font-size:72px;--slide-title-font-size:108px;--slide-body-font-size:44px;--slide-statement-font-size:88px}[data-theme=ruby],[data-code-theme=ruby]{--slide-fg:#fff4ed;--slide-muted:#dfbcc3;--slide-accent:#ff7a68;--slide-accent-strong:#ffb09a;--slide-code-surface:#2a1520;--slide-code-header:#3a1c2a;--slide-code-border:#613348;--slide-code-shadow:#0a020780;--slide-syntax-comment:#cba8b0;--slide-syntax-keyword:#ff9f80;--slide-syntax-string:#c6e19c;--slide-syntax-number:#d9afff;--slide-syntax-function:#8ed9e0;--slide-syntax-operator:#fff4ed;--slide-syntax-punctuation:#e0bdc3;--slide-syntax-name:#fff4ed;--slide-syntax-variable:#fff4ed;--slide-syntax-symbol:#8ed9e0;--slide-syntax-builtin:#8ed9e0;--slide-syntax-constant:#d9afff;--slide-syntax-error:#ff8176;--slide-highlight:#ff7a682e;--slide-focus:#ffb09a;--slide-link:#8ed9e0;--slide-code-font-size:38px;--slide-code-highlight-surface:#ff7a681a;--slide-code-highlight-border:#ff7a68;--slide-code-focus-surface:#ffb09a1a;--slide-code-inset:#ffffff0f;--slide-surface-shine:#ffffff0f}[data-theme=ruby]{--slide-bg:#210f18;--slide-selection:#ff7a6847;--slide-grid-line:#ffe5dc11;--slide-spotlight:#ff7a6829;--slide-gradient-start:#3a1828;--slide-gradient-end:#210f18;--slide-quote:#f1c7c9;--slide-heading-font-size:72px;--slide-title-font-size:108px;--slide-body-font-size:44px;--slide-statement-font-size:88px}[data-theme=catppuccin-latte],[data-code-theme=catppuccin-latte]{--slide-fg:#4c4f69;--slide-muted:#5b5e70;--slide-accent:#8839ef;--slide-accent-strong:#7d34dc;--slide-code-surface:#e6e9ef;--slide-code-header:#dce0e8;--slide-code-border:#bcc0cc;--slide-code-shadow:#4c4f6938;--slide-syntax-comment:#5b5e67;--slide-syntax-keyword:#7832d3;--slide-syntax-string:#2a6a1c;--slide-syntax-number:#a23f07;--slide-syntax-function:#1956d0;--slide-syntax-operator:#02658c;--slide-syntax-punctuation:#5b5e67;--slide-syntax-name:#4c4f69;--slide-syntax-variable:#4c4f69;--slide-syntax-symbol:#10696e;--slide-syntax-builtin:#b90d32;--slide-syntax-constant:#835311;--slide-syntax-error:#b90d32;--slide-highlight:#8839ef21;--slide-focus:#7d34dc;--slide-link:#1b5ee1;--slide-code-font-size:38px;--slide-code-highlight-surface:#8839ef12;--slide-code-highlight-border:#8839ef;--slide-code-focus-surface:#1e66f512;--slide-code-inset:#4c4f6914;--slide-surface-shine:#ffffff8c}[data-theme=catppuccin-latte]{--slide-bg:#eff1f5;--slide-selection:#8839ef33;--slide-grid-line:#4c4f6914;--slide-spotlight:#8839ef1f;--slide-gradient-start:#fbfcfe;--slide-gradient-end:#eff1f5;--slide-quote:#5c5f77;--slide-heading-font-size:72px;--slide-title-font-size:108px;--slide-body-font-size:44px;--slide-statement-font-size:88px}[data-theme=catppuccin-frappe],[data-code-theme=catppuccin-frappe]{--slide-fg:#c6d0f5;--slide-muted:#acb3d1;--slide-accent:#ca9ee6;--slide-accent-strong:#babbf1;--slide-code-surface:#303446;--slide-code-header:#414559;--slide-code-border:#51576d;--slide-code-shadow:#2326348c;--slide-syntax-comment:#aeb4cb;--slide-syntax-keyword:#cea5e7;--slide-syntax-string:#a6d189;--slide-syntax-number:#efa27b;--slide-syntax-function:#99b3ef;--slide-syntax-operator:#99d1db;--slide-syntax-punctuation:#acb3d1;--slide-syntax-name:#c6d0f5;--slide-syntax-variable:#c6d0f5;--slide-syntax-symbol:#81c8be;--slide-syntax-builtin:#eba0a3;--slide-syntax-constant:#e5c890;--slide-syntax-error:#eca1a2;--slide-highlight:#ca9ee62b;--slide-focus:#babbf1;--slide-link:#99d1db;--slide-code-font-size:38px;--slide-code-highlight-surface:#ca9ee61f;--slide-code-highlight-border:#ca9ee6;--slide-code-focus-surface:#babbf11f;--slide-code-inset:#ffffff0f;--slide-surface-shine:#ffffff0f}[data-theme=catppuccin-frappe]{--slide-bg:#292c3c;--slide-selection:#ca9ee647;--slide-grid-line:#c6d0f50f;--slide-spotlight:#ca9ee626;--slide-gradient-start:#414559;--slide-gradient-end:#292c3c;--slide-quote:#b5bfe2;--slide-heading-font-size:72px;--slide-title-font-size:108px;--slide-body-font-size:44px;--slide-statement-font-size:88px}[data-theme=catppuccin-macchiato],[data-code-theme=catppuccin-macchiato]{--slide-fg:#cad3f5;--slide-muted:#a5adcb;--slide-accent:#c6a0f6;--slide-accent-strong:#b7bdf8;--slide-code-surface:#24273a;--slide-code-header:#363a4f;--slide-code-border:#494d64;--slide-code-shadow:#1819268c;--slide-syntax-comment:#9fa5bf;--slide-syntax-keyword:#c6a0f6;--slide-syntax-string:#a6da95;--slide-syntax-number:#f5a97f;--slide-syntax-function:#8aadf4;--slide-syntax-operator:#91d7e3;--slide-syntax-punctuation:#a5adcb;--slide-syntax-name:#cad3f5;--slide-syntax-variable:#cad3f5;--slide-syntax-symbol:#8bd5ca;--slide-syntax-builtin:#ee99a0;--slide-syntax-constant:#eed49f;--slide-syntax-error:#ed8b9a;--slide-highlight:#c6a0f62b;--slide-focus:#b7bdf8;--slide-link:#91d7e3;--slide-code-font-size:38px;--slide-code-highlight-surface:#c6a0f61f;--slide-code-highlight-border:#c6a0f6;--slide-code-focus-surface:#b7bdf81f;--slide-code-inset:#ffffff0f;--slide-surface-shine:#ffffff0f}[data-theme=catppuccin-macchiato]{--slide-bg:#1e2030;--slide-selection:#c6a0f647;--slide-grid-line:#cad3f50f;--slide-spotlight:#c6a0f626;--slide-gradient-start:#363a4f;--slide-gradient-end:#1e2030;--slide-quote:#b8c0e0;--slide-heading-font-size:72px;--slide-title-font-size:108px;--slide-body-font-size:44px;--slide-statement-font-size:88px}[data-theme=catppuccin-mocha],[data-code-theme=catppuccin-mocha]{--slide-fg:#cdd6f4;--slide-muted:#a6adc8;--slide-accent:#cba6f7;--slide-accent-strong:#b4befe;--slide-code-surface:#1e1e2e;--slide-code-header:#313244;--slide-code-border:#45475a;--slide-code-shadow:#11111b8c;--slide-syntax-comment:#979db5;--slide-syntax-keyword:#cba6f7;--slide-syntax-string:#a6e3a1;--slide-syntax-number:#fab387;--slide-syntax-function:#89b4fa;--slide-syntax-operator:#89dceb;--slide-syntax-punctuation:#a6adc8;--slide-syntax-name:#cdd6f4;--slide-syntax-variable:#cdd6f4;--slide-syntax-symbol:#94e2d5;--slide-syntax-builtin:#eba0ac;--slide-syntax-constant:#f9e2af;--slide-syntax-error:#f38ba8;--slide-highlight:#cba6f72b;--slide-focus:#b4befe;--slide-link:#89dceb;--slide-code-font-size:38px;--slide-code-highlight-surface:#cba6f71f;--slide-code-highlight-border:#cba6f7;--slide-code-focus-surface:#b4befe1f;--slide-code-inset:#ffffff0f;--slide-surface-shine:#ffffff0f}[data-theme=catppuccin-mocha]{--slide-bg:#181825;--slide-selection:#cba6f747;--slide-grid-line:#cdd6f40f;--slide-spotlight:#cba6f726;--slide-gradient-start:#313244;--slide-gradient-end:#181825;--slide-quote:#bac2de;--slide-heading-font-size:72px;--slide-title-font-size:108px;--slide-body-font-size:44px;--slide-statement-font-size:88px}*{box-sizing:border-box}::selection{background:var(--slide-selection);color:var(--slide-fg)}html,body{min-height:100%;margin:0}body{background:var(--slide-bg);color:var(--slide-fg);font-family:var(--font-slide-sans);font-synthesis:none;text-rendering:optimizelegibility;font-weight:400}.presentation-root{background:var(--slide-bg);min-height:100dvh;color:var(--slide-fg)}.presentation-root:not(.js) .slide-deck{flex-direction:column;align-items:center;gap:2rem;width:100%;height:auto;min-height:0;padding:2rem;display:flex;overflow:visible}.presentation-root:not(.js) .slide{width:min(100%, var(--slide-canvas-width));aspect-ratio:16/9;height:auto;position:relative;overflow:visible}.presentation-root:not(.js) .slide-content{height:auto;min-height:0}.presentation-root.js .slide-deck{flex-direction:column;align-items:center;gap:2rem;width:100%;height:auto;min-height:0;padding:2rem;display:flex;overflow:visible}.presentation-root.js .slide{width:min(100%, var(--slide-canvas-width));aspect-ratio:16/9;height:auto;position:relative;overflow:visible}.presentation-root.js .slide-content{height:auto;min-height:0}.slide-deck{isolation:isolate;width:100vw;height:100dvh;min-height:0;position:relative;container-type:size}.slide{width:var(--slide-canvas-width);height:var(--slide-canvas-height);aspect-ratio:16/9;color:var(--slide-fg);background:var(--slide-bg);position:relative;overflow:hidden}@supports (width:1cqw) and (height:1cqh) and (transform:scale(tan(atan2(1px, 1px)))){.presentation-root.js{width:100vw;height:100dvh;min-height:0;overflow:hidden}.presentation-root.js .slide-deck{place-items:center;gap:0;width:100%;height:100%;min-height:0;padding:0;display:grid;overflow:hidden;container-type:size}.presentation-root.js .slide{--slide-scale:min(tan(atan2(100cqw, 1920px)), tan(atan2(100cqh, 1080px)));width:var(--slide-canvas-width);height:var(--slide-canvas-height);transform:translate(-50%, -50%) scale(var(--slide-scale,1));transform-origin:50%;margin:0;position:absolute;inset:50% auto auto 50%;overflow:hidden}.presentation-root.js .slide-content{height:100%}.presentation-root.js:not(.is-overview) .slide:not(.is-active),.presentation-root.js[data-overview-active=false] .slide:not(.is-active){visibility:hidden;pointer-events:none}}@supports (transform:scale(abs(-1))){.presentation-root.js .slide{--slide-scale:min(abs(tan(atan2(100cqw, 1920px))), abs(tan(atan2(100cqh, 1080px))))}}.slide-content{z-index:1;flex-direction:column;width:100%;height:100%;padding:108px 132px 100px;display:flex;position:relative}:where(.prose,.layout-split-code .pane){max-width:100%;font-size:var(--slide-body-font-size);letter-spacing:0;line-height:1.4}:where(.prose,.layout-split-code .pane) :where(h1,h2,h3,h4){letter-spacing:-.012em;text-wrap:balance;max-width:16ch;margin:0 0 32px;line-height:1.12}:where(.prose,.layout-split-code .pane) :where(h1,h2){font-size:var(--slide-heading-font-size);font-weight:600}:where(.prose,.layout-split-code .pane) h3{font-size:56px;font-weight:600}:where(.prose,.layout-split-code .pane) h4{font-size:44px;font-weight:600}:where(.prose,.layout-split-code .pane) p{max-width:40ch;margin:0 0 28px}:where(.prose,.layout-split-code .pane) strong{color:var(--slide-accent-strong);font-weight:700}:where(.prose,.layout-split-code .pane) em{color:var(--slide-quote)}:where(.prose,.layout-split-code .pane) a{color:var(--slide-link);text-underline-offset:6px;text-decoration:underline;text-decoration-thickness:3px}:where(.prose,.layout-split-code .pane) :where(ul,ol){max-width:34ch;margin:0 0 28px;padding-inline-start:1.25em}:where(.prose,.layout-split-code .pane) ul{list-style-type:disc}:where(.prose,.layout-split-code .pane) ol{list-style-type:decimal}:where(.prose,.layout-split-code .pane) ul ul{list-style-type:circle}:where(.prose,.layout-split-code .pane) ol ol{list-style-type:lower-alpha}:where(.prose,.layout-split-code .pane) li{margin-block:.25em;padding-inline-start:.2em}:where(.prose,.layout-split-code .pane) li::marker{color:var(--slide-accent)}:where(.prose,.layout-split-code .pane) code:not(pre code){border:1px solid var(--slide-code-border);background:var(--slide-code-surface);color:var(--slide-accent-strong);font-family:var(--font-slide-mono);font-variant-ligatures:none;border-radius:8px;padding:.12em .28em;font-size:.95em}:where(.prose,.layout-split-code .pane) blockquote{border-inline-start:6px solid var(--slide-accent);max-width:34ch;color:var(--slide-quote);margin:0 0 28px;padding:12px 28px;font-style:italic}:where(.prose,.layout-split-code .pane) img{object-fit:contain;border-radius:20px;max-width:100%;max-height:520px;display:block}:where(.prose,.layout-split-code .pane) table{border-collapse:collapse;margin-block:16px 28px;font-size:1em}:where(.prose,.layout-split-code .pane) th,:where(.prose,.layout-split-code .pane) td{border-bottom:2px solid var(--slide-code-border);text-align:start;padding:12px 20px}:where(.prose,.layout-split-code .pane) th{color:var(--slide-accent-strong);font-weight:700}.visually-hidden{clip:rect(0 0 0 0);white-space:nowrap;border:0;width:1px;height:1px;margin:-1px;padding:0;position:absolute;overflow:hidden}.slide{isolation:isolate}.slide:before,.slide:after{content:none;pointer-events:none;position:absolute}.slide:before{z-index:0;background:var(--slide-bg);inset:0}.bg-plain:before{content:"";background:var(--slide-bg)}.bg-gradient:before{content:"";background:linear-gradient(135deg, var(--slide-gradient-start), var(--slide-gradient-end) 64%)}.bg-grid:before{content:"";background-color:var(--slide-bg);background-image:linear-gradient(var(--slide-grid-line) 1px, transparent 1px), linear-gradient(90deg, var(--slide-grid-line) 1px, transparent 1px);background-size:72px 72px}.bg-spotlight:before{content:"";background:radial-gradient(circle at 70% 18%, var(--slide-spotlight), transparent 42%), var(--slide-bg)}.bg-gradient:after,.bg-grid:after,.bg-spotlight:after{content:"";z-index:0;background:var(--slide-spotlight);filter:blur(90px);opacity:.5;border-radius:50%;width:70%;height:70%;top:-28%;right:-12%}.layout-title .slide-content{justify-content:center;padding-inline:180px}.layout-title .prose h1{max-width:12ch;font-size:var(--slide-title-font-size)}.layout-title .prose p{max-width:28ch;color:var(--slide-muted)}.layout-statement .slide-content{justify-content:center;padding-inline:180px}.layout-statement .prose{font-size:var(--slide-statement-font-size);letter-spacing:-.012em;line-height:1.12}.layout-statement .prose :where(h1,h2){font-size:var(--slide-statement-font-size);margin-block-end:36px;line-height:1.12}.layout-statement .prose p{font-size:var(--slide-body-font-size);letter-spacing:0;max-width:20ch;line-height:1.4}.layout-content .slide-content{justify-content:center}.layout-content .prose{max-width:920px}.layout-code .slide-content{justify-content:center;gap:50px}.layout-code .prose{flex:none}.visual,.stack{flex-direction:column;min-height:0;display:flex}.layout-code .visual{width:100%;max-width:none;min-height:0;margin-inline:auto}.layout-code-left .slide-content,.layout-code-right .slide-content,.layout-split-code .slide-content{justify-content:center}.panes{grid-template-rows:minmax(0,1fr);grid-template-columns:minmax(0,1fr) minmax(0,1fr);align-items:center;gap:72px;width:100%;min-height:0;display:grid}.layout-code-left .panes{grid-template-columns:minmax(0,1.55fr) minmax(0,1fr)}.layout-code-right .panes{grid-template-columns:minmax(0,1fr) minmax(0,1.55fr)}.pane{min-width:0;min-height:0;max-height:100%}.pane.prose{max-width:640px}.layout-split-code .panes{align-items:stretch}.layout-split-code .pane{flex-direction:column;min-width:0;display:flex}.layout-split-code .pane>ul>li::marker{color:var(--slide-accent)}.layout-split-code .pane>ol>li::marker{color:var(--slide-accent)}.layout-code-result .slide-content{justify-content:center;gap:24px}.layout-code-result .prose{flex:none}.layout-code-result .prose :where(h1,h2){max-width:24ch}.layout-code-result .prose p{margin-bottom:16px}.layout-code-result .stack{flex-direction:column;gap:24px;min-height:0;display:flex}.stack{min-width:0}@media (max-width:900px){.presentation-root:not(.js) .slide-content{padding:clamp(24px,6vw,56px)}.presentation-root:not(.js) :is(.prose,.pane) :where(h1,h2){font-size:clamp(32px,7vw,64px)}.presentation-root:not(.js) :is(.prose,.pane) :where(h3,h4){font-size:clamp(26px,5vw,44px)}.presentation-root:not(.js) .prose{font-size:clamp(22px,4vw,40px)}.presentation-root:not(.js) .layout-code-left .panes,.presentation-root:not(.js) .layout-code-right .panes,.presentation-root:not(.js) .layout-split-code .panes{grid-template-columns:1fr;gap:40px}}@supports not ((width:1cqw) and (height:1cqh) and (transform:scale(tan(atan2(1px, 1px))))){@media (max-width:900px){.presentation-root.js .slide-content{padding:56px}.presentation-root.js .prose h1{font-size:clamp(48px,9vw,88px)}.presentation-root.js .prose{font-size:clamp(22px,4vw,40px)}.presentation-root.js .layout-code-left .panes,.presentation-root.js .layout-code-right .panes,.presentation-root.js .layout-split-code .panes{grid-template-columns:1fr;gap:40px}}}@supports (width:1cqw) and (height:1cqh) and (transform:scale(tan(atan2(1px, 1px)))){.presentation-root.js.is-overview .slide-deck,.presentation-root.js[data-overview-active=true] .slide-deck{grid-template-columns:repeat(auto-fit,minmax(min(360px,42vw),1fr));grid-auto-rows:max-content;align-content:start;align-items:start;gap:32px;padding:112px 48px 56px;display:grid;overflow:auto}.presentation-root.js.is-overview .slide,.presentation-root.js[data-overview-active=true] .slide{aspect-ratio:16/9;visibility:visible;border:2px solid var(--slide-code-border);width:100%;min-width:0;height:auto;box-shadow:0 12px 28px var(--slide-code-shadow);cursor:pointer;border-radius:16px;margin:0;position:relative;inset:auto;overflow:hidden;transform:none;container-type:inline-size}.presentation-root.js.is-overview .slide.is-active,.presentation-root.js[data-overview-active=true] .slide.is-active{border-color:var(--slide-accent);box-shadow:0 0 0 4px var(--slide-highlight), 0 12px 28px var(--slide-code-shadow)}.presentation-root.js.is-overview .slide-content,.presentation-root.js[data-overview-active=true] .slide-content{--overview-slide-scale:tan(atan2(100cqw, 1920px));width:1920px;height:1080px;transform:scale(var(--overview-slide-scale,1));transform-origin:0 0;padding:108px 132px 100px}.presentation-root.js.is-overview .slide:focus-visible,.presentation-root.js[data-overview-active=true] .slide:focus-visible{outline:5px solid var(--slide-focus);outline-offset:6px}}@supports (transform:scale(abs(-1))){.presentation-root.js.is-overview .slide-content,.presentation-root.js[data-overview-active=true] .slide-content{--overview-slide-scale:abs(tan(atan2(100cqw, 1920px)))}}.code-window,.terminal-window{--slide-window-bar:72px;border:2px solid var(--slide-code-border);min-width:0;min-height:0;max-height:100%;position:relative;overflow:hidden}@supports (color:color-mix(in lab, red, red)){.code-window,.terminal-window{border:2px solid color-mix(in srgb, var(--slide-code-border), transparent 15%)}}.code-window,.terminal-window{border-radius:var(--slide-radius);background:var(--slide-code-surface);box-shadow:0 24px 60px var(--slide-code-shadow), inset 0 1px 0 var(--slide-code-inset);font-family:var(--font-slide-mono);font-size:var(--slide-code-font-size);font-variant-ligatures:none;flex-direction:column;font-weight:450;line-height:1.45;display:flex}.code-window figcaption,.terminal-window figcaption{z-index:2;max-width:min(50%,max(0px,100% - 224px));height:var(--slide-window-bar);color:var(--slide-muted);font-family:var(--font-slide-sans);letter-spacing:.015em;font-size:28px;font-weight:500;line-height:var(--slide-window-bar);text-overflow:ellipsis;white-space:nowrap;position:absolute;top:0;left:50%;overflow:hidden;transform:translate(-50%)}.code-window-header{height:var(--slide-window-bar);flex:0 0 var(--slide-window-bar);border-bottom:2px solid var(--slide-code-border);background:linear-gradient(var(--slide-surface-shine), transparent 62%), var(--slide-code-header);align-items:center;padding:0 28px;display:flex}.code-window-controls{gap:calc(var(--slide-window-bar) * .19);display:flex}.code-window-controls i{width:calc(var(--slide-window-bar) * .3);height:calc(var(--slide-window-bar) * .3);box-shadow:inset 0 0 0 1px var(--slide-dot-rim), inset 0 calc(var(--slide-window-bar) * .04) calc(var(--slide-window-bar) * .05) var(--slide-dot-gloss);border-radius:50%;display:block}.code-window-controls i:first-child{background:var(--slide-dot-close)}.code-window-controls i:nth-child(2){background:var(--slide-dot-minimize)}.code-window-controls i:last-child{background:var(--slide-dot-maximize)}.code-window-language{max-width:max(0px,25% - 40px);color:var(--slide-muted);letter-spacing:.04em;text-overflow:ellipsis;text-transform:uppercase;white-space:nowrap;margin-inline-start:auto;font-size:24px;overflow:hidden}.code-window pre,.terminal-window pre{tab-size:2;scrollbar-width:thin;scrollbar-color:var(--slide-muted) transparent;min-height:0;margin:0;padding:32px 34px 36px;font-family:inherit;overflow:auto}.code-window code,.terminal-window code{color:var(--slide-fg);font:inherit;display:block}.code-window .line{white-space:pre;border-inline-start:4px solid #0000;min-height:1.45em;padding-inline:16px 20px;display:block}.code-window .line:before{content:attr(data-line-number);width:2.2em;color:var(--slide-muted);text-align:end;-webkit-user-select:none;user-select:none;margin-inline-end:.8em;font-size:.8em;display:inline-block}.code-window .line:not([data-line-number]):before{content:none}.code-window .line.is-highlighted{border-inline-start-color:var(--slide-code-highlight-border);background:var(--slide-code-highlight-surface)}.code-window.has-focus .line.is-focused{border-inline-start-color:var(--slide-focus);background:var(--slide-code-focus-surface);opacity:1}.code-window .hll,.code-window .highlight{background:var(--slide-code-highlight-surface)}.code-window .c,.code-window .ch,.code-window .cm,.code-window .c1,.code-window .cs{color:var(--slide-syntax-comment)}.code-window .k,.code-window .kd,.code-window .kn,.code-window .kp,.code-window .kr,.code-window .kt{color:var(--slide-syntax-keyword)}.code-window .s,.code-window .sa,.code-window .sb,.code-window .sc,.code-window .dl,.code-window .sd,.code-window .s1,.code-window .s2{color:var(--slide-syntax-string)}.code-window .m,.code-window .mb,.code-window .mf,.code-window .mh,.code-window .mi,.code-window .mo{color:var(--slide-syntax-number)}.code-window .nf,.code-window .fm,.code-window .nd{color:var(--slide-syntax-function)}:is(.highlighter-rouge,figure.highlight) .c,:is(.highlighter-rouge,figure.highlight) .ch,:is(.highlighter-rouge,figure.highlight) .cm,:is(.highlighter-rouge,figure.highlight) .c1,:is(.highlighter-rouge,figure.highlight) .cs{color:var(--slide-syntax-comment)}:is(.highlighter-rouge,figure.highlight) .k,:is(.highlighter-rouge,figure.highlight) .kd,:is(.highlighter-rouge,figure.highlight) .kn,:is(.highlighter-rouge,figure.highlight) .kp,:is(.highlighter-rouge,figure.highlight) .kr,:is(.highlighter-rouge,figure.highlight) .kt{color:var(--slide-syntax-keyword)}:is(.highlighter-rouge,figure.highlight) .s,:is(.highlighter-rouge,figure.highlight) .sa,:is(.highlighter-rouge,figure.highlight) .sb,:is(.highlighter-rouge,figure.highlight) .sc,:is(.highlighter-rouge,figure.highlight) .dl,:is(.highlighter-rouge,figure.highlight) .sd,:is(.highlighter-rouge,figure.highlight) .s1,:is(.highlighter-rouge,figure.highlight) .s2{color:var(--slide-syntax-string)}:is(.highlighter-rouge,figure.highlight) .m,:is(.highlighter-rouge,figure.highlight) .mb,:is(.highlighter-rouge,figure.highlight) .mf,:is(.highlighter-rouge,figure.highlight) .mh,:is(.highlighter-rouge,figure.highlight) .mi,:is(.highlighter-rouge,figure.highlight) .mo{color:var(--slide-syntax-number)}:is(.highlighter-rouge,figure.highlight) .nf,:is(.highlighter-rouge,figure.highlight) .fm,:is(.highlighter-rouge,figure.highlight) .nd{color:var(--slide-syntax-function)}.code-window .o,.code-window .ow,:is(.highlighter-rouge,figure.highlight) .o,:is(.highlighter-rouge,figure.highlight) .ow{color:var(--slide-syntax-operator)}.code-window .p,:is(.highlighter-rouge,figure.highlight) .p{color:var(--slide-syntax-punctuation)}.code-window .n,.code-window .na,.code-window .nv,.code-window .vc,.code-window .vg,.code-window .vi,.code-window .py,:is(.highlighter-rouge,figure.highlight) .n,:is(.highlighter-rouge,figure.highlight) .na,:is(.highlighter-rouge,figure.highlight) .nv,:is(.highlighter-rouge,figure.highlight) .vc,:is(.highlighter-rouge,figure.highlight) .vg,:is(.highlighter-rouge,figure.highlight) .vi,:is(.highlighter-rouge,figure.highlight) .py{color:var(--slide-syntax-name)}.code-window .nv,.code-window .vc,.code-window .vg,.code-window .vi,:is(.highlighter-rouge,figure.highlight) .nv,:is(.highlighter-rouge,figure.highlight) .vc,:is(.highlighter-rouge,figure.highlight) .vg,:is(.highlighter-rouge,figure.highlight) .vi{color:var(--slide-syntax-variable)}.code-window .x,.code-window .sx,.code-window .ni,.code-window .nl,.code-window .nt,:is(.highlighter-rouge,figure.highlight) .x,:is(.highlighter-rouge,figure.highlight) .sx,:is(.highlighter-rouge,figure.highlight) .ni,:is(.highlighter-rouge,figure.highlight) .nl,:is(.highlighter-rouge,figure.highlight) .nt,.code-window .ss,.code-window .sh,.code-window .si,.code-window .sr,:is(.highlighter-rouge,figure.highlight) .ss,:is(.highlighter-rouge,figure.highlight) .sh,:is(.highlighter-rouge,figure.highlight) .si,:is(.highlighter-rouge,figure.highlight) .sr{color:var(--slide-syntax-symbol)}.code-window .kv,.code-window .kc,.code-window .cp,.code-window .cd,.code-window .pi,:is(.highlighter-rouge,figure.highlight) .kv,:is(.highlighter-rouge,figure.highlight) .kc,:is(.highlighter-rouge,figure.highlight) .cp,:is(.highlighter-rouge,figure.highlight) .cd,:is(.highlighter-rouge,figure.highlight) .pi{color:var(--slide-syntax-keyword)}.code-window .il,:is(.highlighter-rouge,figure.highlight) .il{color:var(--slide-syntax-number)}.code-window .nb,.code-window .bp,:is(.highlighter-rouge,figure.highlight) .nb,:is(.highlighter-rouge,figure.highlight) .bp{color:var(--slide-syntax-builtin)}.code-window .nc,.code-window .no,.code-window .ne,.code-window .nn,.code-window .nx,:is(.highlighter-rouge,figure.highlight) .nc,:is(.highlighter-rouge,figure.highlight) .no,:is(.highlighter-rouge,figure.highlight) .ne,:is(.highlighter-rouge,figure.highlight) .nn,:is(.highlighter-rouge,figure.highlight) .nx{color:var(--slide-syntax-constant)}.code-window .err,:is(.highlighter-rouge,figure.highlight) .err{color:var(--slide-syntax-error);-webkit-text-decoration:wavy underline var(--slide-syntax-error);-webkit-text-decoration:wavy underline var(--slide-syntax-error);text-decoration:wavy underline var(--slide-syntax-error);text-underline-offset:4px}.highlighter-rouge,figure.highlight{min-width:0;font-family:var(--font-slide-mono)}.highlighter-rouge .highlight,figure.highlight{border:1px solid var(--slide-code-border);background:var(--slide-code-surface);box-shadow:inset 0 1px 0 var(--slide-code-inset);font-size:var(--slide-code-font-size);font-variant-ligatures:none;scrollbar-width:thin;scrollbar-color:var(--slide-muted) transparent;border-radius:16px;font-weight:450;line-height:1.45;overflow:auto}.highlighter-rouge pre,figure.highlight pre{margin:0;padding:28px 32px}.highlighter-rouge code,figure.highlight code{color:var(--slide-fg);font:inherit}.code-window.size-sm,.terminal-window.size-sm{--slide-window-bar:62px;font-size:32px}.code-window.size-md,.terminal-window.size-md{--slide-window-bar:72px;font-size:38px}.code-window.size-lg,.terminal-window.size-lg{--slide-window-bar:82px;font-size:42px}.terminal-window{background:var(--slide-code-surface)}.terminal-window pre{padding-top:28px}.terminal-window .tline{white-space:pre-wrap;min-height:1.45em;display:block}.terminal-window .prompt{color:var(--slide-accent-strong);font-weight:700}.terminal-window .cmd{color:var(--slide-link)}.terminal-window .tline:not(:has(.prompt)):not(:has(.cmd)){color:var(--slide-fg)}.presentation-chrome{z-index:20;color:var(--slide-muted);pointer-events:none;position:fixed;inset:0}.presentation-root:not(.js) .presentation-chrome{visibility:hidden;pointer-events:none}.slide-controls{pointer-events:auto;background:0 0;border:1px solid #0000;border-radius:12px;align-items:center;gap:8px;padding:8px;transition:background .2s,border-color .2s;display:flex;position:absolute;bottom:16px;right:24px}.slide-controls:hover,.slide-controls:focus-within{border-color:var(--slide-code-border);background:var(--slide-bg)}@supports (color:color-mix(in lab, red, red)){.slide-controls:hover,.slide-controls:focus-within{background:color-mix(in srgb, var(--slide-bg), transparent 12%)}}.slide-controls:hover,.slide-controls:focus-within{-webkit-backdrop-filter:blur(18px);backdrop-filter:blur(18px)}.slide-control{border:1px solid var(--slide-code-border);width:46px;height:38px;color:var(--slide-fg);cursor:pointer;font:inherit;opacity:0;pointer-events:none;background:0 0;border-radius:9px;place-items:center;line-height:1;transition:background .2s,color .2s,border-color .2s,opacity .2s,transform .2s;display:inline-grid;transform:translateY(4px)}.slide-controls:hover .slide-control,.slide-controls:focus-within .slide-control{opacity:1;pointer-events:auto;transform:none}.slide-control:hover{border-color:var(--slide-accent);background:var(--slide-highlight);color:var(--slide-accent-strong)}.slide-controls:hover .slide-control:disabled,.slide-controls:focus-within .slide-control:disabled{opacity:.35;cursor:default}.slide-counter{font-family:var(--font-slide-mono);letter-spacing:.04em;margin:0;font-size:17px}.slide-progress{width:100%;height:4px;accent-color:var(--slide-accent);opacity:.58;pointer-events:auto;position:absolute;bottom:0;left:0;right:0}.slide-progress::-webkit-progress-bar{background:var(--slide-code-border);border-radius:99px}.slide-progress::-webkit-progress-value{background:var(--slide-accent);border-radius:99px}.overview-hint{z-index:25;border:1px solid var(--slide-code-border);background:var(--slide-code-surface);color:var(--slide-muted);font-family:var(--font-slide-mono);border-radius:999px;margin:0;padding:10px 18px;font-size:14px;position:fixed;top:82px;left:50%;transform:translate(-50%)}.overview-hint[hidden]{display:none}.presentation-root.js.is-fullscreen .presentation-chrome,.presentation-root.js[data-fullscreen-active=true] .presentation-chrome{opacity:0;transition:opacity .35s}.presentation-root.js.is-fullscreen .presentation-chrome:hover,.presentation-root.js.is-fullscreen .presentation-chrome:focus-within,.presentation-root.js[data-fullscreen-active=true] .presentation-chrome:hover,.presentation-root.js[data-fullscreen-active=true] .presentation-chrome:focus-within{opacity:1}.slide-control:focus-visible,.slide-progress:focus-visible{outline:4px solid var(--slide-focus);outline-offset:4px}@media (prefers-reduced-motion:reduce){*,:before,:after{scroll-behavior:auto!important;transition-duration:0s!important;animation-duration:0s!important;animation-iteration-count:1!important}}.presentation-root.is-reduced-motion .presentation-chrome,.presentation-root[data-reduced-motion=true] .presentation-chrome{transition:none}@page{size:13.333in 7.5in;margin:0}@media print{*,:before,:after{transition:none!important;animation:none!important}html,body{width:13.333in;min-width:13.333in;background:var(--slide-bg)!important}body{-webkit-print-color-adjust:exact;print-color-adjust:exact}.presentation-root,.presentation-root.js{width:13.333in!important;height:auto!important;min-height:0!important;overflow:visible!important}.presentation-chrome,.slide-progress,.overview-hint{display:none!important}.slide-deck,.presentation-root.js .slide-deck,.presentation-root.js.is-overview .slide-deck{width:13.333in!important;height:auto!important;min-height:0!important;padding:0!important;display:block!important;position:static!important;overflow:visible!important}.slide,.presentation-root.js .slide,.presentation-root.js.is-overview .slide{break-after:page;page-break-after:always;min-height:0;visibility:visible!important;width:13.333in!important;height:7.5in!important;box-shadow:none!important;cursor:default!important;border:0!important;border-radius:0!important;margin:0!important;display:block!important;position:relative!important;inset:auto!important;overflow:hidden!important;transform:none!important}.slide:last-child{break-after:auto;page-break-after:auto}.slide-content,.presentation-root.js.is-overview .slide-content{transform-origin:0 0;width:1920px!important;height:1080px!important;transform:scale(.66665)!important}.code-window .line,.terminal-window .tline{opacity:1!important}}
|
data/doc/CHANGELOG.md
CHANGED
|
@@ -2,8 +2,21 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to Jekyll Slides are documented here.
|
|
4
4
|
|
|
5
|
-
##
|
|
5
|
+
## 0.3.0 — 2026-09-10
|
|
6
6
|
|
|
7
|
+
- Add the four Catppuccin flavors as presentation themes: `catppuccin-latte`, `catppuccin-frappe`, `catppuccin-macchiato`, and `catppuccin-mocha`, ported from the palette shared by [catppuccin/ghostty](https://github.com/catppuccin/ghostty). Hues are the published values; lightness is adjusted only where a token cannot otherwise clear the 4.5:1 contrast checked on every code surface.
|
|
8
|
+
- Add a `theme` attribute to editor and terminal blocks, so one window can carry any theme while the deck around it keeps its own. The override repaints that window's surface, title bar, syntax colors, prompt, and body text. An unknown name warns and falls back to the deck theme.
|
|
9
|
+
- Give terminal windows a real title bar. It was previously an empty `::before` bar that could hold neither the window controls nor the title, which floated above it.
|
|
10
|
+
- Center editor and terminal titles inside the title bar, and size the controls and bar with the component `size`.
|
|
11
|
+
- Use the macOS traffic-light colors for the window controls in every theme, the way a real title bar does; only the window surface follows the theme. Themes no longer set `--slide-dot-close`, `--slide-dot-minimize`, or `--slide-dot-maximize`.
|
|
12
|
+
- Rename the generated LLM index from `llm.txt` to `llms.txt`, matching the llmstxt.org convention used across these plugins.
|
|
13
|
+
|
|
14
|
+
## 0.2.0 — 2026-09-06
|
|
15
|
+
|
|
16
|
+
- Add folder decks: author a presentation as one Markdown file per slide, ordered by a numeric filename prefix and alphabetically otherwise, opted into with `slides:` in the entry file's front matter.
|
|
17
|
+
- Add slide file front matter (`layout`, `background`, `class`) as an alternative to the `<!-- ... -->` metadata comment.
|
|
18
|
+
- Fix slides rendering upside down in Safari: the CSS length-division trick used to scale slides to the viewport made Safari compute a negative scale factor, which is a 180 degree rotation.
|
|
19
|
+
- Fix `slides_count` for decks whose slides are generated by Liquid, which previously reported the pre-Liquid slide count.
|
|
7
20
|
- Add `bin/prepare_release` to verify the gem, regenerate Markdown API documentation and `llm.txt`, and build a versioned package with a SHA-256 checksum.
|
|
8
21
|
- Ship generated documentation while keeping YARD and release tools development-only.
|
|
9
22
|
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# Class Jekyll::Slides::Deck <a id="class-Jekyll-Slides-Deck"></a>
|
|
2
|
+
|
|
3
|
+
| | |
|
|
4
|
+
| --- | --- |
|
|
5
|
+
| **Inherits** | Object |
|
|
6
|
+
| **Defined in** | lib/jekyll/slides/deck.rb |
|
|
7
|
+
|
|
8
|
+
Represents one folder deck: an entry file plus the slide files a directory
|
|
9
|
+
holds. Reads slide files from disk and assembles them, with the entry body,
|
|
10
|
+
into one Markdown string ready for the existing `PresentationParser` pipeline.
|
|
11
|
+
Knows nothing about Jekyll page objects.
|
|
12
|
+
|
|
13
|
+
## Constants
|
|
14
|
+
### `OPTION_KEYS` <a id="constant-OPTION_KEYS"></a> <a id="OPTION_KEYS-constant"></a>
|
|
15
|
+
Top-level presentation options an author might mistakenly nest under
|
|
16
|
+
<code>slides:</code> instead of setting directly in front matter.
|
|
17
|
+
|
|
18
|
+
## Public Instance Methods
|
|
19
|
+
### `consumed_paths()` <a id="method-i-consumed_paths"></a> <a id="consumed_paths-instance_method"></a>
|
|
20
|
+
Every slide file the deck folder absorbs, so none is published on its own:
|
|
21
|
+
every discovered direct child, plus any explicitly listed path (which may live
|
|
22
|
+
in a subfolder). Order is not meaningful; this is a set for pruning, not the
|
|
23
|
+
render order. Identical to `slide_paths` when <code>slides:</code> is `true`.
|
|
24
|
+
|
|
25
|
+
### `content()` <a id="method-i-content"></a> <a id="content-instance_method"></a>
|
|
26
|
+
Not documented.
|
|
27
|
+
|
|
28
|
+
### `deck?()` <a id="method-i-deck-3F"></a> <a id="deck?-instance_method"></a>
|
|
29
|
+
rubocop:enable Metrics/ParameterLists
|
|
30
|
+
- **@return** [Boolean]
|
|
31
|
+
|
|
32
|
+
### `initialize(directory:, entry_path:, entry_body:, slides:, markdown_extensions:, warning: = nil, read_options: = {}, published: = nil)` <a id="method-i-initialize"></a> <a id="initialize-instance_method"></a>
|
|
33
|
+
rubocop:disable Metrics/ParameterLists -- this exact keyword set is the deck's
|
|
34
|
+
public construction contract; the Jekyll integration layer wires it verbatim.
|
|
35
|
+
- **@return** [Deck] a new instance of Deck
|
|
36
|
+
|
|
37
|
+
### `slide_paths()` <a id="method-i-slide_paths"></a> <a id="slide_paths-instance_method"></a>
|
|
38
|
+
The ordered slide file paths that make up `content`: the explicit list in list
|
|
39
|
+
order when <code>slides:</code> names one, otherwise every discovered file in
|
|
40
|
+
natural order.
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# Module Jekyll::Slides::DeckAssembler <a id="module-Jekyll-Slides-DeckAssembler"></a>
|
|
2
|
+
|
|
3
|
+
| | |
|
|
4
|
+
| --- | --- |
|
|
5
|
+
| **Defined in** | lib/jekyll/slides/deck_assembler.rb |
|
|
6
|
+
|
|
7
|
+
Finds folder-deck entries across a site's pages and output-collection
|
|
8
|
+
documents, assembles each into one Markdown string via `Deck`, and prunes the
|
|
9
|
+
slide files it consumed so they never appear in the built site. Runs once per
|
|
10
|
+
site, inside the +:site, :post_read+ hook, before Liquid rendering and before
|
|
11
|
+
<code>JekyllIntegration.process</code> computes `slides_count`.
|
|
12
|
+
|
|
13
|
+
## Public Class Methods
|
|
14
|
+
### `assemble(site)` <a id="method-c-assemble"></a> <a id="assemble-class_method"></a>
|
|
15
|
+
Assembles every folder deck the site's pages and output-collection documents
|
|
16
|
+
opt into. Mutates <code>site.pages</code>, each collection's `docs`, and
|
|
17
|
+
<code>site.static_files</code> in place to remove consumed slide files.
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# Module Jekyll::Slides::FrontMatter <a id="module-Jekyll-Slides-FrontMatter"></a>
|
|
2
|
+
|
|
3
|
+
| | |
|
|
4
|
+
| --- | --- |
|
|
5
|
+
| **Defined in** | lib/jekyll/slides/front_matter.rb |
|
|
6
|
+
|
|
7
|
+
Splits a leading YAML front matter block off a Markdown source string.
|
|
8
|
+
|
|
9
|
+
## Public Class Methods
|
|
10
|
+
### `parse(text)` <a id="method-c-parse"></a> <a id="parse-class_method"></a>
|
|
11
|
+
Not documented.
|
|
12
|
+
|
|
13
|
+
### `split(source)` <a id="method-c-split"></a> <a id="split-class_method"></a>
|
|
14
|
+
Returns [values, body]. `values` is a Hash for a well-formed leading
|
|
15
|
+
<code>---</code> block; otherwise `values` is {} and `body` is `source`
|
|
16
|
+
unchanged.
|
|
@@ -14,9 +14,6 @@ Not documented.
|
|
|
14
14
|
### `OPTION_KEYS` <a id="constant-OPTION_KEYS"></a> <a id="OPTION_KEYS-constant"></a>
|
|
15
15
|
Not documented.
|
|
16
16
|
|
|
17
|
-
### `THEMES` <a id="constant-THEMES"></a> <a id="THEMES-constant"></a>
|
|
18
|
-
Not documented.
|
|
19
|
-
|
|
20
17
|
## Public Class Methods
|
|
21
18
|
### `install!()` <a id="method-c-install-21"></a> <a id="install!-class_method"></a>
|
|
22
19
|
Not documented.
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# Class Jekyll::Slides::SlideFile <a id="class-Jekyll-Slides-SlideFile"></a>
|
|
2
|
+
|
|
3
|
+
| | |
|
|
4
|
+
| --- | --- |
|
|
5
|
+
| **Inherits** | Object |
|
|
6
|
+
| **Defined in** | lib/jekyll/slides/slide_file.rb |
|
|
7
|
+
|
|
8
|
+
Reads one Markdown file and returns its slide sources. The file's own front
|
|
9
|
+
matter (`layout`, `background`, `class`) becomes a default metadata comment
|
|
10
|
+
applied to every slide the file contains; a slide's own comment wins key by
|
|
11
|
+
key.
|
|
12
|
+
|
|
13
|
+
## Public Instance Methods
|
|
14
|
+
### `initialize(path, warning: = nil, read_options: = {})` <a id="method-i-initialize"></a> <a id="initialize-instance_method"></a>
|
|
15
|
+
- **@return** [SlideFile] a new instance of SlideFile
|
|
16
|
+
|
|
17
|
+
### `slides()` <a id="method-i-slides"></a> <a id="slides-instance_method"></a>
|
|
18
|
+
Not documented.
|
|
@@ -35,6 +35,12 @@ Returns the value of attribute values.
|
|
|
35
35
|
### `parse(content, index: = 0, warning: = nil, components: = nil)` <a id="method-c-parse"></a> <a id="parse-class_method"></a>
|
|
36
36
|
Not documented.
|
|
37
37
|
|
|
38
|
+
### `split_comment(body, warning: = nil)` <a id="method-c-split_comment"></a> <a id="split_comment-class_method"></a>
|
|
39
|
+
Parses a leading "<!-- key: value -->" metadata comment off `body`. Returns
|
|
40
|
+
[body_without_comment, values]. A comment whose lines are not all "key:
|
|
41
|
+
value", or that carries no recognized key, is left in the body untouched.
|
|
42
|
+
Unknown keys warn only when `warning` is given.
|
|
43
|
+
|
|
38
44
|
## Public Instance Methods
|
|
39
45
|
### `initialize(content, index: = 0, warning: = nil)` <a id="method-i-initialize"></a> <a id="initialize-instance_method"></a>
|
|
40
46
|
- **@return** [SlideMetadata] a new instance of SlideMetadata
|
|
@@ -8,5 +8,11 @@
|
|
|
8
8
|
### `escape(value)` <a id="method-c-escape"></a> <a id="escape-class_method"></a>
|
|
9
9
|
Not documented.
|
|
10
10
|
|
|
11
|
+
### `natural_sort_key(name)` <a id="method-c-natural_sort_key"></a> <a id="natural_sort_key-class_method"></a>
|
|
12
|
+
A comparable Array key for natural filename ordering: digit runs compare
|
|
13
|
+
numerically, text runs compare case-insensitively, and digit runs sort before
|
|
14
|
+
text runs. The name itself is appended as a stable tiebreaker so equal-value
|
|
15
|
+
keys (e.g. "01-a" and "1-a") still order deterministically.
|
|
16
|
+
|
|
11
17
|
### `warn(warning, message)` <a id="method-c-warn"></a> <a id="warn-class_method"></a>
|
|
12
18
|
Not documented.
|
data/doc/Jekyll/Slides.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
| | |
|
|
4
4
|
| --- | --- |
|
|
5
|
-
| **Defined in** | lib/jekyll/slides.rb, lib/jekyll/slides/assets.rb, lib/jekyll/slides/layout.rb, lib/jekyll/slides/support.rb, lib/jekyll/slides/version.rb, lib/jekyll/slides/renderer.rb, lib/jekyll/slides/presentation.rb, lib/jekyll/slides/range_parser.rb, lib/jekyll/slides/rouge_renderer.rb, lib/jekyll/slides/slide_metadata.rb, lib/jekyll/slides/slide_renderer.rb, lib/jekyll/slides/component_renderer.rb, lib/jekyll/slides/jekyll_integration.rb, lib/jekyll/slides/presentation_parser.rb |
|
|
5
|
+
| **Defined in** | lib/jekyll/slides.rb, lib/jekyll/slides/deck.rb, lib/jekyll/slides/assets.rb, lib/jekyll/slides/layout.rb, lib/jekyll/slides/support.rb, lib/jekyll/slides/version.rb, lib/jekyll/slides/renderer.rb, lib/jekyll/slides/slide_file.rb, lib/jekyll/slides/front_matter.rb, lib/jekyll/slides/presentation.rb, lib/jekyll/slides/range_parser.rb, lib/jekyll/slides/deck_assembler.rb, lib/jekyll/slides/rouge_renderer.rb, lib/jekyll/slides/slide_metadata.rb, lib/jekyll/slides/slide_renderer.rb, lib/jekyll/slides/component_renderer.rb, lib/jekyll/slides/jekyll_integration.rb, lib/jekyll/slides/presentation_parser.rb |
|
|
6
6
|
|
|
7
7
|
Markdown presentations for Jekyll, with editor and terminal components.
|
|
8
8
|
|
|
@@ -13,9 +13,8 @@ includes, styles, scripts, and offline fonts while preserving the site's theme
|
|
|
13
13
|
and local overrides.
|
|
14
14
|
|
|
15
15
|
Configure defaults under <code>slides:</code> in _config.yml, or use front
|
|
16
|
-
matter on individual decks.
|
|
17
|
-
|
|
18
|
-
quote this value in YAML.
|
|
16
|
+
matter on individual decks. The supported aspect ratio is 16:9; quote this
|
|
17
|
+
value in YAML.
|
|
19
18
|
|
|
20
19
|
Jekyll runs Liquid before rendering each slide as one Markdown document.
|
|
21
20
|
Jekyll::Slides::Presentation also renders slide HTML directly when Jekyll
|
|
@@ -23,12 +22,20 @@ integration is not needed; it does not evaluate Liquid or wrap the
|
|
|
23
22
|
presentation layout.
|
|
24
23
|
|
|
25
24
|
## Constants
|
|
25
|
+
### `DEFAULT_THEME` <a id="constant-DEFAULT_THEME"></a> <a id="DEFAULT_THEME-constant"></a>
|
|
26
|
+
Not documented.
|
|
27
|
+
|
|
26
28
|
### `LAYOUT_NAME` <a id="constant-LAYOUT_NAME"></a> <a id="LAYOUT_NAME-constant"></a>
|
|
27
29
|
Not documented.
|
|
28
30
|
|
|
29
31
|
### `ROOT` <a id="constant-ROOT"></a> <a id="ROOT-constant"></a>
|
|
30
32
|
Not documented.
|
|
31
33
|
|
|
34
|
+
### `THEMES` <a id="constant-THEMES"></a> <a id="THEMES-constant"></a>
|
|
35
|
+
Every theme name the plugin ships. A theme sets the whole deck through front
|
|
36
|
+
matter, and any one of them also restyles a single editor or terminal block
|
|
37
|
+
through that block's `theme` attribute.
|
|
38
|
+
|
|
32
39
|
### `VERSION` <a id="constant-VERSION"></a> <a id="VERSION-constant"></a>
|
|
33
40
|
Not documented.
|
|
34
41
|
|
|
@@ -38,6 +45,9 @@ Not documented.
|
|
|
38
45
|
- [Slides/Assets.md](Slides/Assets.md)
|
|
39
46
|
- [Slides/ComponentRenderer/RenderedDocument.md](Slides/ComponentRenderer/RenderedDocument.md)
|
|
40
47
|
- [Slides/ComponentRenderer.md](Slides/ComponentRenderer.md)
|
|
48
|
+
- [Slides/Deck.md](Slides/Deck.md)
|
|
49
|
+
- [Slides/DeckAssembler.md](Slides/DeckAssembler.md)
|
|
50
|
+
- [Slides/FrontMatter.md](Slides/FrontMatter.md)
|
|
41
51
|
- [Slides/JekyllIntegration.md](Slides/JekyllIntegration.md)
|
|
42
52
|
- [Slides/Layout.md](Slides/Layout.md)
|
|
43
53
|
- [Slides/Presentation.md](Slides/Presentation.md)
|
|
@@ -45,6 +55,7 @@ Not documented.
|
|
|
45
55
|
- [Slides/RangeParser.md](Slides/RangeParser.md)
|
|
46
56
|
- [Slides/Renderer.md](Slides/Renderer.md)
|
|
47
57
|
- [Slides/RougeRenderer.md](Slides/RougeRenderer.md)
|
|
58
|
+
- [Slides/SlideFile.md](Slides/SlideFile.md)
|
|
48
59
|
- [Slides/SlideMetadata.md](Slides/SlideMetadata.md)
|
|
49
60
|
- [Slides/SlideRenderer.md](Slides/SlideRenderer.md)
|
|
50
61
|
- [Slides/Support.md](Slides/Support.md)
|
data/doc/Jekyll.md
CHANGED
|
@@ -2,4 +2,4 @@
|
|
|
2
2
|
|
|
3
3
|
| | |
|
|
4
4
|
| --- | --- |
|
|
5
|
-
| **Defined in** | lib/jekyll/slides.rb, lib/jekyll/slides/assets.rb, lib/jekyll/slides/layout.rb, lib/jekyll/slides/support.rb, lib/jekyll/slides/version.rb, lib/jekyll/slides/renderer.rb, lib/jekyll/slides/presentation.rb, lib/jekyll/slides/range_parser.rb, lib/jekyll/slides/rouge_renderer.rb, lib/jekyll/slides/slide_metadata.rb, lib/jekyll/slides/slide_renderer.rb, lib/jekyll/slides/component_renderer.rb, lib/jekyll/slides/jekyll_integration.rb, lib/jekyll/slides/presentation_parser.rb |
|
|
5
|
+
| **Defined in** | lib/jekyll/slides.rb, lib/jekyll/slides/deck.rb, lib/jekyll/slides/assets.rb, lib/jekyll/slides/layout.rb, lib/jekyll/slides/support.rb, lib/jekyll/slides/version.rb, lib/jekyll/slides/renderer.rb, lib/jekyll/slides/slide_file.rb, lib/jekyll/slides/front_matter.rb, lib/jekyll/slides/presentation.rb, lib/jekyll/slides/range_parser.rb, lib/jekyll/slides/deck_assembler.rb, lib/jekyll/slides/rouge_renderer.rb, lib/jekyll/slides/slide_metadata.rb, lib/jekyll/slides/slide_renderer.rb, lib/jekyll/slides/component_renderer.rb, lib/jekyll/slides/jekyll_integration.rb, lib/jekyll/slides/presentation_parser.rb |
|