@troshab/slidev-theme-troshab 0.1.0 → 0.1.1

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 CHANGED
@@ -10,7 +10,7 @@ A minimal, universal [Slidev](https://sli.dev) theme built around one flexible l
10
10
 
11
11
  ```md
12
12
  ---
13
- theme: troshab
13
+ theme: @troshab/slidev-theme-troshab
14
14
  ---
15
15
  ```
16
16
 
@@ -22,6 +22,8 @@ theme: troshab
22
22
 
23
23
  **Design system** - 3-layer Dracula/Alucard palette (11 color families × 11 shades), IBM Plex Sans/Mono typography, and a motion system based on IBM Carbon. All tokens are CSS variables - components never hardcode colors.
24
24
 
25
+ **1920×1080 canvas** - optimized for Full HD projectors and screens. All sizing uses `rem` units that scale automatically from the root font-size, so the layout adapts cleanly if the canvas resolution changes.
26
+
25
27
  **v-click auto-registration** - interactive components (AnimatedCounter, Countdown, ImageCompare, Stepper, Conversation, StyledText spoilers) register their own click slots. No `clicks:` frontmatter, no `<v-click>` wrappers needed.
26
28
 
27
29
  **Accessibility** - WCAG AA contrast (target AAA), BDA dyslexia-friendly spacing (word-spacing 0.08em, letter-spacing 0.02em), keyboard focus styles, 5% safe-zone padding.
@@ -4,13 +4,15 @@
4
4
  * Replaces <div class="bg-primary"></div> and raw ![](image) in bg slots.
5
5
  *
6
6
  * Gradient prop:
7
- * 1. Presets (string): "accent" (colorful brand), "subtle" (neutral)
7
+ * 1. Presets (string): "section", "subtle" (alias), "accent", "primary",
8
+ * "success", "warning", "danger", "info"
8
9
  * 2. Full control (array): [type, direction, ...colorStops]
9
10
  * - type: 'linear' | 'radial' | 'conic'
10
11
  * - direction: CSS direction ('135deg', 'to right', 'circle', 'from 45deg')
11
12
  * - colorStops: [semanticColor, position] tuples
12
13
  *
13
14
  * Examples:
15
+ * gradient="section"
14
16
  * gradient="accent"
15
17
  * :gradient="['linear', '135deg', ['primary', '0%'], ['info', '100%']]"
16
18
  * :gradient="['radial', 'circle', ['primary', '0%'], ['soft', '100%']]"
@@ -48,15 +50,25 @@ function resolveColor(name: string): string {
48
50
  return colorVarMap[name] || name
49
51
  }
50
52
 
53
+ const gradientPresets: Record<string, string> = {
54
+ primary: 'var(--gradient-primary)',
55
+ success: 'var(--gradient-success)',
56
+ warning: 'var(--gradient-warning)',
57
+ danger: 'var(--gradient-danger)',
58
+ info: 'var(--gradient-info)',
59
+ accent: 'var(--gradient-accent)',
60
+ section: 'var(--gradient-section)',
61
+ subtle: 'var(--gradient-section)',
62
+ }
63
+
51
64
  const gradientStyle = computed(() => {
52
65
  const g = props.gradient
53
66
  if (!g) return undefined
54
67
 
55
68
  // String presets
56
69
  if (typeof g === 'string') {
57
- if (g === 'accent') return { background: 'var(--gradient-accent)' }
58
- if (g === 'subtle') return { background: 'var(--gradient-section)' }
59
- return undefined
70
+ const v = gradientPresets[g]
71
+ return v ? { background: v } : undefined
60
72
  }
61
73
 
62
74
  // Array: [type, direction, ...colorStops]
@@ -45,7 +45,7 @@ defineProps<{
45
45
  padding: 1rem 1rem 1rem 1.25rem;
46
46
  margin-block: 1rem;
47
47
  background-color: var(--color-bg-soft);
48
- border-left: 4px solid var(--color-info);
48
+ border-left: var(--border-accent) solid var(--color-info);
49
49
  border-radius: 0 0.375rem 0.375rem 0;
50
50
  }
51
51
 
@@ -35,7 +35,7 @@ const isPhosphorIcon = computed(() => props.icon?.startsWith('ph-'))
35
35
  padding: 1.25rem;
36
36
  background-color: var(--color-bg-soft);
37
37
  border-radius: 0.5rem;
38
- border: 1px solid var(--color-border);
38
+ border: var(--border-thin) solid var(--color-border);
39
39
  transition:
40
40
  border-color var(--dur-fast-02) var(--ease-standard),
41
41
  box-shadow var(--dur-fast-02) var(--ease-standard);
@@ -43,11 +43,11 @@ const isPhosphorIcon = computed(() => props.icon?.startsWith('ph-'))
43
43
 
44
44
  .card:hover {
45
45
  border-color: var(--color-border-strong);
46
- box-shadow: 0 2px 8px color-mix(in srgb, var(--color-black) 5%, transparent);
46
+ box-shadow: 0 0.125rem 0.5rem color-mix(in srgb, var(--color-black) 5%, transparent);
47
47
  }
48
48
 
49
49
  .dark .card:hover {
50
- box-shadow: 0 2px 8px color-mix(in srgb, var(--color-black) 20%, transparent);
50
+ box-shadow: 0 0.125rem 0.5rem color-mix(in srgb, var(--color-black) 20%, transparent);
51
51
  }
52
52
 
53
53
  .card-icon {
@@ -47,7 +47,7 @@ defineProps<{
47
47
  background: var(--color-bg-soft);
48
48
  border-radius: 0.5rem;
49
49
  padding: var(--space-sm);
50
- border-left: 4px solid var(--section-color);
50
+ border-left: var(--border-accent) solid var(--section-color);
51
51
  }
52
52
 
53
53
  .case-study-title {
@@ -199,7 +199,7 @@ const afterDiffLines = computed<CodeLine[]>(() =>
199
199
  display: flex;
200
200
  border-radius: 0.5rem;
201
201
  overflow: hidden;
202
- border: 1px solid var(--color-border);
202
+ border: var(--border-thin) solid var(--color-border);
203
203
  }
204
204
 
205
205
  .code-diff-split {
@@ -224,6 +224,6 @@ const afterDiffLines = computed<CodeLine[]>(() =>
224
224
 
225
225
  /* Divider between panels */
226
226
  .code-diff-split > .code-hl:first-child {
227
- border-right: 1px solid var(--color-border-strong);
227
+ border-right: var(--border-thin) solid var(--color-border-strong);
228
228
  }
229
229
  </style>
@@ -209,7 +209,7 @@ function tokenize(text: string): string {
209
209
  word-spacing: normal;
210
210
  border-radius: 0.5rem;
211
211
  overflow: hidden;
212
- border: 1px solid var(--color-border);
212
+ border: var(--border-thin) solid var(--color-border);
213
213
  background-color: var(--shiki-color-background, var(--color-bg-muted));
214
214
  }
215
215
 
@@ -219,7 +219,7 @@ function tokenize(text: string): string {
219
219
  align-items: center;
220
220
  justify-content: space-between;
221
221
  padding: 0.25rem 0.75rem;
222
- border-bottom: 1px solid var(--color-border);
222
+ border-bottom: var(--border-thin) solid var(--color-border);
223
223
  background-color: var(--shiki-color-background, var(--color-bg-muted));
224
224
  }
225
225
 
@@ -83,7 +83,7 @@ watch(() => [isDark.value, props.name], resolveColor)
83
83
  display: flex;
84
84
  align-items: flex-end;
85
85
  padding: 0.5rem;
86
- border: 1px solid var(--color-border);
86
+ border: var(--border-thin) solid var(--color-border);
87
87
  color: var(--color-white);
88
88
  }
89
89
 
@@ -95,7 +95,7 @@ watch(() => [isDark.value, props.name], resolveColor)
95
95
  font-size: var(--font-size-small);
96
96
  font-family: var(--font-mono);
97
97
  line-height: 1.3;
98
- text-shadow: 0 1px 3px color-mix(in srgb, var(--color-black) 30%, transparent);
98
+ text-shadow: 0 0.0625rem 0.1875rem color-mix(in srgb, var(--color-black) 30%, transparent);
99
99
  }
100
100
 
101
101
  .color-swatch-hex {
@@ -109,6 +109,6 @@ watch(() => [isDark.value, props.name], resolveColor)
109
109
  }
110
110
 
111
111
  .color-swatch-light .color-swatch-label {
112
- text-shadow: 0 1px 3px color-mix(in srgb, var(--color-white) 40%, transparent);
112
+ text-shadow: 0 0.0625rem 0.1875rem color-mix(in srgb, var(--color-white) 40%, transparent);
113
113
  }
114
114
  </style>
@@ -274,19 +274,19 @@ defineExpose({ fire })
274
274
  }
275
275
 
276
276
  .confetti-square {
277
- width: 10px;
278
- height: 10px;
277
+ width: 0.625rem;
278
+ height: 0.625rem;
279
279
  }
280
280
 
281
281
  .confetti-circle {
282
- width: 8px;
283
- height: 8px;
282
+ width: 0.5rem;
283
+ height: 0.5rem;
284
284
  border-radius: 50%;
285
285
  }
286
286
 
287
287
  .confetti-strip {
288
- width: 3px;
289
- height: 12px;
290
- border-radius: 1px;
288
+ width: 0.1875rem;
289
+ height: 0.75rem;
290
+ border-radius: 0.0625rem;
291
291
  }
292
292
  </style>
@@ -205,20 +205,20 @@ function getInitials(name: string): string {
205
205
  .conversation {
206
206
  display: flex;
207
207
  flex-direction: column;
208
- gap: var(--space-xs, 8px);
208
+ gap: var(--space-xs, 0.5rem);
209
209
  max-width: 100%;
210
- padding: var(--space-sm, 16px) 0;
210
+ padding: var(--space-sm, 1rem) 0;
211
211
  }
212
212
 
213
213
  /* Row layout */
214
214
  .conv-row {
215
215
  display: flex;
216
216
  align-items: flex-end;
217
- gap: var(--space-xs, 8px);
217
+ gap: var(--space-xs, 0.5rem);
218
218
  }
219
219
 
220
220
  .conv-group-continuation {
221
- margin-top: calc(-1 * var(--space-xs, 8px) + 2px);
221
+ margin-top: calc(-1 * var(--space-xs, 0.5rem) + 0.125rem);
222
222
  }
223
223
 
224
224
  .conv-left {
@@ -273,7 +273,7 @@ function getInitials(name: string): string {
273
273
  .conv-sender {
274
274
  font-size: 0.75rem;
275
275
  color: var(--color-text-tertiary);
276
- margin-bottom: 2px;
276
+ margin-bottom: 0.125rem;
277
277
  padding: 0 0.75rem;
278
278
  }
279
279
 
@@ -284,7 +284,7 @@ function getInitials(name: string): string {
284
284
  /* Bubble */
285
285
  .conv-bubble {
286
286
  padding: 0.5rem 0.75rem;
287
- font-size: var(--font-size-small, 18px);
287
+ font-size: var(--font-size-small, 1.125rem);
288
288
  line-height: var(--line-height-body, 1.35);
289
289
  word-wrap: break-word;
290
290
  }
@@ -293,7 +293,7 @@ function getInitials(name: string): string {
293
293
  .conv-bubble-left {
294
294
  background-color: var(--color-bg-soft);
295
295
  color: var(--color-text);
296
- border: 1px solid var(--color-border);
296
+ border: var(--border-thin) solid var(--color-border);
297
297
  }
298
298
 
299
299
  .conv-bubble-left.conv-bubble-single {
@@ -316,7 +316,7 @@ function getInitials(name: string): string {
316
316
  .conv-bubble-right {
317
317
  background-color: var(--color-primary);
318
318
  color: var(--color-primary-foreground);
319
- border: 1px solid transparent;
319
+ border: var(--border-thin) solid transparent;
320
320
  }
321
321
 
322
322
  .conv-bubble-right.conv-bubble-single {
@@ -395,11 +395,11 @@ function getInitials(name: string): string {
395
395
 
396
396
  .conv-msg-enter-from {
397
397
  opacity: 0;
398
- transform: translateY(var(--shift-sm, 12px));
398
+ transform: translateY(var(--shift-sm, 0.75rem));
399
399
  }
400
400
 
401
401
  .conv-msg-leave-to {
402
402
  opacity: 0;
403
- transform: translateY(calc(-1 * var(--shift-xs, 6px)));
403
+ transform: translateY(calc(-1 * var(--shift-xs, 0.375rem)));
404
404
  }
405
405
  </style>
@@ -377,23 +377,23 @@ defineExpose({ start, pause, resume, stop, reset, toggle })
377
377
  }
378
378
 
379
379
  .countdown-size-sm .countdown-ring {
380
- width: 120px;
381
- height: 120px;
380
+ width: 7.5rem;
381
+ height: 7.5rem;
382
382
  }
383
383
 
384
384
  .countdown-size-md .countdown-ring {
385
- width: 160px;
386
- height: 160px;
385
+ width: 10rem;
386
+ height: 10rem;
387
387
  }
388
388
 
389
389
  .countdown-size-lg .countdown-ring {
390
- width: 200px;
391
- height: 200px;
390
+ width: 12.5rem;
391
+ height: 12.5rem;
392
392
  }
393
393
 
394
394
  .countdown-size-xl .countdown-ring {
395
- width: 260px;
396
- height: 260px;
395
+ width: 16.25rem;
396
+ height: 16.25rem;
397
397
  }
398
398
 
399
399
  .countdown-ring-svg {
@@ -443,8 +443,8 @@ defineExpose({ start, pause, resume, stop, reset, toggle })
443
443
 
444
444
  /* Ring text needs smaller font to fit inside circle */
445
445
  .countdown-size-sm .countdown-ring .countdown-time { font-size: var(--font-size-base); }
446
- .countdown-size-md .countdown-ring .countdown-time { font-size: 28px; }
447
- .countdown-size-lg .countdown-ring .countdown-time { font-size: 40px; }
446
+ .countdown-size-md .countdown-ring .countdown-time { font-size: 1.75rem; }
447
+ .countdown-size-lg .countdown-ring .countdown-time { font-size: 2.5rem; }
448
448
  .countdown-size-xl .countdown-ring .countdown-time { font-size: var(--font-size-h1); }
449
449
 
450
450
  /* Controls */
@@ -52,7 +52,7 @@ defineProps<{
52
52
  .definition-body :deep(h3) {
53
53
  color: var(--color-primary);
54
54
  font-size: var(--font-size-base);
55
- border-top: 2px solid var(--color-border);
55
+ border-top: var(--border-medium) solid var(--color-border);
56
56
  padding-top: var(--space-sm);
57
57
  margin-top: var(--space-md);
58
58
  }
@@ -131,32 +131,32 @@ const displayUrl = computed(() => {
131
131
  ============================================ */
132
132
  .iphone-frame {
133
133
  position: relative;
134
- width: 280px;
135
- height: 580px;
134
+ width: 17.5rem;
135
+ height: 36.25rem;
136
136
  background-color: var(--color-drac-fg-900);
137
- border-radius: 40px;
138
- padding: 12px;
137
+ border-radius: 2.5rem;
138
+ padding: 0.75rem;
139
139
  box-shadow:
140
- 0 0 0 2px var(--color-drac-fg-700),
141
- 0 20px 40px color-mix(in srgb, var(--color-black) 30%, transparent);
140
+ 0 0 0 0.125rem var(--color-drac-fg-700),
141
+ 0 1.25rem 2.5rem color-mix(in srgb, var(--color-black) 30%, transparent);
142
142
  }
143
143
 
144
144
  .dark .iphone-frame {
145
145
  background-color: var(--color-drac-fg-800);
146
146
  box-shadow:
147
- 0 0 0 2px var(--color-drac-fg-600),
148
- 0 20px 40px color-mix(in srgb, var(--color-black) 50%, transparent);
147
+ 0 0 0 0.125rem var(--color-drac-fg-600),
148
+ 0 1.25rem 2.5rem color-mix(in srgb, var(--color-black) 50%, transparent);
149
149
  }
150
150
 
151
151
  .iphone-notch {
152
152
  position: absolute;
153
- top: 12px;
153
+ top: 0.75rem;
154
154
  left: 50%;
155
155
  transform: translateX(-50%);
156
- width: 120px;
157
- height: 28px;
156
+ width: 7.5rem;
157
+ height: 1.75rem;
158
158
  background-color: var(--color-drac-fg-900);
159
- border-radius: 0 0 16px 16px;
159
+ border-radius: 0 0 1rem 1rem;
160
160
  z-index: 10;
161
161
  }
162
162
 
@@ -168,7 +168,7 @@ const displayUrl = computed(() => {
168
168
  width: 100%;
169
169
  height: 100%;
170
170
  background-color: var(--color-bg);
171
- border-radius: 28px;
171
+ border-radius: 1.75rem;
172
172
  overflow: hidden;
173
173
  }
174
174
 
@@ -189,11 +189,11 @@ const displayUrl = computed(() => {
189
189
 
190
190
  .macbook-screen {
191
191
  position: relative;
192
- width: 560px;
192
+ width: 35rem;
193
193
  background-color: var(--color-drac-fg-900);
194
- border-radius: 12px 12px 0 0;
195
- padding: 8px 8px 0 8px;
196
- box-shadow: 0 -2px 20px color-mix(in srgb, var(--color-black) 20%, transparent);
194
+ border-radius: 0.75rem 0.75rem 0 0;
195
+ padding: 0.5rem 0.5rem 0 0.5rem;
196
+ box-shadow: 0 -0.125rem 1.25rem color-mix(in srgb, var(--color-black) 20%, transparent);
197
197
  }
198
198
 
199
199
  .dark .macbook-screen {
@@ -201,11 +201,11 @@ const displayUrl = computed(() => {
201
201
  }
202
202
 
203
203
  .macbook-camera {
204
- width: 8px;
205
- height: 8px;
204
+ width: 0.5rem;
205
+ height: 0.5rem;
206
206
  background-color: var(--color-drac-fg-700);
207
207
  border-radius: 50%;
208
- margin: 4px auto 8px auto;
208
+ margin: 0.25rem auto 0.5rem auto;
209
209
  }
210
210
 
211
211
  .dark .macbook-camera {
@@ -216,7 +216,7 @@ const displayUrl = computed(() => {
216
216
  width: 100%;
217
217
  aspect-ratio: 16 / 10;
218
218
  background-color: var(--color-bg);
219
- border-radius: 4px 4px 0 0;
219
+ border-radius: 0.25rem 0.25rem 0 0;
220
220
  overflow: hidden;
221
221
  }
222
222
 
@@ -227,10 +227,10 @@ const displayUrl = computed(() => {
227
227
  }
228
228
 
229
229
  .macbook-base {
230
- width: 620px;
231
- height: 14px;
230
+ width: 38.75rem;
231
+ height: 0.875rem;
232
232
  background: linear-gradient(to bottom, var(--color-drac-fg-300) 0%, var(--color-drac-fg-400) 100%);
233
- border-radius: 0 0 8px 8px;
233
+ border-radius: 0 0 0.5rem 0.5rem;
234
234
  display: flex;
235
235
  justify-content: center;
236
236
  align-items: flex-start;
@@ -241,10 +241,10 @@ const displayUrl = computed(() => {
241
241
  }
242
242
 
243
243
  .macbook-notch {
244
- width: 80px;
245
- height: 4px;
244
+ width: 5rem;
245
+ height: 0.25rem;
246
246
  background-color: var(--color-drac-fg-500);
247
- border-radius: 0 0 4px 4px;
247
+ border-radius: 0 0 0.25rem 0.25rem;
248
248
  }
249
249
 
250
250
  .dark .macbook-notch {
@@ -256,35 +256,35 @@ const displayUrl = computed(() => {
256
256
  ============================================ */
257
257
  .browser-frame {
258
258
  width: 100%;
259
- max-width: 640px;
259
+ max-width: 40rem;
260
260
  background-color: var(--color-bg-soft);
261
- border: 1px solid var(--color-border);
262
- border-radius: 8px;
261
+ border: var(--border-thin) solid var(--color-border);
262
+ border-radius: 0.5rem;
263
263
  overflow: hidden;
264
- box-shadow: 0 4px 20px color-mix(in srgb, var(--color-black) 10%, transparent);
264
+ box-shadow: 0 0.25rem 1.25rem color-mix(in srgb, var(--color-black) 10%, transparent);
265
265
  }
266
266
 
267
267
  .dark .browser-frame {
268
- box-shadow: 0 4px 20px color-mix(in srgb, var(--color-black) 30%, transparent);
268
+ box-shadow: 0 0.25rem 1.25rem color-mix(in srgb, var(--color-black) 30%, transparent);
269
269
  }
270
270
 
271
271
  .browser-toolbar {
272
272
  display: flex;
273
273
  align-items: center;
274
- gap: 12px;
275
- padding: 10px 12px;
274
+ gap: 0.75rem;
275
+ padding: 0.625rem 0.75rem;
276
276
  background-color: var(--color-bg-muted);
277
- border-bottom: 1px solid var(--color-border);
277
+ border-bottom: var(--border-thin) solid var(--color-border);
278
278
  }
279
279
 
280
280
  .browser-buttons {
281
281
  display: flex;
282
- gap: 6px;
282
+ gap: 0.375rem;
283
283
  }
284
284
 
285
285
  .browser-btn {
286
- width: 12px;
287
- height: 12px;
286
+ width: 0.75rem;
287
+ height: 0.75rem;
288
288
  border-radius: 50%;
289
289
  }
290
290
 
@@ -304,17 +304,17 @@ const displayUrl = computed(() => {
304
304
  flex: 1;
305
305
  display: flex;
306
306
  align-items: center;
307
- gap: 6px;
308
- padding: 6px 12px;
307
+ gap: 0.375rem;
308
+ padding: 0.375rem 0.75rem;
309
309
  background-color: var(--color-bg);
310
- border-radius: 6px;
310
+ border-radius: 0.375rem;
311
311
  font-size: 0.75rem;
312
312
  color: var(--color-text-secondary);
313
313
  }
314
314
 
315
315
  .browser-lock {
316
- width: 12px;
317
- height: 12px;
316
+ width: 0.75rem;
317
+ height: 0.75rem;
318
318
  opacity: 0.6;
319
319
  }
320
320
 
@@ -344,30 +344,30 @@ const displayUrl = computed(() => {
344
344
  ============================================ */
345
345
  .tablet-frame {
346
346
  position: relative;
347
- width: 500px;
348
- height: 360px;
347
+ width: 31.25rem;
348
+ height: 22.5rem;
349
349
  background-color: var(--color-drac-fg-900);
350
- border-radius: 20px;
351
- padding: 16px;
350
+ border-radius: 1.25rem;
351
+ padding: 1rem;
352
352
  box-shadow:
353
- 0 0 0 2px var(--color-drac-fg-700),
354
- 0 20px 40px color-mix(in srgb, var(--color-black) 30%, transparent);
353
+ 0 0 0 0.125rem var(--color-drac-fg-700),
354
+ 0 1.25rem 2.5rem color-mix(in srgb, var(--color-black) 30%, transparent);
355
355
  }
356
356
 
357
357
  .dark .tablet-frame {
358
358
  background-color: var(--color-drac-fg-800);
359
359
  box-shadow:
360
- 0 0 0 2px var(--color-drac-fg-600),
361
- 0 20px 40px color-mix(in srgb, var(--color-black) 50%, transparent);
360
+ 0 0 0 0.125rem var(--color-drac-fg-600),
361
+ 0 1.25rem 2.5rem color-mix(in srgb, var(--color-black) 50%, transparent);
362
362
  }
363
363
 
364
364
  .tablet-camera {
365
365
  position: absolute;
366
366
  left: 50%;
367
- top: 6px;
367
+ top: 0.375rem;
368
368
  transform: translateX(-50%);
369
- width: 8px;
370
- height: 8px;
369
+ width: 0.5rem;
370
+ height: 0.5rem;
371
371
  background-color: var(--color-drac-fg-700);
372
372
  border-radius: 50%;
373
373
  }
@@ -380,7 +380,7 @@ const displayUrl = computed(() => {
380
380
  width: 100%;
381
381
  height: 100%;
382
382
  background-color: var(--color-bg);
383
- border-radius: 4px;
383
+ border-radius: 0.25rem;
384
384
  overflow: hidden;
385
385
  }
386
386
 
@@ -49,11 +49,11 @@ defineProps<{
49
49
  }
50
50
 
51
51
  .image-border {
52
- border: 1px solid var(--color-border);
52
+ border: var(--border-thin) solid var(--color-border);
53
53
  }
54
54
 
55
55
  .image-shadow {
56
- box-shadow: 0 4px 12px color-mix(in srgb, var(--color-black) 15%, transparent);
56
+ box-shadow: 0 0.25rem 0.75rem color-mix(in srgb, var(--color-black) 15%, transparent);
57
57
  }
58
58
 
59
59
  .image-rounded {
@@ -368,46 +368,46 @@ onUnmounted(() => {
368
368
  .image-compare-horizontal .image-compare-slider {
369
369
  top: 0;
370
370
  bottom: 0;
371
- width: 4px;
372
- margin-left: -2px;
371
+ width: 0.25rem;
372
+ margin-left: -0.125rem;
373
373
  background-color: var(--color-drac-fg-50);
374
- box-shadow: 0 0 4px color-mix(in srgb, var(--color-black) 30%, transparent);
374
+ box-shadow: 0 0 0.25rem color-mix(in srgb, var(--color-black) 30%, transparent);
375
375
  }
376
376
 
377
377
  .image-compare-vertical .image-compare-slider {
378
378
  left: 0;
379
379
  right: 0;
380
- height: 4px;
381
- margin-top: -2px;
380
+ height: 0.25rem;
381
+ margin-top: -0.125rem;
382
382
  background-color: var(--color-drac-fg-50);
383
- box-shadow: 0 0 4px color-mix(in srgb, var(--color-black) 30%, transparent);
383
+ box-shadow: 0 0 0.25rem color-mix(in srgb, var(--color-black) 30%, transparent);
384
384
  }
385
385
 
386
386
  /* Handle */
387
387
  .image-compare-handle {
388
388
  position: absolute;
389
- width: 44px;
390
- height: 44px;
389
+ width: 2.75rem;
390
+ height: 2.75rem;
391
391
  background-color: var(--color-drac-fg-50);
392
392
  border-radius: 50%;
393
- box-shadow: 0 2px 8px color-mix(in srgb, var(--color-black) 30%, transparent);
393
+ box-shadow: 0 0.125rem 0.5rem color-mix(in srgb, var(--color-black) 30%, transparent);
394
394
  display: flex;
395
395
  align-items: center;
396
396
  justify-content: center;
397
397
  }
398
398
 
399
399
  .image-compare-arrow {
400
- width: 16px;
401
- height: 16px;
400
+ width: 1rem;
401
+ height: 1rem;
402
402
  color: var(--color-text);
403
403
  }
404
404
 
405
405
  .image-compare-horizontal .image-compare-arrow-left {
406
- margin-right: -2px;
406
+ margin-right: -0.125rem;
407
407
  }
408
408
 
409
409
  .image-compare-horizontal .image-compare-arrow-right {
410
- margin-left: -2px;
410
+ margin-left: -0.125rem;
411
411
  }
412
412
 
413
413
  .image-compare-vertical .image-compare-handle {
@@ -416,21 +416,21 @@ onUnmounted(() => {
416
416
 
417
417
  .image-compare-vertical .image-compare-arrow-left {
418
418
  transform: rotate(90deg);
419
- margin-bottom: -2px;
419
+ margin-bottom: -0.125rem;
420
420
  }
421
421
 
422
422
  .image-compare-vertical .image-compare-arrow-right {
423
423
  transform: rotate(90deg);
424
- margin-top: -2px;
424
+ margin-top: -0.125rem;
425
425
  }
426
426
 
427
427
  /* Focus styles */
428
428
  .image-compare-slider:focus {
429
- outline: 3px solid var(--color-primary);
430
- outline-offset: 2px;
429
+ outline: var(--border-thick) solid var(--color-primary);
430
+ outline-offset: var(--border-medium);
431
431
  }
432
432
 
433
433
  .image-compare-slider:focus .image-compare-handle {
434
- border: 2px solid var(--color-primary);
434
+ border: var(--border-medium) solid var(--color-primary);
435
435
  }
436
436
  </style>
@@ -58,7 +58,7 @@ defineProps<{
58
58
  }
59
59
 
60
60
  .matrix-cell {
61
- border: 1px solid var(--color-border);
61
+ border: var(--border-thin) solid var(--color-border);
62
62
  border-radius: 0.5rem;
63
63
  padding: var(--space-xs);
64
64
  }
@@ -283,7 +283,7 @@ const warning = computed<string | null>(() => {
283
283
  .mermaid-chart-warning {
284
284
  align-self: stretch;
285
285
  padding: 0.375rem 0.75rem;
286
- border-left: 3px solid var(--color-danger);
286
+ border-left: var(--border-thick) solid var(--color-danger);
287
287
  background: var(--color-danger-tint);
288
288
  color: var(--color-danger);
289
289
  font-size: var(--font-size-small);
@@ -106,7 +106,7 @@ const sizeClasses: Record<string, string> = {
106
106
  padding: var(--space-md);
107
107
  background: var(--color-bg-soft);
108
108
  border-radius: 0.5rem;
109
- border: 1px solid var(--color-border);
109
+ border: var(--border-thin) solid var(--color-border);
110
110
  }
111
111
 
112
112
  .metric-bare {
@@ -78,24 +78,24 @@ const colorVar: Record<string, string> = {
78
78
  .pricing-plan {
79
79
  flex: 1;
80
80
  background: var(--color-bg-soft);
81
- border: 1px solid var(--color-border);
81
+ border: var(--border-thin) solid var(--color-border);
82
82
  border-radius: 0.5rem;
83
83
  padding: var(--space-md);
84
84
  }
85
85
 
86
86
  .pricing-plan-highlighted {
87
87
  border-color: var(--color-primary);
88
- border-width: 2px;
88
+ border-width: var(--border-medium);
89
89
  transform: scale(1.03);
90
- box-shadow: 0 4px 16px color-mix(in srgb, var(--color-black) 10%, transparent);
90
+ box-shadow: 0 0.25rem 1rem color-mix(in srgb, var(--color-black) 10%, transparent);
91
91
  }
92
92
 
93
93
  .dark .pricing-plan-highlighted {
94
- box-shadow: 0 4px 16px color-mix(in srgb, var(--color-black) 30%, transparent);
94
+ box-shadow: 0 0.25rem 1rem color-mix(in srgb, var(--color-black) 30%, transparent);
95
95
  }
96
96
 
97
97
  .pricing-plan-header {
98
- border-bottom: 2px solid var(--color-border);
98
+ border-bottom: var(--border-medium) solid var(--color-border);
99
99
  padding-bottom: var(--space-xs);
100
100
  margin-bottom: var(--space-sm);
101
101
  }
@@ -73,7 +73,7 @@ const barStyle = computed(() => {
73
73
  }
74
74
 
75
75
  .progress-bar {
76
- height: 3px;
76
+ height: 0.1875rem;
77
77
  background-color: var(--color-primary);
78
78
  opacity: 0.8;
79
79
  transition: width var(--dur-moderate-01) var(--ease-standard);
@@ -66,7 +66,7 @@ function levelFontSize(index: number, total: number): string {
66
66
  .pyramid-level {
67
67
  flex: 1;
68
68
  text-align: center;
69
- border-top: 3px solid;
69
+ border-top: var(--border-thick) solid;
70
70
  padding-top: var(--space-xs);
71
71
  }
72
72
 
@@ -23,7 +23,7 @@ const props = withDefaults(defineProps<{
23
23
  color?: string // Semantic color name (primary, success, accent, etc.) or 'text' (default)
24
24
  bgColor?: string // Semantic bg name (bg, bg-soft, bg-muted) or omit for 'bg' (default)
25
25
  }>(), {
26
- size: 200
26
+ size: 400
27
27
  })
28
28
 
29
29
  const isDark = useIsDark()
@@ -53,7 +53,7 @@ const bubbleStyle = computed(() => {
53
53
  display: inline-block;
54
54
  padding: 1rem 1.25rem;
55
55
  background-color: var(--bubble-bg);
56
- border: 1px solid var(--bubble-border);
56
+ border: var(--border-thin) solid var(--bubble-border);
57
57
  border-radius: 1rem;
58
58
  max-width: 100%;
59
59
  margin-bottom: var(--space-sm);
@@ -71,9 +71,9 @@ const bubbleStyle = computed(() => {
71
71
  .bubble-speech.bubble-bottom::after {
72
72
  content: '';
73
73
  position: absolute;
74
- bottom: -12px;
75
- left: 23px;
76
- border-width: 13px 9px 0 9px;
74
+ bottom: -0.75rem;
75
+ left: 1.4375rem;
76
+ border-width: 0.8125rem 0.5625rem 0 0.5625rem;
77
77
  border-style: solid;
78
78
  border-color: var(--bubble-bg) transparent transparent transparent;
79
79
  }
@@ -81,9 +81,9 @@ const bubbleStyle = computed(() => {
81
81
  .bubble-speech.bubble-bottom::before {
82
82
  content: '';
83
83
  position: absolute;
84
- bottom: -13px;
85
- left: 23px;
86
- border-width: 13px 9px 0 9px;
84
+ bottom: -0.8125rem;
85
+ left: 1.4375rem;
86
+ border-width: 0.8125rem 0.5625rem 0 0.5625rem;
87
87
  border-style: solid;
88
88
  border-color: var(--bubble-border) transparent transparent transparent;
89
89
  }
@@ -91,9 +91,9 @@ const bubbleStyle = computed(() => {
91
91
  .bubble-speech.bubble-top::after {
92
92
  content: '';
93
93
  position: absolute;
94
- top: -12px;
95
- left: 23px;
96
- border-width: 0 9px 13px 9px;
94
+ top: -0.75rem;
95
+ left: 1.4375rem;
96
+ border-width: 0 0.5625rem 0.8125rem 0.5625rem;
97
97
  border-style: solid;
98
98
  border-color: transparent transparent var(--bubble-bg) transparent;
99
99
  }
@@ -101,9 +101,9 @@ const bubbleStyle = computed(() => {
101
101
  .bubble-speech.bubble-top::before {
102
102
  content: '';
103
103
  position: absolute;
104
- top: -13px;
105
- left: 23px;
106
- border-width: 0 9px 13px 9px;
104
+ top: -0.8125rem;
105
+ left: 1.4375rem;
106
+ border-width: 0 0.5625rem 0.8125rem 0.5625rem;
107
107
  border-style: solid;
108
108
  border-color: transparent transparent var(--bubble-border) transparent;
109
109
  }
@@ -111,9 +111,9 @@ const bubbleStyle = computed(() => {
111
111
  .bubble-speech.bubble-left::after {
112
112
  content: '';
113
113
  position: absolute;
114
- left: -12px;
115
- top: 15px;
116
- border-width: 9px 13px 9px 0;
114
+ left: -0.75rem;
115
+ top: 0.9375rem;
116
+ border-width: 0.5625rem 0.8125rem 0.5625rem 0;
117
117
  border-style: solid;
118
118
  border-color: transparent var(--bubble-bg) transparent transparent;
119
119
  }
@@ -121,9 +121,9 @@ const bubbleStyle = computed(() => {
121
121
  .bubble-speech.bubble-left::before {
122
122
  content: '';
123
123
  position: absolute;
124
- left: -13px;
125
- top: 15px;
126
- border-width: 9px 13px 9px 0;
124
+ left: -0.8125rem;
125
+ top: 0.9375rem;
126
+ border-width: 0.5625rem 0.8125rem 0.5625rem 0;
127
127
  border-style: solid;
128
128
  border-color: transparent var(--bubble-border) transparent transparent;
129
129
  }
@@ -131,9 +131,9 @@ const bubbleStyle = computed(() => {
131
131
  .bubble-speech.bubble-right::after {
132
132
  content: '';
133
133
  position: absolute;
134
- right: -12px;
135
- top: 15px;
136
- border-width: 9px 0 9px 13px;
134
+ right: -0.75rem;
135
+ top: 0.9375rem;
136
+ border-width: 0.5625rem 0 0.5625rem 0.8125rem;
137
137
  border-style: solid;
138
138
  border-color: transparent transparent transparent var(--bubble-bg);
139
139
  }
@@ -141,9 +141,9 @@ const bubbleStyle = computed(() => {
141
141
  .bubble-speech.bubble-right::before {
142
142
  content: '';
143
143
  position: absolute;
144
- right: -13px;
145
- top: 15px;
146
- border-width: 9px 0 9px 13px;
144
+ right: -0.8125rem;
145
+ top: 0.9375rem;
146
+ border-width: 0.5625rem 0 0.5625rem 0.8125rem;
147
147
  border-style: solid;
148
148
  border-color: transparent transparent transparent var(--bubble-border);
149
149
  }
@@ -154,16 +154,16 @@ const bubbleStyle = computed(() => {
154
154
  content: '';
155
155
  position: absolute;
156
156
  background-color: var(--bubble-bg);
157
- border: 1px solid var(--bubble-border);
157
+ border: var(--border-thin) solid var(--bubble-border);
158
158
  border-radius: 50%;
159
159
  }
160
160
 
161
- .bubble-thought.bubble-bottom::after { width: 16px; height: 16px; bottom: -10px; left: 32px; }
162
- .bubble-thought.bubble-bottom::before { width: 10px; height: 10px; bottom: -20px; left: 24px; }
163
- .bubble-thought.bubble-top::after { width: 16px; height: 16px; top: -10px; left: 32px; }
164
- .bubble-thought.bubble-top::before { width: 10px; height: 10px; top: -20px; left: 24px; }
165
- .bubble-thought.bubble-left::after { width: 16px; height: 16px; left: -10px; top: 20px; }
166
- .bubble-thought.bubble-left::before { width: 10px; height: 10px; left: -22px; top: 16px; }
167
- .bubble-thought.bubble-right::after { width: 16px; height: 16px; right: -10px; top: 20px; }
168
- .bubble-thought.bubble-right::before { width: 10px; height: 10px; right: -22px; top: 16px; }
161
+ .bubble-thought.bubble-bottom::after { width: 1rem; height: 1rem; bottom: -0.625rem; left: 2rem; }
162
+ .bubble-thought.bubble-bottom::before { width: 0.625rem; height: 0.625rem; bottom: -1.25rem; left: 1.5rem; }
163
+ .bubble-thought.bubble-top::after { width: 1rem; height: 1rem; top: -0.625rem; left: 2rem; }
164
+ .bubble-thought.bubble-top::before { width: 0.625rem; height: 0.625rem; top: -1.25rem; left: 1.5rem; }
165
+ .bubble-thought.bubble-left::after { width: 1rem; height: 1rem; left: -0.625rem; top: 1.25rem; }
166
+ .bubble-thought.bubble-left::before { width: 0.625rem; height: 0.625rem; left: -1.375rem; top: 1rem; }
167
+ .bubble-thought.bubble-right::after { width: 1rem; height: 1rem; right: -0.625rem; top: 1.25rem; }
168
+ .bubble-thought.bubble-right::before { width: 0.625rem; height: 0.625rem; right: -1.375rem; top: 1rem; }
169
169
  </style>
@@ -238,7 +238,7 @@ function isUpcoming(index: number) {
238
238
  display: flex;
239
239
  flex-direction: column;
240
240
  width: 100%;
241
- padding: 4px;
241
+ padding: 0.25rem;
242
242
  }
243
243
 
244
244
  /* ===== Track ===== */
@@ -310,7 +310,7 @@ function isUpcoming(index: number) {
310
310
 
311
311
  .stepper-dots .stepper-step.is-active .stepper-marker {
312
312
  background-color: var(--stepper-color);
313
- box-shadow: 0 0 0 3px color-mix(in srgb, var(--stepper-color) 30%, transparent);
313
+ box-shadow: 0 0 0 0.1875rem color-mix(in srgb, var(--stepper-color) 30%, transparent);
314
314
  }
315
315
 
316
316
  .stepper-dots .stepper-step.is-completed .stepper-marker {
@@ -408,11 +408,11 @@ function isUpcoming(index: number) {
408
408
  /* Horizontal connectors */
409
409
 
410
410
  .stepper-horizontal .stepper-connector {
411
- height: 2px;
411
+ height: 0.125rem;
412
412
  flex: 0 0 2rem;
413
413
  background-color: var(--color-border);
414
414
  overflow: hidden;
415
- margin-top: calc(var(--stepper-marker-size) / 2 - 1px);
415
+ margin-top: calc(var(--stepper-marker-size) / 2 - 0.0625rem);
416
416
  }
417
417
 
418
418
  /* dots: same margin-top formula from parent rule applies */
@@ -461,11 +461,11 @@ function isUpcoming(index: number) {
461
461
  /* Vertical connectors */
462
462
 
463
463
  .stepper-vertical .stepper-connector {
464
- width: 2px;
464
+ width: 0.125rem;
465
465
  min-height: 1rem;
466
466
  flex: 0 0 auto;
467
467
  background-color: var(--color-border);
468
- margin-left: calc(var(--stepper-marker-size) / 2 - 1px);
468
+ margin-left: calc(var(--stepper-marker-size) / 2 - 0.0625rem);
469
469
  margin-top: 0.25rem;
470
470
  margin-bottom: 0.25rem;
471
471
  }
@@ -532,11 +532,11 @@ function isUpcoming(index: number) {
532
532
 
533
533
  .stepper-panel-enter-from {
534
534
  opacity: 0;
535
- transform: translateY(var(--shift-sm, 12px));
535
+ transform: translateY(var(--shift-sm, 0.75rem));
536
536
  }
537
537
 
538
538
  .stepper-panel-leave-to {
539
539
  opacity: 0;
540
- transform: translateY(calc(var(--shift-xs, 8px) * -1));
540
+ transform: translateY(calc(var(--shift-xs, 0.375rem) * -1));
541
541
  }
542
542
  </style>
@@ -207,8 +207,8 @@ const sizeMap: Record<string, string> = {
207
207
  }
208
208
 
209
209
  .is-spoiler:focus-visible {
210
- outline: 3px solid var(--color-primary);
211
- outline-offset: 2px;
210
+ outline: var(--border-thick) solid var(--color-primary);
211
+ outline-offset: var(--border-medium);
212
212
  }
213
213
 
214
214
  .is-spoiler-revealed {
@@ -255,7 +255,7 @@ const sizeMap: Record<string, string> = {
255
255
  background-color: color-mix(in srgb, var(--text-highlight-bg) 20%, transparent);
256
256
  padding: 0.1em 0.25em;
257
257
  border-radius: 0.2em;
258
- border-bottom: 2px solid var(--text-highlight-bg);
258
+ border-bottom: var(--border-medium) solid var(--text-highlight-bg);
259
259
  margin: 0 0.1em;
260
260
  }
261
261
 
@@ -264,11 +264,11 @@ const sizeMap: Record<string, string> = {
264
264
  font-family: 'IBM Plex Mono', monospace;
265
265
  font-size: 0.85em;
266
266
  background: var(--color-bg-soft);
267
- border: 1px solid var(--color-border);
268
- border-bottom-width: 2px;
267
+ border: var(--border-thin) solid var(--color-border);
268
+ border-bottom-width: var(--border-medium);
269
269
  padding: 0.1em 0.4em;
270
270
  border-radius: 0.25em;
271
- box-shadow: 0 1px 0 var(--color-border);
271
+ box-shadow: 0 0.0625rem 0 var(--color-border);
272
272
  white-space: nowrap;
273
273
  margin: 0 0.1em;
274
274
  }
@@ -96,13 +96,13 @@ const attribution = computed(() => {
96
96
  background-color: var(--color-bg-soft);
97
97
  border-radius: 0.5rem;
98
98
  padding: var(--space-lg);
99
- border: 1px solid var(--color-border);
99
+ border: var(--border-thin) solid var(--color-border);
100
100
  }
101
101
 
102
102
  /* Minimal variant */
103
103
  .testimonial-minimal {
104
104
  padding: var(--space-md) 0;
105
- border-left: 4px solid var(--color-primary);
105
+ border-left: var(--border-accent) solid var(--color-primary);
106
106
  padding-left: var(--space-md);
107
107
  }
108
108
 
@@ -131,8 +131,8 @@ const attribution = computed(() => {
131
131
 
132
132
  /* Quote icon */
133
133
  .testimonial-quote-icon {
134
- width: 48px;
135
- height: 48px;
134
+ width: 3rem;
135
+ height: 3rem;
136
136
  opacity: 0.3;
137
137
  margin-bottom: var(--space-sm);
138
138
  }
@@ -192,8 +192,8 @@ const attribution = computed(() => {
192
192
  }
193
193
 
194
194
  .testimonial-avatar {
195
- width: 48px;
196
- height: 48px;
195
+ width: 3rem;
196
+ height: 3rem;
197
197
  border-radius: 50%;
198
198
  overflow: hidden;
199
199
  flex-shrink: 0;
package/example_dark.md CHANGED
@@ -6,5 +6,6 @@ info: |
6
6
  Complete theme showcase — all layouts, components, and features
7
7
  colorSchema: dark
8
8
  transition: slide-left
9
+ canvasWidth: 1920
9
10
  src: ./example_content.md
10
11
  ---
package/example_white.md CHANGED
@@ -6,5 +6,6 @@ info: |
6
6
  Complete theme showcase — all layouts, components, and features
7
7
  colorSchema: light
8
8
  transition: slide-left
9
+ canvasWidth: 1920
9
10
  src: ./example_content.md
10
11
  ---
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@troshab/slidev-theme-troshab",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "description": "A minimal, universal Slidev theme with flexible layouts and ready-to-use slide templates",
5
5
  "author": "troshab",
6
6
  "license": "PolyForm-Noncommercial-1.0.0",
package/setup/mermaid.ts CHANGED
@@ -140,11 +140,11 @@ export default defineMermaidSetup(() => {
140
140
  pie7: colors.chart7,
141
141
  pie8: colors.chart8,
142
142
  pieStrokeColor: colors.bg,
143
- pieStrokeWidth: '2px',
143
+ pieStrokeWidth: '4px',
144
144
  pieTitleTextColor: colors.text,
145
145
  pieSectionTextColor: colors.bg,
146
146
  pieLegendTextColor: colors.text,
147
- pieOuterStrokeWidth: '2px',
147
+ pieOuterStrokeWidth: '4px',
148
148
  pieOuterStrokeColor: colors.borderStrong,
149
149
  pieOpacity: '1',
150
150
 
@@ -184,11 +184,11 @@ export default defineMermaidSetup(() => {
184
184
  gitBranchLabel7: colors.bg,
185
185
  commitLabelColor: colors.text,
186
186
  commitLabelBackground: colors.bgMuted,
187
- commitLabelFontSize: '12px',
187
+ commitLabelFontSize: '24px',
188
188
  tagLabelColor: colors.text,
189
189
  tagLabelBackground: colors.bgSoft,
190
190
  tagLabelBorder: colors.borderStrong,
191
- tagLabelFontSize: '12px',
191
+ tagLabelFontSize: '24px',
192
192
 
193
193
  // Timeline & Mindmap — both use cScale/cScaleLabel (not mindmap* vars)
194
194
  // Text on colored blocks: colors.bg contrasts in both themes
package/styles/base.css CHANGED
@@ -69,17 +69,21 @@
69
69
  ============================================ */
70
70
 
71
71
  :root {
72
+ /* Canvas: 1920×1080. 1rem = 16 × (1920/980) ≈ 31.347px so all rem values
73
+ scale proportionally from the original 980×552 design. */
74
+ font-size: 31.347px;
75
+
72
76
  /* --- Fonts --- */
73
77
  --font-sans: 'IBM Plex Sans', system-ui, -apple-system, sans-serif;
74
78
  --font-mono: 'IBM Plex Mono', 'Consolas', 'Monaco', monospace;
75
79
 
76
80
  /* --- Typography Scale (3 main + 1 small) ---
77
- h1 = 57px, h2 = 43px (also h3), body = 24px, small = 18px.
81
+ h1 = 111.7px, h2 = 84.2px (also h3), body = 47px, small = 35.3px.
78
82
  */
79
- --font-size-h1: 3.5625rem; /* 57px */
80
- --font-size-h2: 2.6875rem; /* 43px */
81
- --font-size-base: 1.5rem; /* 24px — body text */
82
- --font-size-small: 1.125rem; /* 18px — captions, labels, code */
83
+ --font-size-h1: 3.5625rem; /* 111.7px */
84
+ --font-size-h2: 2.6875rem; /* 84.2px */
85
+ --font-size-base: 1.5rem; /* 47px — body text */
86
+ --font-size-small: 1.125rem; /* 35.3px — captions, labels, code */
83
87
 
84
88
  /* --- Font Weights --- */
85
89
  --font-weight-normal: 400;
@@ -132,6 +136,12 @@
132
136
  /* --- Safe-zone for projectors/TV overscan (5% default) --- */
133
137
  --safe-inset-x: 5%;
134
138
  --safe-inset-y: 5%;
139
+
140
+ /* --- Border Width Tokens (rem-based, scale with canvas) --- */
141
+ --border-thin: 0.0625rem; /* ≈ 1px at 980 → ~2px at 1920 */
142
+ --border-medium: 0.125rem; /* ≈ 2px → ~4px */
143
+ --border-thick: 0.1875rem; /* ≈ 3px → ~6px */
144
+ --border-accent: 0.25rem; /* ≈ 4px → ~8px */
135
145
  }
136
146
 
137
147
  /* ============================================
@@ -290,7 +300,7 @@
290
300
 
291
301
  /* Border only on native Shiki code blocks (not on pre inside CodeHighlight/CodeDiff) */
292
302
  .slidev-layout pre.slidev-code {
293
- border: 1px solid var(--color-border);
303
+ border: var(--border-thin) solid var(--color-border);
294
304
  }
295
305
 
296
306
  /* Reset .slidev-layout pre overrides for CodeHighlight/CodeDiff inner pre */
@@ -305,7 +315,7 @@
305
315
  .slidev-layout pre[data-lang] {
306
316
  position: relative;
307
317
  /* Override Slidev's --slidev-code-padding (applied with !important) to make room for the label */
308
- --slidev-code-padding: 2.25rem 8px 8px 8px;
318
+ --slidev-code-padding: 2.25rem 0.5rem 0.5rem 0.5rem;
309
319
  }
310
320
 
311
321
  .slidev-layout pre[data-lang]::before {
@@ -321,7 +331,7 @@
321
331
  text-transform: uppercase;
322
332
  letter-spacing: 0.05em;
323
333
  color: var(--color-text-tertiary);
324
- border-bottom: 1px solid var(--color-border);
334
+ border-bottom: var(--border-thin) solid var(--color-border);
325
335
  background: var(--shiki-color-background, var(--color-bg-muted));
326
336
  border-radius: 0.5rem 0.5rem 0 0;
327
337
  }
@@ -358,7 +368,7 @@
358
368
  padding-right: 1rem;
359
369
  padding-top: 0.5rem;
360
370
  padding-bottom: 0.5rem;
361
- border: 1px solid var(--color-border);
371
+ border: var(--border-thin) solid var(--color-border);
362
372
  text-align: left;
363
373
  }
364
374
 
@@ -375,7 +385,7 @@
375
385
  padding-left: 1rem;
376
386
  margin-top: 1rem;
377
387
  margin-bottom: 1rem;
378
- border-left: 4px solid var(--color-border-strong);
388
+ border-left: var(--border-accent) solid var(--color-border-strong);
379
389
  color: var(--color-text-secondary);
380
390
  font-style: normal; /* No italic for readability */
381
391
  max-width: var(--measure);
@@ -434,7 +444,7 @@
434
444
  /* Overlay text: invariant (always light text on dark overlay, regardless of theme) */
435
445
  .slide-fullscreen .slide-bg:has(.bg-overlay-dark) ~ .slide-content {
436
446
  color: var(--color-drac-fg-50);
437
- text-shadow: 0 2px 4px color-mix(in srgb, var(--color-black) 30%, transparent);
447
+ text-shadow: 0 0.125rem 0.25rem color-mix(in srgb, var(--color-black) 30%, transparent);
438
448
  }
439
449
 
440
450
  .slide-fullscreen .slide-bg:has(.bg-overlay-dark) ~ .slide-content h1,
@@ -533,7 +543,7 @@
533
543
  .slide-panel .slide-bg:has(.bg-info) ~ .slide-panel-content p { color: inherit; }
534
544
 
535
545
  /* bgOverlay detection for split panels */
536
- .slide-panel .slide-bg:has(.bg-overlay-dark) ~ .slide-panel-content { color: var(--color-drac-fg-50); text-shadow: 0 2px 4px color-mix(in srgb, var(--color-black) 30%, transparent); }
546
+ .slide-panel .slide-bg:has(.bg-overlay-dark) ~ .slide-panel-content { color: var(--color-drac-fg-50); text-shadow: 0 0.125rem 0.25rem color-mix(in srgb, var(--color-black) 30%, transparent); }
537
547
  .slide-panel .slide-bg:has(.bg-overlay-dark) ~ .slide-panel-content h1,
538
548
  .slide-panel .slide-bg:has(.bg-overlay-dark) ~ .slide-panel-content h2,
539
549
  .slide-panel .slide-bg:has(.bg-overlay-dark) ~ .slide-panel-content h3,
@@ -569,7 +579,7 @@
569
579
  .slide-footnote .slide-single hr {
570
580
  margin-top: auto;
571
581
  border: none;
572
- border-top: 1px solid var(--color-border);
582
+ border-top: var(--border-thin) solid var(--color-border);
573
583
  width: 100%;
574
584
  }
575
585
 
@@ -618,7 +628,7 @@
618
628
  .slide-col-title {
619
629
  padding-bottom: var(--space-sm);
620
630
  margin-bottom: var(--space-sm);
621
- border-bottom: 2px solid var(--color-border);
631
+ border-bottom: var(--border-medium) solid var(--color-border);
622
632
  }
623
633
 
624
634
  .slide-col-title h3 {
@@ -645,7 +655,7 @@
645
655
  .slide-col-bg-info h1, .slide-col-bg-info h2, .slide-col-bg-info h3 { color: inherit; }
646
656
 
647
657
  /* Per-column border */
648
- .slide-col-border { border: 1px solid var(--color-border); border-radius: 0.5rem; padding: 1rem; }
658
+ .slide-col-border { border: var(--border-thin) solid var(--color-border); border-radius: 0.5rem; padding: 1rem; }
649
659
 
650
660
  /* --- 7c. Split Mode --- */
651
661
  .slide-split {
@@ -701,7 +711,7 @@
701
711
  margin-top: auto;
702
712
  position: relative;
703
713
  z-index: 2;
704
- border-top: 1px solid var(--color-border);
714
+ border-top: var(--border-thin) solid var(--color-border);
705
715
  }
706
716
 
707
717
  /* In padded layouts (columns, fullscreen), extend footer to full slide width */
@@ -809,7 +819,7 @@ a.btn-secondary:hover {
809
819
  content: '';
810
820
  position: absolute;
811
821
  inset: var(--safe-inset-y) var(--safe-inset-x);
812
- border: 2px dashed color-mix(in srgb, var(--color-drac-red-500) 50%, transparent);
822
+ border: var(--border-medium) dashed color-mix(in srgb, var(--color-drac-red-500) 50%, transparent);
813
823
  pointer-events: none;
814
824
  z-index: 9999;
815
825
  }
@@ -827,7 +837,7 @@ a.btn-secondary:hover {
827
837
  .safe-zone-border {
828
838
  position: absolute;
829
839
  inset: 5% 5%;
830
- border: 3px dashed var(--color-danger);
840
+ border: var(--border-thick) dashed var(--color-danger);
831
841
  border-radius: 0.5rem;
832
842
  pointer-events: none;
833
843
  }
@@ -853,7 +863,7 @@ a.btn-secondary:hover {
853
863
 
854
864
  /* Enhanced blockquote callout base style */
855
865
  .slidev-layout blockquote:has(p:first-child strong:first-child) {
856
- border-left-width: 4px;
866
+ border-left-width: var(--border-accent);
857
867
  padding: 1rem 1rem 1rem 1.25rem;
858
868
  background-color: var(--color-bg-soft);
859
869
  border-radius: 0 0.375rem 0.375rem 0;
@@ -885,8 +895,8 @@ a.btn-secondary:hover {
885
895
  ============================================ */
886
896
 
887
897
  .slidev-layout :focus-visible {
888
- outline: 3px solid var(--color-primary);
889
- outline-offset: 2px;
898
+ outline: var(--border-thick) solid var(--color-primary);
899
+ outline-offset: var(--border-medium);
890
900
  }
891
901
 
892
902
  /* Ensure focus is not obscured */
package/styles/colors.css CHANGED
@@ -280,7 +280,7 @@
280
280
  --slidev-code-font-family: var(--font-mono);
281
281
  --slidev-code-line-height: var(--line-height-code);
282
282
  --slidev-code-radius: 0.5rem;
283
- --slidev-code-padding: 8px;
283
+ --slidev-code-padding: 0.5rem;
284
284
  --shiki-token-comment: var(--color-drac-comment-700);
285
285
  --shiki-token-punctuation: var(--color-drac-pink-700);
286
286
  --shiki-token-keyword: var(--color-drac-pink-700);
@@ -389,7 +389,7 @@ html.dark {
389
389
  --slidev-code-font-family: var(--font-mono);
390
390
  --slidev-code-line-height: var(--line-height-code);
391
391
  --slidev-code-radius: 0.5rem;
392
- --slidev-code-padding: 8px;
392
+ --slidev-code-padding: 0.5rem;
393
393
  --shiki-token-comment: var(--color-drac-comment-200);
394
394
  --shiki-token-punctuation: var(--color-drac-pink-200);
395
395
  --shiki-token-keyword: var(--color-drac-pink-200);
package/styles/motion.css CHANGED
@@ -41,10 +41,10 @@
41
41
  --dur-exit-modifier: 0.8;
42
42
 
43
43
  /* --- Movement Distances --- */
44
- --shift-xs: 6px; /* subtle */
45
- --shift-sm: 12px; /* small */
46
- --shift-md: 20px; /* medium */
47
- --shift-lg: 28px; /* large */
44
+ --shift-xs: 0.375rem; /* subtle */
45
+ --shift-sm: 0.75rem; /* small */
46
+ --shift-md: 1.25rem; /* medium */
47
+ --shift-lg: 1.75rem; /* large */
48
48
 
49
49
  /* --- Scale Values --- */
50
50
  --scale-subtle: 0.985;