accessible-marp-decks 2.0.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.
- package/CHANGELOG.md +52 -0
- package/LICENSE +15 -0
- package/NOTICE +21 -0
- package/README.md +181 -0
- package/package.json +68 -0
- package/src/cli.js +247 -0
- package/src/core/escape.js +16 -0
- package/src/core/marpit.js +29 -0
- package/src/core/render.js +87 -0
- package/src/core/runtime-script.js +99 -0
- package/src/core/template.js +36 -0
- package/src/core/themes.js +56 -0
- package/src/core/transforms/_code.js +15 -0
- package/src/core/transforms/_img.js +98 -0
- package/src/core/transforms/_section.js +59 -0
- package/src/core/transforms/index.js +23 -0
- package/src/eleventy.js +53 -0
- package/src/index.js +19 -0
- package/themes/_template.css +249 -0
- package/themes/basic.css +316 -0
- package/themes/document.css +68 -0
- package/themes/high-contrast.css +237 -0
|
@@ -0,0 +1,249 @@
|
|
|
1
|
+
/* @theme template */
|
|
2
|
+
/*!
|
|
3
|
+
* @auto-scaling true
|
|
4
|
+
* @size 16:9 1280px 720px
|
|
5
|
+
* @size 4:3 960px 720px
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
/* ===========================================================================
|
|
9
|
+
* THEME TEMPLATE — copy this file to themes/<your-theme>.css to make your own.
|
|
10
|
+
*
|
|
11
|
+
* 1. Rename the theme in the `@theme` line above (line 1) to match the file.
|
|
12
|
+
* 2. Recolour: edit the two colour blocks in EDIT ZONE 1 below. That's the
|
|
13
|
+
* only part most themes need to touch.
|
|
14
|
+
* 3. Optionally tweak type in EDIT ZONE 2.
|
|
15
|
+
* 4. Style elements as you like further down — headings, code, tables, etc.
|
|
16
|
+
*
|
|
17
|
+
* The layout helpers (box, stack, columns, grid, frame, …) are included below so
|
|
18
|
+
* they show up in the Marp VSCode preview too. They are plain grid/flex CSS —
|
|
19
|
+
* leave them as-is unless you want to restyle a layout.
|
|
20
|
+
*
|
|
21
|
+
* The responsive 16:9 scaling comes from the always-injected document.css, so
|
|
22
|
+
* there is nothing to set up for that. Everything inside a slide is sized in
|
|
23
|
+
* `em` so it scales with the window — keep new rules in `em`/`%` to preserve it.
|
|
24
|
+
* ======================================================================== */
|
|
25
|
+
|
|
26
|
+
/* --- EDIT ZONE 1: COLOURS ------------------------------------------------- */
|
|
27
|
+
:root {
|
|
28
|
+
/* Light mode (default) */
|
|
29
|
+
--bg: #ffffff;
|
|
30
|
+
--fg: #1a1a1a;
|
|
31
|
+
--muted: #565656;
|
|
32
|
+
--accent: #0b5cad;
|
|
33
|
+
--border: #b1b4b6;
|
|
34
|
+
--code-bg: #f3f4f6;
|
|
35
|
+
--chip-bg: #eaeaea;
|
|
36
|
+
--focus-bg: #ffdd00;
|
|
37
|
+
--focus-fg: #1a1a1a;
|
|
38
|
+
|
|
39
|
+
/* Syntax highlighting (a11y-light) */
|
|
40
|
+
--hl-bg: #fefefe;
|
|
41
|
+
--hl-fg: #545454;
|
|
42
|
+
--hl-comment: #696969;
|
|
43
|
+
--hl-red: #d91e18;
|
|
44
|
+
--hl-orange: #aa5d00;
|
|
45
|
+
--hl-green: #008000;
|
|
46
|
+
--hl-cyan: #007faa;
|
|
47
|
+
--hl-purple: #7928a1;
|
|
48
|
+
--hl-attr: #aa5d00;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
@media (prefers-color-scheme: dark) {
|
|
52
|
+
:root {
|
|
53
|
+
/* Dark mode */
|
|
54
|
+
--bg: #14141a;
|
|
55
|
+
--fg: #f2f2f2;
|
|
56
|
+
--muted: #b9b9b9;
|
|
57
|
+
--accent: #8ab4f8;
|
|
58
|
+
--border: #555555;
|
|
59
|
+
--code-bg: #24242c;
|
|
60
|
+
--chip-bg: #33333c;
|
|
61
|
+
--focus-bg: #ffdd00;
|
|
62
|
+
--focus-fg: #1a1a1a;
|
|
63
|
+
|
|
64
|
+
/* Syntax highlighting (a11y-dark) */
|
|
65
|
+
--hl-bg: #2b2b2b;
|
|
66
|
+
--hl-fg: #f8f8f2;
|
|
67
|
+
--hl-comment: #d4d0ab;
|
|
68
|
+
--hl-red: #ffa07a;
|
|
69
|
+
--hl-orange: #f5ab35;
|
|
70
|
+
--hl-green: #abe338;
|
|
71
|
+
--hl-cyan: #00e0e0;
|
|
72
|
+
--hl-purple: #dcc6e0;
|
|
73
|
+
--hl-attr: #ffd700;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/* --- EDIT ZONE 2: TYPE ---------------------------------------------------- */
|
|
78
|
+
section {
|
|
79
|
+
--font-body: system-ui, -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
|
|
80
|
+
--font-mono: ui-monospace, "SF Mono", Menlo, Consolas, monospace;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/* ===========================================================================
|
|
84
|
+
* Layout helpers — plain grid/flex, tailored to slides. Usually leave as-is.
|
|
85
|
+
* ======================================================================== */
|
|
86
|
+
:root {
|
|
87
|
+
--space-xs: 0.5em;
|
|
88
|
+
--space-s: 1em;
|
|
89
|
+
--space-m: 1.5em;
|
|
90
|
+
--space-l: 2.25em;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
.box { padding: var(--space-m); }
|
|
94
|
+
.box-s { padding: var(--space-s); }
|
|
95
|
+
.box-l { padding: var(--space-l); }
|
|
96
|
+
|
|
97
|
+
.stack { display: flex; flex-direction: column; gap: var(--space-s); }
|
|
98
|
+
.stack-s { gap: var(--space-xs); }
|
|
99
|
+
.stack-l { gap: var(--space-l); }
|
|
100
|
+
|
|
101
|
+
.cluster { display: flex; flex-wrap: wrap; gap: var(--space-s); align-items: center; }
|
|
102
|
+
|
|
103
|
+
.columns { display: grid; grid-template-columns: repeat(2, 1fr); gap: var(--space-m); align-items: start; }
|
|
104
|
+
.columns-3 { grid-template-columns: repeat(3, 1fr); }
|
|
105
|
+
|
|
106
|
+
.grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(14em, 1fr)); gap: var(--space-m); }
|
|
107
|
+
|
|
108
|
+
.center { max-inline-size: 40ch; margin-inline: auto; }
|
|
109
|
+
|
|
110
|
+
.frame { display: grid; place-items: center; aspect-ratio: 16 / 9; overflow: hidden; }
|
|
111
|
+
.frame-square { aspect-ratio: 1; }
|
|
112
|
+
.frame > img, .frame > video { inline-size: 100%; block-size: 100%; object-fit: cover; }
|
|
113
|
+
|
|
114
|
+
.cover { display: flex; flex-direction: column; justify-content: space-between; block-size: 100%; }
|
|
115
|
+
|
|
116
|
+
.sidebar { display: grid; grid-template-columns: auto 1fr; gap: var(--space-m); align-items: start; }
|
|
117
|
+
|
|
118
|
+
.overlay-centre { position: absolute; inset: 0; display: grid; place-items: center; }
|
|
119
|
+
|
|
120
|
+
/* Slide-level variants — apply to a whole slide with `<!-- _class: … -->`.
|
|
121
|
+
Written as section.X because Marpit scopes bare classes as descendants. */
|
|
122
|
+
section.cover { justify-content: space-between; }
|
|
123
|
+
section.center { align-items: center; text-align: center; }
|
|
124
|
+
section.stack { justify-content: flex-start; gap: var(--space-s); }
|
|
125
|
+
|
|
126
|
+
/* ===========================================================================
|
|
127
|
+
* Element styles — tweak to taste.
|
|
128
|
+
* ======================================================================== */
|
|
129
|
+
|
|
130
|
+
/* Slide */
|
|
131
|
+
section {
|
|
132
|
+
font-family: var(--font-body);
|
|
133
|
+
line-height: 1.3;
|
|
134
|
+
font-size: 29px;
|
|
135
|
+
color: var(--fg);
|
|
136
|
+
background: var(--bg);
|
|
137
|
+
align-items: stretch;
|
|
138
|
+
display: flex;
|
|
139
|
+
flex-flow: column nowrap;
|
|
140
|
+
justify-content: center;
|
|
141
|
+
padding: 2.7em;
|
|
142
|
+
background-size: cover; }
|
|
143
|
+
section > *:last-child { margin-bottom: 0; }
|
|
144
|
+
section > *:first-child, section header:first-child + * { margin-top: 0; }
|
|
145
|
+
|
|
146
|
+
/* Headings and links */
|
|
147
|
+
h1, h2, h3, h4, h5, h6 { color: var(--accent); }
|
|
148
|
+
h1, h2, p, ul li, ol li { max-width: 66%; }
|
|
149
|
+
h1 { font-size: 1.75em; }
|
|
150
|
+
h2 { font-size: 1.6em; margin-bottom: 1em; }
|
|
151
|
+
h3 { font-size: 1.1em; margin-top: 0; }
|
|
152
|
+
h4 { font-size: 1.05em; }
|
|
153
|
+
h5 { font-size: 1em; }
|
|
154
|
+
h6 { font-size: 0.9em; }
|
|
155
|
+
p { margin-top: 0; }
|
|
156
|
+
|
|
157
|
+
a, a:visited { color: var(--accent); }
|
|
158
|
+
a:focus {
|
|
159
|
+
outline: none;
|
|
160
|
+
padding: 0.1em;
|
|
161
|
+
text-decoration: none;
|
|
162
|
+
background-color: var(--focus-bg);
|
|
163
|
+
color: var(--focus-fg);
|
|
164
|
+
border-bottom: 0.17em solid var(--focus-fg); }
|
|
165
|
+
|
|
166
|
+
hr { height: 0; padding-top: 0.25em; }
|
|
167
|
+
|
|
168
|
+
/* Lists */
|
|
169
|
+
ul, ol { margin-top: 0; margin-bottom: 1.5em; }
|
|
170
|
+
ul li, ol li { padding-left: 1em; line-height: 1.3; margin-bottom: .5em; }
|
|
171
|
+
|
|
172
|
+
/* Quotes */
|
|
173
|
+
blockquote { margin: 0; padding-left: 1em; border-left: 0.35em solid var(--border); }
|
|
174
|
+
blockquote p { font-style: italic; }
|
|
175
|
+
|
|
176
|
+
/* Code */
|
|
177
|
+
pre { margin: 0 0 1em; overflow: visible; }
|
|
178
|
+
pre code {
|
|
179
|
+
display: block;
|
|
180
|
+
overflow-y: visible;
|
|
181
|
+
overflow-x: auto;
|
|
182
|
+
padding: .75em;
|
|
183
|
+
border: 1px dashed var(--border);
|
|
184
|
+
font-size: .9em; }
|
|
185
|
+
pre code:focus {
|
|
186
|
+
outline: 0.14em solid var(--fg);
|
|
187
|
+
outline-offset: 0.14em;
|
|
188
|
+
box-shadow: 0 0 0 0.17em var(--focus-bg); }
|
|
189
|
+
code {
|
|
190
|
+
font-family: var(--font-mono);
|
|
191
|
+
font-size: 1em;
|
|
192
|
+
background-color: var(--code-bg);
|
|
193
|
+
padding: 0 .2em;
|
|
194
|
+
border-radius: 0.17em; }
|
|
195
|
+
kbd {
|
|
196
|
+
color: var(--fg);
|
|
197
|
+
font-size: .9em;
|
|
198
|
+
border: 1px solid var(--border);
|
|
199
|
+
border-radius: 0.14em;
|
|
200
|
+
padding: 0 .3em; }
|
|
201
|
+
|
|
202
|
+
/* Media */
|
|
203
|
+
img, figure { margin-top: 0; max-width: 100%; }
|
|
204
|
+
figure { margin: 0; }
|
|
205
|
+
img { border: 1px solid var(--border); }
|
|
206
|
+
|
|
207
|
+
/* Table */
|
|
208
|
+
table { border-collapse: collapse; }
|
|
209
|
+
th, td { border: 1px solid var(--border); padding: .4em .6em; text-align: left; }
|
|
210
|
+
|
|
211
|
+
/* Header and footer */
|
|
212
|
+
header, footer {
|
|
213
|
+
font-size: .75em;
|
|
214
|
+
color: var(--muted);
|
|
215
|
+
margin: 0;
|
|
216
|
+
position: absolute;
|
|
217
|
+
left: 0;
|
|
218
|
+
right: 0;
|
|
219
|
+
padding-inline: 1em;
|
|
220
|
+
min-height: 1em; }
|
|
221
|
+
header { top: 0.7em; }
|
|
222
|
+
footer { bottom: 0.7em; }
|
|
223
|
+
footer a, footer a:visited { color: var(--muted); }
|
|
224
|
+
|
|
225
|
+
.pagination {
|
|
226
|
+
color: var(--muted);
|
|
227
|
+
font-size: 1.1em;
|
|
228
|
+
position: absolute;
|
|
229
|
+
padding: 0;
|
|
230
|
+
right: 1em;
|
|
231
|
+
top: 0; }
|
|
232
|
+
.pagination span:last-of-type {
|
|
233
|
+
border-radius: 50%;
|
|
234
|
+
padding: 0.2em 0.4em;
|
|
235
|
+
background-color: var(--chip-bg); }
|
|
236
|
+
|
|
237
|
+
/* Syntax highlighting — a11y-light / a11y-dark by @ericwbailey */
|
|
238
|
+
pre code.hljs { display: block; overflow-x: auto; padding: 1em; }
|
|
239
|
+
code.hljs { padding: 3px 5px; }
|
|
240
|
+
.hljs { background: var(--hl-bg); color: var(--hl-fg); }
|
|
241
|
+
.hljs-comment, .hljs-quote { color: var(--hl-comment); }
|
|
242
|
+
.hljs-deletion, .hljs-name, .hljs-regexp, .hljs-selector-class, .hljs-selector-id, .hljs-tag, .hljs-template-variable, .hljs-variable { color: var(--hl-red); }
|
|
243
|
+
.hljs-built_in, .hljs-link, .hljs-literal, .hljs-meta, .hljs-number, .hljs-params, .hljs-type { color: var(--hl-orange); }
|
|
244
|
+
.hljs-attribute { color: var(--hl-attr); }
|
|
245
|
+
.hljs-addition, .hljs-bullet, .hljs-string, .hljs-symbol { color: var(--hl-green); }
|
|
246
|
+
.hljs-section, .hljs-title { color: var(--hl-cyan); }
|
|
247
|
+
.hljs-keyword, .hljs-selector-tag { color: var(--hl-purple); }
|
|
248
|
+
.hljs-emphasis { font-style: italic; }
|
|
249
|
+
.hljs-strong { font-weight: 700; }
|
package/themes/basic.css
ADDED
|
@@ -0,0 +1,316 @@
|
|
|
1
|
+
/* @theme basic */
|
|
2
|
+
/*!
|
|
3
|
+
* @auto-scaling true
|
|
4
|
+
* @size 16:9 1280px 720px
|
|
5
|
+
* @size 4:3 960px 720px
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
/*
|
|
9
|
+
* A single, neutral theme. Colours come from custom properties so the whole
|
|
10
|
+
* deck flips to dark mode automatically when the reader's OS prefers it — no
|
|
11
|
+
* second stylesheet. Override the variables below to rebrand.
|
|
12
|
+
*
|
|
13
|
+
* Sizes use `em` for a consistent scale, but any unit works: the whole slide is
|
|
14
|
+
* scaled to the window as one unit (see the `zoom` rule in document.css), so
|
|
15
|
+
* everything shrinks together and nothing reflows.
|
|
16
|
+
*/
|
|
17
|
+
:root {
|
|
18
|
+
/* Light mode (default) */
|
|
19
|
+
--bg: #ffffff;
|
|
20
|
+
--fg: #1a1a1a;
|
|
21
|
+
--muted: #565656;
|
|
22
|
+
--accent: #1d4ed8;
|
|
23
|
+
--border: #b1b4b6;
|
|
24
|
+
--code-bg: #f3f4f6;
|
|
25
|
+
--chip-bg: #eaeaea;
|
|
26
|
+
--focus-bg: #ffdd00;
|
|
27
|
+
--focus-fg: #1a1a1a;
|
|
28
|
+
|
|
29
|
+
/* Syntax highlighting (a11y-light) */
|
|
30
|
+
--hl-bg: #fefefe;
|
|
31
|
+
--hl-fg: #545454;
|
|
32
|
+
--hl-comment: #696969;
|
|
33
|
+
--hl-red: #d91e18;
|
|
34
|
+
--hl-orange: #aa5d00;
|
|
35
|
+
--hl-green: #008000;
|
|
36
|
+
--hl-cyan: #007faa;
|
|
37
|
+
--hl-purple: #7928a1;
|
|
38
|
+
--hl-attr: #aa5d00;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
@media (prefers-color-scheme: dark) {
|
|
42
|
+
:root {
|
|
43
|
+
/* Dark mode */
|
|
44
|
+
--bg: #1a1a1a;
|
|
45
|
+
--fg: #f2f2f2;
|
|
46
|
+
--muted: #b9b9b9;
|
|
47
|
+
--accent: #8ab4f8;
|
|
48
|
+
--border: #555555;
|
|
49
|
+
--code-bg: #2a2a2a;
|
|
50
|
+
--chip-bg: #333333;
|
|
51
|
+
--focus-bg: #ffdd00;
|
|
52
|
+
--focus-fg: #1a1a1a;
|
|
53
|
+
|
|
54
|
+
/* Syntax highlighting (a11y-dark) */
|
|
55
|
+
--hl-bg: #2b2b2b;
|
|
56
|
+
--hl-fg: #f8f8f2;
|
|
57
|
+
--hl-comment: #d4d0ab;
|
|
58
|
+
--hl-red: #ffa07a;
|
|
59
|
+
--hl-orange: #f5ab35;
|
|
60
|
+
--hl-green: #abe338;
|
|
61
|
+
--hl-cyan: #00e0e0;
|
|
62
|
+
--hl-purple: #dcc6e0;
|
|
63
|
+
--hl-attr: #ffd700;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/*
|
|
68
|
+
* Layout helpers. Plain, slide-native CSS: because a slide is a fixed canvas
|
|
69
|
+
* that scales as a whole (it never reflows), simple grid/flex layouts are all
|
|
70
|
+
* we need. Compose slides by putting these classes on raw HTML inside a slide,
|
|
71
|
+
* e.g. <div class="columns"> … </div>. See docs/layouts.md.
|
|
72
|
+
*
|
|
73
|
+
* Sizes use a small em-based spacing scale so gaps scale with the slide.
|
|
74
|
+
*/
|
|
75
|
+
:root {
|
|
76
|
+
--space-xs: 0.5em;
|
|
77
|
+
--space-s: 1em;
|
|
78
|
+
--space-m: 1.5em;
|
|
79
|
+
--space-l: 2.25em;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/* box — a padded container */
|
|
83
|
+
.box { padding: var(--space-m); }
|
|
84
|
+
.box-s { padding: var(--space-s); }
|
|
85
|
+
.box-l { padding: var(--space-l); }
|
|
86
|
+
|
|
87
|
+
/* stack — even vertical spacing between children */
|
|
88
|
+
.stack { display: flex; flex-direction: column; gap: var(--space-s); }
|
|
89
|
+
.stack-s { gap: var(--space-xs); }
|
|
90
|
+
.stack-l { gap: var(--space-l); }
|
|
91
|
+
|
|
92
|
+
/* cluster — a wrapping row of items with even gaps (tags, chips, buttons) */
|
|
93
|
+
.cluster { display: flex; flex-wrap: wrap; gap: var(--space-s); align-items: center; }
|
|
94
|
+
|
|
95
|
+
/* columns — equal-width columns side by side */
|
|
96
|
+
.columns { display: grid; grid-template-columns: repeat(2, 1fr); gap: var(--space-m); align-items: start; }
|
|
97
|
+
.columns-3 { grid-template-columns: repeat(3, 1fr); }
|
|
98
|
+
|
|
99
|
+
/* grid — as many equal cards as fit, each at least 14em wide */
|
|
100
|
+
.grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(14em, 1fr)); gap: var(--space-m); }
|
|
101
|
+
|
|
102
|
+
/* center — a centred column at a comfortable reading measure */
|
|
103
|
+
.center { max-inline-size: 40ch; margin-inline: auto; }
|
|
104
|
+
|
|
105
|
+
/* frame — crop media to a fixed aspect ratio (16:9 by default) */
|
|
106
|
+
.frame { display: grid; place-items: center; aspect-ratio: 16 / 9; overflow: hidden; }
|
|
107
|
+
.frame-square { aspect-ratio: 1; }
|
|
108
|
+
.frame > img, .frame > video { inline-size: 100%; block-size: 100%; object-fit: cover; }
|
|
109
|
+
|
|
110
|
+
/* cover — pin content to top and bottom, fill the slide height */
|
|
111
|
+
.cover { display: flex; flex-direction: column; justify-content: space-between; block-size: 100%; }
|
|
112
|
+
|
|
113
|
+
/* sidebar — a self-sized side column beside a flexible main column */
|
|
114
|
+
.sidebar { display: grid; grid-template-columns: auto 1fr; gap: var(--space-m); align-items: start; }
|
|
115
|
+
|
|
116
|
+
/* overlay-centre — centre an element over a positioned ancestor */
|
|
117
|
+
.overlay-centre { position: absolute; inset: 0; display: grid; place-items: center; }
|
|
118
|
+
|
|
119
|
+
/* Slide-level variants — apply to a whole slide with `<!-- _class: … -->`.
|
|
120
|
+
Written as section.X because Marpit scopes bare classes as descendants. */
|
|
121
|
+
section.cover { justify-content: space-between; }
|
|
122
|
+
section.center { align-items: center; text-align: center; }
|
|
123
|
+
section.stack { justify-content: flex-start; gap: var(--space-s); }
|
|
124
|
+
|
|
125
|
+
/* Slide. In an export, font-size is overridden by document.css to track the
|
|
126
|
+
window width; the value here is the base used by the Marp VSCode preview. */
|
|
127
|
+
section {
|
|
128
|
+
font-family: system-ui, -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
|
|
129
|
+
line-height: 1.3;
|
|
130
|
+
font-size: 29px;
|
|
131
|
+
color: var(--fg);
|
|
132
|
+
background: var(--bg);
|
|
133
|
+
align-items: stretch;
|
|
134
|
+
display: flex;
|
|
135
|
+
flex-flow: column nowrap;
|
|
136
|
+
justify-content: center;
|
|
137
|
+
padding: 2.7em;
|
|
138
|
+
background-size: cover; }
|
|
139
|
+
section > *:last-child {
|
|
140
|
+
margin-bottom: 0; }
|
|
141
|
+
section > *:first-child, section header:first-child + * {
|
|
142
|
+
margin-top: 0; }
|
|
143
|
+
|
|
144
|
+
/* Headings and links */
|
|
145
|
+
h1, h2, h3, h4, h5, h6 {
|
|
146
|
+
color: var(--accent); }
|
|
147
|
+
|
|
148
|
+
h1, h2, p, ul li, ol li {
|
|
149
|
+
max-width: 66%; }
|
|
150
|
+
|
|
151
|
+
h1 {
|
|
152
|
+
font-size: 1.75em; }
|
|
153
|
+
|
|
154
|
+
h2 {
|
|
155
|
+
font-size: 1.6em;
|
|
156
|
+
margin-bottom: 1em; }
|
|
157
|
+
|
|
158
|
+
h3 {
|
|
159
|
+
font-size: 1.1em;
|
|
160
|
+
margin-top: 0; }
|
|
161
|
+
|
|
162
|
+
h4 { font-size: 1.05em; }
|
|
163
|
+
h5 { font-size: 1em; }
|
|
164
|
+
h6 { font-size: 0.9em; }
|
|
165
|
+
|
|
166
|
+
p { margin-top: 0; }
|
|
167
|
+
|
|
168
|
+
a, a:visited {
|
|
169
|
+
color: var(--accent); }
|
|
170
|
+
|
|
171
|
+
a:focus {
|
|
172
|
+
outline: none;
|
|
173
|
+
padding: 0.1em;
|
|
174
|
+
text-decoration: none;
|
|
175
|
+
background-color: var(--focus-bg);
|
|
176
|
+
color: var(--focus-fg);
|
|
177
|
+
border-bottom: 0.17em solid var(--focus-fg); }
|
|
178
|
+
|
|
179
|
+
hr {
|
|
180
|
+
height: 0;
|
|
181
|
+
padding-top: 0.25em; }
|
|
182
|
+
|
|
183
|
+
/* Lists */
|
|
184
|
+
ul, ol {
|
|
185
|
+
margin-top: 0;
|
|
186
|
+
margin-bottom: 1.5em; }
|
|
187
|
+
ul li, ol li {
|
|
188
|
+
padding-left: 1em;
|
|
189
|
+
line-height: 1.3;
|
|
190
|
+
margin-bottom: .5em; }
|
|
191
|
+
|
|
192
|
+
/* Quotes */
|
|
193
|
+
blockquote {
|
|
194
|
+
margin: 0;
|
|
195
|
+
padding-left: 1em;
|
|
196
|
+
border-left: 0.35em solid var(--border); }
|
|
197
|
+
blockquote p {
|
|
198
|
+
font-style: italic; }
|
|
199
|
+
|
|
200
|
+
/* Code */
|
|
201
|
+
pre {
|
|
202
|
+
margin: 0 0 1em;
|
|
203
|
+
overflow: visible; }
|
|
204
|
+
pre code {
|
|
205
|
+
display: block;
|
|
206
|
+
overflow-y: visible;
|
|
207
|
+
overflow-x: auto;
|
|
208
|
+
padding: .75em;
|
|
209
|
+
border: 1px dashed var(--border);
|
|
210
|
+
font-size: .9em; }
|
|
211
|
+
pre code:focus {
|
|
212
|
+
outline: 0.14em solid var(--fg);
|
|
213
|
+
outline-offset: 0.14em;
|
|
214
|
+
box-shadow: 0 0 0 0.17em var(--focus-bg); }
|
|
215
|
+
|
|
216
|
+
code {
|
|
217
|
+
font-family: ui-monospace, "SF Mono", Menlo, Consolas, monospace;
|
|
218
|
+
font-size: 1em;
|
|
219
|
+
background-color: var(--code-bg);
|
|
220
|
+
padding: 0 .2em;
|
|
221
|
+
border-radius: 0.17em; }
|
|
222
|
+
|
|
223
|
+
kbd {
|
|
224
|
+
color: var(--fg);
|
|
225
|
+
font-size: .9em;
|
|
226
|
+
border: 1px solid var(--border);
|
|
227
|
+
border-radius: 0.14em;
|
|
228
|
+
padding: 0 .3em; }
|
|
229
|
+
|
|
230
|
+
/* Media */
|
|
231
|
+
img, figure {
|
|
232
|
+
margin-top: 0;
|
|
233
|
+
max-width: 100%; }
|
|
234
|
+
|
|
235
|
+
figure {
|
|
236
|
+
margin: 0; }
|
|
237
|
+
|
|
238
|
+
img {
|
|
239
|
+
border: 1px solid var(--border); }
|
|
240
|
+
|
|
241
|
+
/* Table */
|
|
242
|
+
table {
|
|
243
|
+
border-collapse: collapse; }
|
|
244
|
+
th, td {
|
|
245
|
+
border: 1px solid var(--border);
|
|
246
|
+
padding: .4em .6em;
|
|
247
|
+
text-align: left; }
|
|
248
|
+
|
|
249
|
+
/* Header and footer */
|
|
250
|
+
header, footer {
|
|
251
|
+
font-size: .75em;
|
|
252
|
+
color: var(--muted);
|
|
253
|
+
margin: 0;
|
|
254
|
+
position: absolute;
|
|
255
|
+
left: 0;
|
|
256
|
+
right: 0;
|
|
257
|
+
padding-inline: 1em;
|
|
258
|
+
min-height: 1em; }
|
|
259
|
+
|
|
260
|
+
header { top: 0.7em; }
|
|
261
|
+
footer { bottom: 0.7em; }
|
|
262
|
+
|
|
263
|
+
footer a, footer a:visited {
|
|
264
|
+
color: var(--muted); }
|
|
265
|
+
|
|
266
|
+
.pagination {
|
|
267
|
+
color: var(--muted);
|
|
268
|
+
font-size: 1.1em;
|
|
269
|
+
position: absolute;
|
|
270
|
+
padding: 0;
|
|
271
|
+
right: 1em;
|
|
272
|
+
top: 0; }
|
|
273
|
+
.pagination span:last-of-type {
|
|
274
|
+
border-radius: 50%;
|
|
275
|
+
padding: 0.2em 0.4em;
|
|
276
|
+
background-color: var(--chip-bg); }
|
|
277
|
+
|
|
278
|
+
/* Syntax highlighting — a11y-light / a11y-dark by @ericwbailey */
|
|
279
|
+
pre code.hljs {
|
|
280
|
+
display: block;
|
|
281
|
+
overflow-x: auto;
|
|
282
|
+
padding: 1em; }
|
|
283
|
+
|
|
284
|
+
code.hljs {
|
|
285
|
+
padding: 3px 5px; }
|
|
286
|
+
|
|
287
|
+
.hljs {
|
|
288
|
+
background: var(--hl-bg);
|
|
289
|
+
color: var(--hl-fg); }
|
|
290
|
+
|
|
291
|
+
.hljs-comment, .hljs-quote {
|
|
292
|
+
color: var(--hl-comment); }
|
|
293
|
+
|
|
294
|
+
.hljs-deletion, .hljs-name, .hljs-regexp, .hljs-selector-class, .hljs-selector-id, .hljs-tag, .hljs-template-variable, .hljs-variable {
|
|
295
|
+
color: var(--hl-red); }
|
|
296
|
+
|
|
297
|
+
.hljs-built_in, .hljs-link, .hljs-literal, .hljs-meta, .hljs-number, .hljs-params, .hljs-type {
|
|
298
|
+
color: var(--hl-orange); }
|
|
299
|
+
|
|
300
|
+
.hljs-attribute {
|
|
301
|
+
color: var(--hl-attr); }
|
|
302
|
+
|
|
303
|
+
.hljs-addition, .hljs-bullet, .hljs-string, .hljs-symbol {
|
|
304
|
+
color: var(--hl-green); }
|
|
305
|
+
|
|
306
|
+
.hljs-section, .hljs-title {
|
|
307
|
+
color: var(--hl-cyan); }
|
|
308
|
+
|
|
309
|
+
.hljs-keyword, .hljs-selector-tag {
|
|
310
|
+
color: var(--hl-purple); }
|
|
311
|
+
|
|
312
|
+
.hljs-emphasis {
|
|
313
|
+
font-style: italic; }
|
|
314
|
+
|
|
315
|
+
.hljs-strong {
|
|
316
|
+
font-weight: 700; }
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Base layer injected into every rendered deck, regardless of theme. It owns
|
|
3
|
+
* the two things that must work no matter which theme is used: the responsive
|
|
4
|
+
* 16:9 scaling, and the functional accessibility utilities the transforms
|
|
5
|
+
* depend on. All *visual* styling lives in the theme.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
*, *::before, *::after { box-sizing: border-box; }
|
|
9
|
+
|
|
10
|
+
body {
|
|
11
|
+
margin: 0;
|
|
12
|
+
padding: 0;
|
|
13
|
+
background: #e6e6e6;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
@media (prefers-color-scheme: dark) {
|
|
17
|
+
body { background: #000000; }
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
img { max-inline-size: 100%; block-size: auto; }
|
|
21
|
+
|
|
22
|
+
/*
|
|
23
|
+
* Uniform whole-slide scaling.
|
|
24
|
+
*
|
|
25
|
+
* Marpit renders every slide at a fixed 1280×720 design size. The inlined
|
|
26
|
+
* runtime script sets `--slide-scale` on `div.marpit` to (container width /
|
|
27
|
+
* 1280), and `zoom` scales each slide — text, spacing, layout, everything — as
|
|
28
|
+
* one rigid unit. Nothing reflows: the layout is computed once at 1280px and
|
|
29
|
+
* simply magnified. `zoom` also shrinks the slide's layout box, so slides stack
|
|
30
|
+
* with no gaps and there's no horizontal overflow. We style Marpit's real
|
|
31
|
+
* `div.marpit > section` selector (no wrapper) so the theme's scoped rules keep
|
|
32
|
+
* applying.
|
|
33
|
+
*
|
|
34
|
+
* Without JavaScript `--slide-scale` stays 1: slides render at full 1280px size
|
|
35
|
+
* and the page scrolls — a readable, if unscaled, fallback.
|
|
36
|
+
*/
|
|
37
|
+
div.marpit {
|
|
38
|
+
width: 100%;
|
|
39
|
+
max-width: 1280px;
|
|
40
|
+
margin-inline: auto;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
div.marpit > section {
|
|
44
|
+
zoom: var(--slide-scale, 1);
|
|
45
|
+
margin-block: 1rem;
|
|
46
|
+
position: relative;
|
|
47
|
+
overflow: hidden;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/* Functional a11y utility — used by the injected screen-reader pagination. */
|
|
51
|
+
.visually-hidden {
|
|
52
|
+
position: absolute !important;
|
|
53
|
+
width: 1px !important;
|
|
54
|
+
height: 1px !important;
|
|
55
|
+
margin: 0 !important;
|
|
56
|
+
padding: 0 !important;
|
|
57
|
+
overflow: hidden !important;
|
|
58
|
+
clip: rect(0 0 0 0) !important;
|
|
59
|
+
clip-path: inset(50%) !important;
|
|
60
|
+
border: 0 !important;
|
|
61
|
+
white-space: nowrap !important;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/* Baseline focus ring so keyboard focus is visible even under a bare theme. */
|
|
65
|
+
:focus-visible {
|
|
66
|
+
outline: 3px solid currentColor;
|
|
67
|
+
outline-offset: 2px;
|
|
68
|
+
}
|