slidev-theme-tud-db 0.0.5 → 0.0.7
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/README.md +3 -1
- package/components/DbFrame.vue +2 -1
- package/global-bottom.vue +1 -1
- package/layouts/cover.vue +4 -4
- package/layouts/section-num.vue +4 -2
- package/layouts/section.vue +4 -4
- package/package.json +1 -1
- package/setup/shiki.ts +42 -0
- package/styles/db-theme.css +84 -30
package/README.md
CHANGED
|
@@ -29,7 +29,7 @@ pnpm dev
|
|
|
29
29
|
|
|
30
30
|
No `addons:` line needed — the theme enables `slidev-addon-gsap` via its
|
|
31
31
|
defaults, so `import { useTl } from 'slidev-addon-gsap'` works in any slide. The
|
|
32
|
-
theme also sets `canvasWidth: 960` (
|
|
32
|
+
theme also sets `canvasWidth: 960` (the 720pt PowerPoint slide, so 1pt == 4/3 px), Noto Sans, light scheme, and
|
|
33
33
|
Comark on; override any in your own headmatter.
|
|
34
34
|
|
|
35
35
|
## Example
|
|
@@ -55,5 +55,7 @@ cp -r node_modules/slidev-theme-db/skills/slidev-theme-db .claude/skills/
|
|
|
55
55
|
- `styles/db-theme.css` — tokens, typography, lists, tables (keyed on `.db-default`).
|
|
56
56
|
- `setup/shiki.ts` (fenced) and the `THEME` in `vite.config.ts` (inline `{lang}`) —
|
|
57
57
|
the **two** highlighters; keep them in sync (both `catppuccin-latte`).
|
|
58
|
+
`setup/shiki.ts` also holds the transformer behind `⟦name:text⟧` code marks
|
|
59
|
+
(spans a slide's timeline can recolour).
|
|
58
60
|
- Link the theme with `link:` (not `file:`), and **restart** the dev server after
|
|
59
61
|
editing theme files (Vite doesn't hot-reload `node_modules`).
|
package/components/DbFrame.vue
CHANGED
|
@@ -11,7 +11,8 @@ const props = defineProps({
|
|
|
11
11
|
class="slidev-layout default db-default relative"
|
|
12
12
|
:style="props.codeSize ? { '--slidev-code-font-size': props.codeSize } : undefined"
|
|
13
13
|
>
|
|
14
|
-
|
|
14
|
+
<!-- top padding puts the title's baseline at 41.9pt, as in the template -->
|
|
15
|
+
<div class="db-default__body px-[30px] pt-[26.5px] pb-[33.5px]">
|
|
15
16
|
<slot />
|
|
16
17
|
</div>
|
|
17
18
|
</div>
|
package/global-bottom.vue
CHANGED
|
@@ -42,7 +42,7 @@ const logos = computed(() => slideLogos[$nav.value.currentPage] ?? {})
|
|
|
42
42
|
class="db-footer absolute inset-x-0 bottom-0 h-[40px] px-[30px] flex items-center justify-between bg-[var(--db-footer-bg)] pointer-events-auto transition-opacity duration-500"
|
|
43
43
|
>
|
|
44
44
|
<img class="h-[25px]" :src="tudBlack" alt="TU Dresden" />
|
|
45
|
-
<span class="
|
|
45
|
+
<span class="db-footer__page">
|
|
46
46
|
<span class="font-bold">{{ $nav.currentPage }}</span>
|
|
47
47
|
<template v-if="$nav.clicksTotal > 0">
|
|
48
48
|
<span class="text-[0.7em]">.{{ $nav.clicks + 1 }}</span>
|
package/layouts/cover.vue
CHANGED
|
@@ -21,12 +21,12 @@ useLogo({ ddrg: 'white', tud: true })
|
|
|
21
21
|
|
|
22
22
|
<style scoped>
|
|
23
23
|
.db-cover__title :deep(h1) {
|
|
24
|
-
@apply
|
|
24
|
+
@apply font-700 leading-10;
|
|
25
|
+
font-size: var(--db-fs-cover-title) !important;
|
|
25
26
|
}
|
|
26
27
|
.db-cover__title :deep(p) {
|
|
27
|
-
@apply absolute top-[95px] m-0
|
|
28
|
-
|
|
29
|
-
/* font-size: 15px; */
|
|
28
|
+
@apply absolute top-[95px] m-0;
|
|
29
|
+
font-size: var(--db-fs-subtitle);
|
|
30
30
|
color: var(--db-text-soft);
|
|
31
31
|
}
|
|
32
32
|
</style>
|
package/layouts/section-num.vue
CHANGED
|
@@ -60,10 +60,12 @@ const num = computed(() => {
|
|
|
60
60
|
|
|
61
61
|
<style scoped>
|
|
62
62
|
.db-cover__title :deep(h1) {
|
|
63
|
-
@apply
|
|
63
|
+
@apply font-700 leading-10 text-[var(--db-heading-blue)];
|
|
64
|
+
font-size: var(--db-fs-cover-title) !important;
|
|
64
65
|
}
|
|
65
66
|
.db-cover__title :deep(p) {
|
|
66
|
-
@apply absolute top-[95px] m-0
|
|
67
|
+
@apply absolute top-[95px] m-0;
|
|
68
|
+
font-size: var(--db-fs-subtitle);
|
|
67
69
|
color: var(--db-text-soft);
|
|
68
70
|
}
|
|
69
71
|
</style>
|
package/layouts/section.vue
CHANGED
|
@@ -21,12 +21,12 @@ useLogo({ ddrg: 'color', footer: true })
|
|
|
21
21
|
|
|
22
22
|
<style scoped>
|
|
23
23
|
.db-cover__title :deep(h1) {
|
|
24
|
-
@apply
|
|
24
|
+
@apply font-700 leading-10 text-[var(--db-heading-blue)];
|
|
25
|
+
font-size: var(--db-fs-section-title) !important;
|
|
25
26
|
}
|
|
26
27
|
.db-cover__title :deep(p) {
|
|
27
|
-
@apply absolute top-[95px] m-0
|
|
28
|
-
|
|
29
|
-
/* font-size: 15px; */
|
|
28
|
+
@apply absolute top-[95px] m-0;
|
|
29
|
+
font-size: var(--db-fs-subtitle);
|
|
30
30
|
color: var(--db-text-soft);
|
|
31
31
|
}
|
|
32
32
|
</style>
|
package/package.json
CHANGED
package/setup/shiki.ts
CHANGED
|
@@ -5,9 +5,51 @@
|
|
|
5
5
|
// NB: no `import { defineShikiSetup } from '@slidev/types'` on purpose — it's
|
|
6
6
|
// only a type helper, and Slidev calls this default export as `setup(ctx)`.
|
|
7
7
|
// catppuccin-latte / -mocha are bundled with Shiki, so no extra deps needed.
|
|
8
|
+
|
|
9
|
+
// Code marks: wrap exact character ranges of a fenced block so a slide can
|
|
10
|
+
// recolour that text, e.g. at a click. Inside the code, write ⟦name:text⟧: the
|
|
11
|
+
// markers are removed and `text` is wrapped in <span class="code-mark mark-name">.
|
|
12
|
+
//
|
|
13
|
+
// WHERE salary > ⟦paren:(⟧
|
|
14
|
+
//
|
|
15
|
+
// A mark looks like the code around it until something recolours it, typically
|
|
16
|
+
// a gsap timeline at a click. A mark can span several syntax-coloured tokens,
|
|
17
|
+
// so recolour the tokens inside it too:
|
|
18
|
+
//
|
|
19
|
+
// tl.to('.mark-paren, .mark-paren span', { color: '#f9c611' })
|
|
20
|
+
//
|
|
21
|
+
// A mark must stay within one line. Magic-move blocks don't run Shiki
|
|
22
|
+
// transformers, so marks only work in plain fenced blocks.
|
|
23
|
+
const MARK = /⟦([\w-]+):([^⟧\n]*)⟧/g
|
|
24
|
+
|
|
25
|
+
interface Decoration { start: number, end: number, properties: Record<string, string> }
|
|
26
|
+
|
|
27
|
+
const codeMarks = {
|
|
28
|
+
name: 'tud-db:code-marks',
|
|
29
|
+
preprocess(code: string, options: { decorations?: Decoration[] }) {
|
|
30
|
+
if (!code.includes('⟦'))
|
|
31
|
+
return
|
|
32
|
+
const marks: Decoration[] = []
|
|
33
|
+
let out = ''
|
|
34
|
+
let last = 0
|
|
35
|
+
for (const m of code.matchAll(MARK)) {
|
|
36
|
+
out += code.slice(last, m.index)
|
|
37
|
+
const start = out.length
|
|
38
|
+
out += m[2]
|
|
39
|
+
marks.push({ start, end: out.length, properties: { class: `code-mark mark-${m[1]}` } })
|
|
40
|
+
last = m.index! + m[0].length
|
|
41
|
+
}
|
|
42
|
+
out += code.slice(last)
|
|
43
|
+
// Shiki reads the decorations from these options when it renders
|
|
44
|
+
options.decorations = [...(options.decorations ?? []), ...marks]
|
|
45
|
+
return out
|
|
46
|
+
},
|
|
47
|
+
}
|
|
48
|
+
|
|
8
49
|
export default () => ({
|
|
9
50
|
themes: {
|
|
10
51
|
light: 'catppuccin-latte',
|
|
11
52
|
dark: 'catppuccin-mocha',
|
|
12
53
|
},
|
|
54
|
+
transformers: [codeMarks],
|
|
13
55
|
})
|
package/styles/db-theme.css
CHANGED
|
@@ -20,6 +20,21 @@
|
|
|
20
20
|
--db-table-stripe: #dbdbdb; /* zebra-striped table rows */
|
|
21
21
|
--db-table-rule: #b9b9b9; /* table header/footer rule lines */
|
|
22
22
|
|
|
23
|
+
/* Type scale, in PowerPoint points. The template slide is 720×405pt but the
|
|
24
|
+
theme renders it on Slidev's 960×540px canvas, so 1pt == 4/3 px — never
|
|
25
|
+
write a pt value as px. Sizes measured from resource/template.pdf. */
|
|
26
|
+
--db-pt: calc(4px / 3);
|
|
27
|
+
--db-fs-cover-title: calc(28 * var(--db-pt)); /* cover / section-num title */
|
|
28
|
+
--db-fs-section-title: calc(24 * var(--db-pt)); /* section title */
|
|
29
|
+
--db-fs-subtitle: calc(14 * var(--db-pt)); /* cover / section subtitle */
|
|
30
|
+
--db-fs-title: calc(22 * var(--db-pt)); /* content slide title (h1) */
|
|
31
|
+
--db-fs-heading: calc(15 * var(--db-pt)); /* blue sub-header (h2/h3) */
|
|
32
|
+
--db-fs-body: calc(13 * var(--db-pt)); /* body text, 1st-level bullets */
|
|
33
|
+
--db-fs-small: calc(12 * var(--db-pt)); /* 2nd-level bullets, page number */
|
|
34
|
+
--db-fs-code: calc(11 * var(--db-pt)); /* code blocks */
|
|
35
|
+
--db-fs-caption: calc(11 * var(--db-pt)); /* table / code captions */
|
|
36
|
+
--db-fs-table: calc(10 * var(--db-pt)); /* table cells */
|
|
37
|
+
|
|
23
38
|
/* Slidev theme variables */
|
|
24
39
|
--slidev-theme-primary: var(--db-accent3);
|
|
25
40
|
}
|
|
@@ -29,8 +44,7 @@
|
|
|
29
44
|
* height:100% fills the slide (theme provides this; not inherited from
|
|
30
45
|
* @slidev/theme-default anymore). */
|
|
31
46
|
.slidev-layout {
|
|
32
|
-
|
|
33
|
-
background: #ffffff;
|
|
47
|
+
/* background: #ffffff; */
|
|
34
48
|
color: var(--db-text-soft);
|
|
35
49
|
font-family: 'NotoSans', ui-sans-serif, system-ui, sans-serif;
|
|
36
50
|
}
|
|
@@ -60,33 +74,36 @@
|
|
|
60
74
|
color: var(--db-accent3);
|
|
61
75
|
}
|
|
62
76
|
|
|
63
|
-
/* Content slides ("Titel und Inhalt").
|
|
64
|
-
*
|
|
77
|
+
/* Content slides ("Titel und Inhalt"). Font sizes come from the pt type scale
|
|
78
|
+
* on :root; spacing below is in canvas px, chosen so the baselines land where
|
|
79
|
+
* resource/template.pdf has them: title 41.9pt, first sub-header 92.5pt, then
|
|
80
|
+
* bullets every 18pt, and 27.9pt from a bullet to the next sub-header. (Noto
|
|
81
|
+
* Sans puts the baseline 0.388em below the middle of its line box.) */
|
|
65
82
|
.slidev-layout.db-default {
|
|
66
|
-
font-size:
|
|
67
|
-
|
|
68
|
-
padding: 0; /* we control spacing via the body wrapper + footer */
|
|
83
|
+
font-size: var(--db-fs-body);
|
|
84
|
+
padding: 0;
|
|
69
85
|
}
|
|
70
86
|
.slidev-layout.db-default h1 {
|
|
71
87
|
color: var(--db-text-soft); /* black/gray page heading */
|
|
72
|
-
font-size:
|
|
73
|
-
line-height:
|
|
74
|
-
margin-bottom:
|
|
88
|
+
font-size: var(--db-fs-title);
|
|
89
|
+
line-height: 2.25rem;
|
|
90
|
+
margin-bottom: 39px; /* gap to first sub-header (baseline at 92.5pt) */
|
|
75
91
|
}
|
|
76
92
|
.slidev-layout.db-default h2,
|
|
77
93
|
.slidev-layout.db-default h3 {
|
|
78
94
|
color: var(--db-heading-blue); /* blue sub-headers */
|
|
79
|
-
font-size:
|
|
80
|
-
line-height: 1.
|
|
81
|
-
margin-top:
|
|
82
|
-
(bullet list, code block, paragraph, …)
|
|
95
|
+
font-size: var(--db-fs-heading);
|
|
96
|
+
line-height: 1.75rem;
|
|
97
|
+
margin-top: 11px; /* space ABOVE a sub-header, whatever precedes it
|
|
98
|
+
(bullet list, code block, paragraph, …);
|
|
99
|
+
27.9pt baseline-to-baseline after a bullet */
|
|
83
100
|
}
|
|
84
101
|
/* …except a sub-header that is the FIRST content of its area (right under the
|
|
85
102
|
page title, or the top of a column / grid cell) — the title's margin-bottom
|
|
86
103
|
or the grid gap already provides that separation.
|
|
87
104
|
This is wrap-proof: a section wrapped in a <div> (e.g. a GSAP animation
|
|
88
105
|
anchor) is still treated as "top" when its wrapper is the first child, but a
|
|
89
|
-
wrapped section that FOLLOWS other content keeps
|
|
106
|
+
wrapped section that FOLLOWS other content keeps its top gap. So adding a
|
|
90
107
|
wrapper div later does NOT collapse the spacing. (default layout: h1 is a
|
|
91
108
|
sibling of the content; two-cols-header: .db-grid__col; two-cols-grid:
|
|
92
109
|
.db-rowgrid cells.) */
|
|
@@ -112,7 +129,7 @@
|
|
|
112
129
|
.slidev-layout.db-default ul ul,
|
|
113
130
|
.slidev-layout.db-default ol ol {
|
|
114
131
|
margin-left: 0; /* 2nd-level marker aligns with 1st-level text (no extra indent) */
|
|
115
|
-
font-size:
|
|
132
|
+
font-size: var(--db-fs-small); /* 2nd-level text a touch smaller (12pt vs 13pt) */
|
|
116
133
|
}
|
|
117
134
|
.slidev-layout.db-default ul ul { list-style-type: square; }
|
|
118
135
|
/* Tight vertical rhythm (theme defaults to ~1.8 line-height) */
|
|
@@ -135,11 +152,6 @@
|
|
|
135
152
|
.slidev-layout.db-default li::marker {
|
|
136
153
|
color: var(--db-text-soft);
|
|
137
154
|
}
|
|
138
|
-
/* Shrink only the bullet glyphs (• ▪); ordered-list numbers keep text size. */
|
|
139
|
-
.slidev-layout.db-default ul li::marker {
|
|
140
|
-
font-size: 0.8em;
|
|
141
|
-
}
|
|
142
|
-
|
|
143
155
|
/* Blockquotes -> a muted italic aside with a leading en-dash
|
|
144
156
|
(the "– …" secondary-note style). */
|
|
145
157
|
.slidev-layout.db-default blockquote {
|
|
@@ -204,24 +216,39 @@
|
|
|
204
216
|
.slidev-layout.db-default .with-bg pre.slidev-code {
|
|
205
217
|
background: rgba(0, 0, 0, 0.03) !important;
|
|
206
218
|
}
|
|
207
|
-
/* Code sizing (Slidev defaults: 12px / 18px / 8px).
|
|
208
|
-
tighter vertical padding so the box hugs the code top and bottom.
|
|
219
|
+
/* Code sizing (Slidev defaults: 12px / 18px / 8px). 11pt like the template's
|
|
220
|
+
listings, with tighter vertical padding so the box hugs the code top and bottom.
|
|
221
|
+
No left padding: without a background box, the code text lines up with the
|
|
222
|
+
text, captions and tables around it, as in the template. A .with-bg box gets
|
|
223
|
+
its inset back. */
|
|
209
224
|
.slidev-layout.db-default {
|
|
210
|
-
--slidev-code-font-size:
|
|
225
|
+
--slidev-code-font-size: var(--db-fs-code);
|
|
211
226
|
--slidev-code-line-height: 1.3;
|
|
227
|
+
--slidev-code-padding: 4px 10px 4px 0;
|
|
228
|
+
}
|
|
229
|
+
.slidev-layout.db-default .with-bg {
|
|
212
230
|
--slidev-code-padding: 4px 10px;
|
|
213
231
|
}
|
|
232
|
+
/* No programming ligatures: Fira Code would draw <> as a diamond and <=, >=,
|
|
233
|
+
!= as ≤, ≥, ≠, which readers then can't type. Code shows the characters
|
|
234
|
+
as written. (The theme's --> arrows in prose are a text replacement, not a
|
|
235
|
+
ligature, so they are unaffected.) */
|
|
236
|
+
.slidev-layout code,
|
|
237
|
+
.slidev-layout pre {
|
|
238
|
+
font-variant-ligatures: none;
|
|
239
|
+
}
|
|
214
240
|
|
|
215
241
|
/* Line numbers (```lang {lines:true}```): tighten the gutter. Slidev's defaults
|
|
216
242
|
are a wide 24px gap between the number and the code, plus the block's 10px
|
|
217
243
|
left padding before the number. Both are scoped to line-numbered blocks so
|
|
218
244
|
plain code blocks keep their normal padding. */
|
|
219
245
|
.slidev-layout.db-default .slidev-code-line-numbers .slidev-code,
|
|
220
|
-
.slidev-layout.db-default .shiki-magic-move-container.slidev-code {
|
|
246
|
+
.slidev-layout.db-default .shiki-magic-move-container.slidev-code:has(.shiki-magic-move-line-number) {
|
|
221
247
|
/* override the padding *variable* (Slidev applies padding via it, which beats
|
|
222
248
|
a plain padding-left here). top right bottom left — only the left shrinks.
|
|
223
249
|
The Magic Move container isn't wrapped in .slidev-code-line-numbers, so it
|
|
224
|
-
needs the same override to keep its gutter rule aligned with plain blocks
|
|
250
|
+
needs the same override to keep its gutter rule aligned with plain blocks;
|
|
251
|
+
one without line numbers keeps the plain blocks' zero inset. */
|
|
225
252
|
--slidev-code-padding: 4px 10px 4px 6px; /* less space left of the numbers (was 10px) */
|
|
226
253
|
}
|
|
227
254
|
.slidev-layout.db-default .slidev-code-line-numbers .slidev-code code .line::before {
|
|
@@ -263,13 +290,16 @@
|
|
|
263
290
|
/* Optional caption above a code block.
|
|
264
291
|
Authoring: ```python [What this snippet does] */
|
|
265
292
|
.slidev-layout.db-default .slidev-code-block-title {
|
|
266
|
-
padding: 3px
|
|
293
|
+
padding: 3px 0; /* flush with the code text below (see above) */
|
|
267
294
|
background: transparent; /* drop Slidev's heavy gray title bar */
|
|
268
|
-
font-size:
|
|
295
|
+
font-size: var(--db-fs-caption);
|
|
269
296
|
font-style: italic;
|
|
270
297
|
color: var(--db-text);
|
|
271
298
|
opacity: 0.85;
|
|
272
299
|
}
|
|
300
|
+
.slidev-layout.db-default .with-bg .slidev-code-block-title {
|
|
301
|
+
padding-inline: 10px; /* match the boxed code's inset */
|
|
302
|
+
}
|
|
273
303
|
|
|
274
304
|
/* Optional table captions (need Comark, enabled by this theme).
|
|
275
305
|
ABOVE the table: [Title]{.table-caption} -> black, non-italic
|
|
@@ -282,7 +312,7 @@
|
|
|
282
312
|
.slidev-layout.db-default p:has(.table-caption),
|
|
283
313
|
.slidev-layout.db-default .table-footer,
|
|
284
314
|
.slidev-layout.db-default p:has(.table-footer) {
|
|
285
|
-
font-size:
|
|
315
|
+
font-size: var(--db-fs-caption);
|
|
286
316
|
background: transparent !important;
|
|
287
317
|
}
|
|
288
318
|
.slidev-layout.db-default .table-caption,
|
|
@@ -322,7 +352,7 @@
|
|
|
322
352
|
.slidev-layout.db-default table {
|
|
323
353
|
border-collapse: collapse;
|
|
324
354
|
width: auto; /* default: hug content */
|
|
325
|
-
font-size:
|
|
355
|
+
font-size: var(--db-fs-table); /* 10pt */
|
|
326
356
|
}
|
|
327
357
|
/* Width control: tables hug content by default. To pin a width, wrap in
|
|
328
358
|
<div class="table-w" style="width: …"> — the table then fills that box, so
|
|
@@ -361,6 +391,7 @@
|
|
|
361
391
|
border: none; /* no vertical/cell borders */
|
|
362
392
|
padding: 2px 8px 4px; /* tight padding; bottom>top optically centers
|
|
363
393
|
single-line text (nudges it up) */
|
|
394
|
+
line-height: 1.4; /* rows every 19.2pt (25.6px), as in the template */
|
|
364
395
|
vertical-align: middle; /* center cell text vertically */
|
|
365
396
|
text-align: center; /* center by default; :--/--: in markdown override */
|
|
366
397
|
}
|
|
@@ -384,6 +415,12 @@
|
|
|
384
415
|
.slidev-layout.db-default tbody tr:last-child td {
|
|
385
416
|
border-bottom: 1px solid var(--db-table-rule);
|
|
386
417
|
}
|
|
418
|
+
/* Footer page number (global-bottom.vue): 12pt like the template. */
|
|
419
|
+
.db-footer__page {
|
|
420
|
+
font-size: var(--db-fs-small);
|
|
421
|
+
color: var(--db-text);
|
|
422
|
+
}
|
|
423
|
+
|
|
387
424
|
/* Inline code inside tables AND headings: keep the syntax colors but drop the
|
|
388
425
|
gray "pill" background/padding so it reads like plain text. */
|
|
389
426
|
.slidev-layout.db-default th code,
|
|
@@ -394,3 +431,20 @@
|
|
|
394
431
|
background: transparent;
|
|
395
432
|
padding: 0;
|
|
396
433
|
}
|
|
434
|
+
/* In a heading, code takes the heading's size and weight (the template's
|
|
435
|
+
"1.1 DISTINCT" is bold mono), not the light, smaller inline-code style. */
|
|
436
|
+
.slidev-layout.db-default :is(h1, h2, h3) code {
|
|
437
|
+
font-size: 1em;
|
|
438
|
+
font-weight: inherit;
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
/* Inline math: KaTeX's default 1.21em makes capitals 15% taller than Noto
|
|
442
|
+
Sans ones, and its 1.2 line height stretches the bullet it sits in. At 1.05em
|
|
443
|
+
the capitals match; line-height 1 keeps a formula's bullet within 0.5px of its
|
|
444
|
+
neighbours. (Not 0: that misplaces overlays such as the slash of \notin.) */
|
|
445
|
+
.slidev-layout.db-default .katex {
|
|
446
|
+
font-size: 1.05em;
|
|
447
|
+
}
|
|
448
|
+
.slidev-layout.db-default :not(.katex-display) > .katex {
|
|
449
|
+
line-height: 1;
|
|
450
|
+
}
|