kmcom-nuxt-layers 2.2.13 → 2.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,1913 @@
1
+ <script setup lang="ts">
2
+ useSeoMeta({
3
+ title: 'Design System — kmcom-nuxt-layers',
4
+ description:
5
+ 'Comprehensive design system reference: typography, colors, layout grid, section components, motion components, and UI components.',
6
+ })
7
+
8
+ // Grid debug ref
9
+ const gridDebug = ref<{ toggle: () => void } | null>(null)
10
+
11
+ // Color tokens for demo
12
+ const semanticColors = ['dimmed', 'muted', 'toned', 'default', 'highlighted', 'inverted'] as const
13
+ const statusColors = ['info', 'success', 'warning', 'error'] as const
14
+ const brandColors = ['primary', 'secondary', 'neutral'] as const
15
+
16
+ // Typography weight demos
17
+ const fontWeights = [
18
+ 'font-thin',
19
+ 'font-light',
20
+ 'font-normal',
21
+ 'font-medium',
22
+ 'font-semibold',
23
+ 'font-bold',
24
+ 'font-black',
25
+ ] as const
26
+
27
+ // Sample code for CodeBlock demo
28
+ const sampleCode = `function useScreen() {
29
+ const breakpoints = useBreakpoints(breakpointsTailwind)
30
+ const isMobile = breakpoints.smaller('md')
31
+ const isDesktop = breakpoints.greaterOrEqual('lg')
32
+ return { isMobile, isDesktop }
33
+ }`
34
+
35
+ // Code samples — kept as script variables to avoid the Vue HTML lexer treating
36
+ // <!-- sequences inside {{ `` }} template literals as HTML comment nodes.
37
+ const scrollProgressCodeSample = [
38
+ '<!-- Fixed top bar -->',
39
+ '<div class="fixed top-0 left-0 right-0 z-50">',
40
+ ' <MotionScrollProgress type="linear" :height="3" />',
41
+ '</div>',
42
+ '',
43
+ '<!-- Floating circular indicator -->',
44
+ '<div class="fixed bottom-6 right-6">',
45
+ ' <MotionScrollProgress type="circular" :size="56" :stroke-width="4" :show-percentage="false" />',
46
+ '</div>',
47
+ ].join('\n')
48
+
49
+ const scrollStatsCodeSample = [
50
+ '<!-- Add during development only -->',
51
+ "<MotionScrollStats :show=\"['velocity', 'progress', 'scrollY']\" position=\"bottom-right\" />",
52
+ ].join('\n')
53
+
54
+ const layoutPageCodeSample = [
55
+ '// Standard page with grid layout + header and footer',
56
+ 'definePageMeta({',
57
+ " layout: { name: 'grid', props: { showHeader: true, showFooter: true } },",
58
+ '})',
59
+ '',
60
+ '// No chrome — content-only',
61
+ "definePageMeta({ layout: 'grid' })",
62
+ '',
63
+ '// Full-bleed / animation page — opt out entirely',
64
+ 'definePageMeta({ layout: false })',
65
+ '',
66
+ '// In the template:',
67
+ '// <LayoutPage title="About" description="Learn more." :show-header="true">',
68
+ '// <LayoutSection>...</LayoutSection>',
69
+ '// </LayoutPage>',
70
+ ].join('\n')
71
+
72
+ // Table of contents
73
+ const tocItems = [
74
+ {
75
+ id: 'typography-headlines',
76
+ label: 'Typography — Headlines',
77
+ icon: 'i-lucide-heading',
78
+ },
79
+ {
80
+ id: 'typography-controls',
81
+ label: 'Typography — Controls',
82
+ icon: 'i-lucide-type',
83
+ },
84
+ {
85
+ id: 'typography-decorative',
86
+ label: 'Typography — Decorative',
87
+ icon: 'i-lucide-pen-tool',
88
+ },
89
+ {
90
+ id: 'typography-blocks',
91
+ label: 'Typography — Blocks',
92
+ icon: 'i-lucide-code',
93
+ },
94
+ { id: 'color-system', label: 'Color System', icon: 'i-lucide-palette' },
95
+ { id: 'layout-grid', label: 'Layout Grid', icon: 'i-lucide-grid-3x3' },
96
+ { id: 'layout-page', label: 'LayoutPage', icon: 'i-lucide-file' },
97
+ {
98
+ id: 'section-components',
99
+ label: 'Section Components',
100
+ icon: 'i-lucide-image',
101
+ },
102
+ {
103
+ id: 'motion-components',
104
+ label: 'Motion Components',
105
+ icon: 'i-lucide-sparkles',
106
+ },
107
+ {
108
+ id: 'links-group',
109
+ label: 'LinksGroup',
110
+ icon: 'i-lucide-mouse-pointer-click',
111
+ },
112
+ {
113
+ id: 'ui-components',
114
+ label: 'UI Components',
115
+ icon: 'i-lucide-mouse-pointer',
116
+ },
117
+ ]
118
+
119
+ // Gallery items for section demo
120
+ const galleryItems = [
121
+ { id: 1, title: 'Item 1', color: 'bg-blue-500' },
122
+ { id: 2, title: 'Item 2', color: 'bg-green-500' },
123
+ { id: 3, title: 'Item 3', color: 'bg-purple-500' },
124
+ { id: 4, title: 'Item 4', color: 'bg-orange-500' },
125
+ { id: 5, title: 'Item 5', color: 'bg-pink-500' },
126
+ { id: 6, title: 'Item 6', color: 'bg-cyan-500' },
127
+ ]
128
+ </script>
129
+
130
+ <template>
131
+ <div class="bg-default text-default min-h-screen">
132
+ <!-- Grid Debug Overlay -->
133
+ <LayoutGridDebug ref="gridDebug" />
134
+
135
+ <UContainer class="py-8">
136
+ <div class="space-y-12">
137
+ <!-- 1. Page Header -->
138
+ <div class="flex flex-wrap items-start gap-4">
139
+ <div class="min-w-0 flex-1">
140
+ <h1 class="text-highlighted text-3xl font-bold">Design System</h1>
141
+ <p class="text-muted mt-1">
142
+ Comprehensive reference for typography, colors, layout, and components provided by
143
+ <code class="bg-elevated rounded px-1.5 py-0.5 font-mono text-sm">
144
+ kmcom-nuxt-layers </code
145
+ >.
146
+ </p>
147
+ </div>
148
+ <UButton
149
+ variant="outline"
150
+ icon="i-lucide-grid-3x3"
151
+ class="shrink-0"
152
+ @click="gridDebug?.toggle()"
153
+ >
154
+ Grid Debug
155
+ <UKbd class="ml-2">⌘G</UKbd>
156
+ </UButton>
157
+ </div>
158
+
159
+ <!-- 2. Table of Contents -->
160
+ <nav class="not-prose">
161
+ <div class="grid gap-1.5 sm:grid-cols-2 lg:grid-cols-3">
162
+ <a
163
+ v-for="item in tocItems"
164
+ :key="item.id"
165
+ :href="`#${item.id}`"
166
+ class="bg-elevated hover:bg-muted/10 group flex items-center gap-3 rounded-lg px-3 py-2 transition-colors"
167
+ >
168
+ <UIcon :name="item.icon" class="text-primary shrink-0" />
169
+ <span
170
+ class="text-highlighted group-hover:text-primary text-sm font-medium transition-colors"
171
+ >{{ item.label }}</span
172
+ >
173
+ </a>
174
+ </div>
175
+ </nav>
176
+
177
+ <!-- 3. Typography — Headlines -->
178
+ <section id="typography-headlines" class="space-y-8">
179
+ <div>
180
+ <h2 class="mb-1 text-2xl font-bold">Typography — Headlines</h2>
181
+ <p class="text-muted">Semantic h1–h6 headings with responsive sizing</p>
182
+ </div>
183
+
184
+ <UCard>
185
+ <template #header>
186
+ <div class="flex items-center gap-2">
187
+ <UIcon name="i-lucide-heading" class="text-primary" />
188
+ <h3 class="text-xl font-semibold">TypographyHeadline</h3>
189
+ </div>
190
+ <p class="text-muted mt-1 text-sm">
191
+ Use <code class="font-mono">:level</code> prop (1–6) to render semantic heading
192
+ elements
193
+ </p>
194
+ </template>
195
+
196
+ <div class="space-y-4">
197
+ <TypographyHeadline :level="1">Headline Level 1</TypographyHeadline>
198
+ <TypographyHeadline :level="2">Headline Level 2</TypographyHeadline>
199
+ <TypographyHeadline :level="3">Headline Level 3</TypographyHeadline>
200
+ <TypographyHeadline :level="4">Headline Level 4</TypographyHeadline>
201
+ <TypographyHeadline :level="5">Headline Level 5</TypographyHeadline>
202
+ <TypographyHeadline :level="6">Headline Level 6</TypographyHeadline>
203
+ </div>
204
+
205
+ <template #footer>
206
+ <TypographyCodeBlock language="vue" class="text-sm">
207
+ {{ '<TypographyHeadline :level="2">Headline Level 2</TypographyHeadline>' }}
208
+ </TypographyCodeBlock>
209
+ </template>
210
+ </UCard>
211
+ </section>
212
+
213
+ <!-- 4. Typography — Controls -->
214
+ <section id="typography-controls" class="space-y-8">
215
+ <div>
216
+ <h2 class="mb-1 text-2xl font-bold">Typography — Controls</h2>
217
+ <p class="text-muted">Font weight, slant, leading, and transform axes</p>
218
+ </div>
219
+
220
+ <UCard>
221
+ <template #header>
222
+ <div class="flex items-center gap-2">
223
+ <UIcon name="i-lucide-type" class="text-primary" />
224
+ <h3 class="text-xl font-semibold">Typography</h3>
225
+ </div>
226
+ <p class="text-muted mt-1 text-sm">
227
+ Base typography component with font axis controls
228
+ </p>
229
+ </template>
230
+
231
+ <div class="space-y-6">
232
+ <!-- Weight -->
233
+ <div>
234
+ <h4 class="text-muted mb-3 text-sm font-medium uppercase tracking-wide">
235
+ Font Weight
236
+ </h4>
237
+ <div class="space-y-2">
238
+ <Typography v-for="weight in fontWeights" :key="weight" :weight class="text-lg">
239
+ {{ weight.replace('font-', '') }} — The quick brown fox jumps over the lazy dog
240
+ </Typography>
241
+ </div>
242
+ </div>
243
+
244
+ <!-- Slant -->
245
+ <div>
246
+ <h4 class="text-muted mb-3 text-sm font-medium uppercase tracking-wide">
247
+ Font Slant
248
+ </h4>
249
+ <div class="space-y-2">
250
+ <Typography slant="normal" class="text-lg"
251
+ >Normal — The quick brown fox</Typography
252
+ >
253
+ <Typography slant="italic" class="text-lg"
254
+ >Italic — The quick brown fox</Typography
255
+ >
256
+ </div>
257
+ </div>
258
+
259
+ <!-- Leading -->
260
+ <div>
261
+ <h4 class="text-muted mb-3 text-sm font-medium uppercase tracking-wide">
262
+ Line Height (Leading)
263
+ </h4>
264
+ <div class="grid gap-4 md:grid-cols-3">
265
+ <div class="bg-elevated rounded-lg p-3">
266
+ <Typography leading="leading-tight" class="text-sm">
267
+ <strong>Tight</strong> — Lorem ipsum dolor sit amet, consectetur adipiscing
268
+ elit. Sed do eiusmod tempor.
269
+ </Typography>
270
+ </div>
271
+ <div class="bg-elevated rounded-lg p-3">
272
+ <Typography leading="leading-normal" class="text-sm">
273
+ <strong>Normal</strong> — Lorem ipsum dolor sit amet, consectetur adipiscing
274
+ elit. Sed do eiusmod tempor.
275
+ </Typography>
276
+ </div>
277
+ <div class="bg-elevated rounded-lg p-3">
278
+ <Typography leading="leading-loose" class="text-sm">
279
+ <strong>Loose</strong> — Lorem ipsum dolor sit amet, consectetur adipiscing
280
+ elit. Sed do eiusmod tempor.
281
+ </Typography>
282
+ </div>
283
+ </div>
284
+ </div>
285
+
286
+ <!-- Transform -->
287
+ <div>
288
+ <h4 class="text-muted mb-3 text-sm font-medium uppercase tracking-wide">
289
+ Text Transform
290
+ </h4>
291
+ <div class="flex flex-wrap gap-4">
292
+ <Typography transform="none">Normal Text</Typography>
293
+ <Typography transform="uppercase">Uppercase</Typography>
294
+ <Typography transform="lowercase">LOWERCASE</Typography>
295
+ <Typography transform="capitalize">capitalize each word</Typography>
296
+ </div>
297
+ </div>
298
+ </div>
299
+ </UCard>
300
+ </section>
301
+
302
+ <!-- 5. Typography — Decorative -->
303
+ <section id="typography-decorative" class="space-y-8">
304
+ <div>
305
+ <h2 class="mb-1 text-2xl font-bold">Typography — Decorative</h2>
306
+ <p class="text-muted">SVG-based text stroke for crisp outlines at any size</p>
307
+ </div>
308
+
309
+ <UCard>
310
+ <template #header>
311
+ <div class="flex items-center gap-2">
312
+ <UIcon name="i-lucide-pen-tool" class="text-primary" />
313
+ <h3 class="text-xl font-semibold">TypographyTextStroke</h3>
314
+ </div>
315
+ <p class="text-muted mt-1 text-sm">
316
+ Inherits font size and weight from parent — works at any scale
317
+ </p>
318
+ </template>
319
+
320
+ <div class="space-y-8">
321
+ <!-- Outline only -->
322
+ <div>
323
+ <h4 class="text-muted mb-3 text-sm font-medium uppercase tracking-wide">
324
+ Outline Only
325
+ </h4>
326
+ <div class="text-7xl font-bold">
327
+ <TypographyTextStroke text="Outline" :stroke-width="2" />
328
+ </div>
329
+ </div>
330
+
331
+ <!-- Fill + Stroke -->
332
+ <div>
333
+ <h4 class="text-muted mb-3 text-sm font-medium uppercase tracking-wide">
334
+ Fill + Stroke
335
+ </h4>
336
+ <div class="text-primary text-7xl font-bold">
337
+ <TypographyTextStroke
338
+ text="Filled"
339
+ :stroke-width="3"
340
+ stroke-color="var(--ui-text)"
341
+ fill="currentColor"
342
+ />
343
+ </div>
344
+ </div>
345
+
346
+ <!-- Stroke widths -->
347
+ <div>
348
+ <h4 class="text-muted mb-3 text-sm font-medium uppercase tracking-wide">
349
+ Stroke Widths
350
+ </h4>
351
+ <div class="space-y-2">
352
+ <div class="text-5xl font-bold">
353
+ <TypographyTextStroke text="1px stroke" :stroke-width="1" />
354
+ </div>
355
+ <div class="text-5xl font-bold">
356
+ <TypographyTextStroke text="2px stroke" :stroke-width="2" />
357
+ </div>
358
+ <div class="text-5xl font-bold">
359
+ <TypographyTextStroke text="4px stroke" :stroke-width="4" />
360
+ </div>
361
+ </div>
362
+ </div>
363
+
364
+ <!-- Colors -->
365
+ <div>
366
+ <h4 class="text-muted mb-3 text-sm font-medium uppercase tracking-wide">Colors</h4>
367
+ <div class="flex flex-wrap gap-6">
368
+ <div class="text-5xl font-bold">
369
+ <TypographyTextStroke text="Red" :stroke-width="2" stroke-color="red" />
370
+ </div>
371
+ <div class="text-5xl font-bold">
372
+ <TypographyTextStroke text="Blue" :stroke-width="2" stroke-color="blue" />
373
+ </div>
374
+ <div class="text-5xl font-bold">
375
+ <TypographyTextStroke
376
+ text="Multi"
377
+ :stroke-width="2"
378
+ stroke-color="purple"
379
+ fill="gold"
380
+ />
381
+ </div>
382
+ </div>
383
+ </div>
384
+
385
+ <!-- Inside Headline -->
386
+ <div>
387
+ <h4 class="text-muted mb-3 text-sm font-medium uppercase tracking-wide">
388
+ Inside Headline
389
+ </h4>
390
+ <TypographyHeadline :level="1">
391
+ <TypographyTextStroke text="Headline Stroke" tag="span" :stroke-width="2" />
392
+ </TypographyHeadline>
393
+ </div>
394
+ </div>
395
+
396
+ <template #footer>
397
+ <TypographyCodeBlock language="vue" class="text-sm">
398
+ {{ `
399
+ <h1 class="text-8xl font-bold">
400
+ <TypographyTextStroke text="Hello" :stroke-width="2" stroke-color="red" />
401
+ </h1>
402
+ ` }}
403
+ </TypographyCodeBlock>
404
+ </template>
405
+ </UCard>
406
+ </section>
407
+
408
+ <!-- 6. Typography — Blocks -->
409
+ <section id="typography-blocks" class="space-y-8">
410
+ <div>
411
+ <h2 class="mb-1 text-2xl font-bold">Typography — Blocks</h2>
412
+ <p class="text-muted">Semantic wrappers for code and quoted content</p>
413
+ </div>
414
+
415
+ <div class="grid gap-6 md:grid-cols-2">
416
+ <UCard>
417
+ <template #header>
418
+ <div class="flex items-center gap-2">
419
+ <UIcon name="i-lucide-code" class="text-primary" />
420
+ <h3 class="text-xl font-semibold">CodeBlock</h3>
421
+ </div>
422
+ <p class="text-muted mt-1 text-sm">Semantic pre/code wrapper for code snippets</p>
423
+ </template>
424
+ <TypographyCodeBlock
425
+ language="typescript"
426
+ class="rounded-lg bg-gray-900 p-4 text-sm text-gray-100"
427
+ >
428
+ {{ sampleCode }}
429
+ </TypographyCodeBlock>
430
+ </UCard>
431
+
432
+ <UCard>
433
+ <template #header>
434
+ <div class="flex items-center gap-2">
435
+ <UIcon name="i-lucide-quote" class="text-primary" />
436
+ <h3 class="text-xl font-semibold">QuoteBlock</h3>
437
+ </div>
438
+ <p class="text-muted mt-1 text-sm">Semantic blockquote wrapper</p>
439
+ </template>
440
+ <TypographyQuoteBlock class="border-primary border-l-4 pl-4 italic">
441
+ "The best way to predict the future is to create it."
442
+ <Typography tag="span" class="text-muted mt-2 block text-sm not-italic">
443
+ — Peter Drucker
444
+ </Typography>
445
+ </TypographyQuoteBlock>
446
+ </UCard>
447
+ </div>
448
+ </section>
449
+
450
+ <!-- 7. Color System -->
451
+ <section id="color-system" class="space-y-8">
452
+ <div>
453
+ <h2 class="mb-1 text-2xl font-bold">Color System</h2>
454
+ <p class="text-muted">Semantic, status, brand, and accent color tokens</p>
455
+ </div>
456
+
457
+ <UCard>
458
+ <template #header>
459
+ <div class="flex items-center gap-2">
460
+ <UIcon name="i-lucide-palette" class="text-primary" />
461
+ <h3 class="text-xl font-semibold">Color Tokens</h3>
462
+ </div>
463
+ <p class="text-muted mt-1 text-sm">
464
+ Text, background, and border usage types across the design system
465
+ </p>
466
+ </template>
467
+
468
+ <div class="space-y-6">
469
+ <!-- Semantic Colors -->
470
+ <div>
471
+ <h4 class="text-muted mb-3 text-sm font-medium uppercase tracking-wide">
472
+ Semantic (dimmed → inverted)
473
+ </h4>
474
+ <div class="flex flex-wrap gap-3">
475
+ <div
476
+ v-for="color in semanticColors"
477
+ :key="color"
478
+ class="border-default rounded-lg border px-4 py-2"
479
+ >
480
+ <Typography :color weight="font-medium">{{ color }}</Typography>
481
+ </div>
482
+ </div>
483
+ </div>
484
+
485
+ <!-- Status Colors -->
486
+ <div>
487
+ <h4 class="text-muted mb-3 text-sm font-medium uppercase tracking-wide">Status</h4>
488
+ <div class="flex flex-wrap gap-3">
489
+ <UBadge v-for="color in statusColors" :key="color" :color size="lg">
490
+ {{ color }}
491
+ </UBadge>
492
+ </div>
493
+ </div>
494
+
495
+ <!-- Brand Colors -->
496
+ <div>
497
+ <h4 class="text-muted mb-3 text-sm font-medium uppercase tracking-wide">Brand</h4>
498
+ <div class="flex flex-wrap gap-3">
499
+ <UBadge v-for="color in brandColors" :key="color" :color size="lg">
500
+ {{ color }}
501
+ </UBadge>
502
+ <div class="rounded-full px-3 py-1.5 text-sm font-medium">
503
+ <Typography color="accent" weight="font-medium">accent</Typography>
504
+ </div>
505
+ </div>
506
+ </div>
507
+
508
+ <!-- Base Colors -->
509
+ <div>
510
+ <h4 class="text-muted mb-3 text-sm font-medium uppercase tracking-wide">Base</h4>
511
+ <div class="flex flex-wrap gap-3">
512
+ <div class="rounded-lg bg-black px-4 py-2 text-sm font-medium text-white">
513
+ black
514
+ </div>
515
+ <div
516
+ class="border-default rounded-lg border bg-white px-4 py-2 text-sm font-medium text-black"
517
+ >
518
+ white
519
+ </div>
520
+ </div>
521
+ </div>
522
+ </div>
523
+ </UCard>
524
+ </section>
525
+
526
+ <!-- 8. Layout Grid -->
527
+ <section id="layout-grid" class="space-y-8">
528
+ <div>
529
+ <h2 class="mb-1 text-2xl font-bold">Layout Grid</h2>
530
+ <p class="text-muted">
531
+ 18-column Swiss grid with subgrid support and responsive values
532
+ </p>
533
+ </div>
534
+
535
+ <UCard>
536
+ <template #header>
537
+ <div class="flex items-center gap-2">
538
+ <UIcon name="i-lucide-grid-3x3" class="text-primary" />
539
+ <h3 class="text-xl font-semibold">LayoutGridItem</h3>
540
+ </div>
541
+ <p class="text-muted mt-1 text-sm">
542
+ Position content on the 18-column grid with responsive values
543
+ </p>
544
+ </template>
545
+
546
+ <div class="space-y-6">
547
+ <!-- Visual demo -->
548
+ <div>
549
+ <h4 class="text-muted mb-3 text-sm font-medium uppercase tracking-wide">
550
+ Responsive Column Spans
551
+ </h4>
552
+ <div class="bg-elevated space-y-2 rounded-lg p-4">
553
+ <div class="grid-cols-18 grid gap-1">
554
+ <div class="col-span-6 rounded bg-blue-500/20 p-2 text-center text-xs">
555
+ 6 cols (mobile)
556
+ </div>
557
+ <div
558
+ class="col-span-6 rounded bg-blue-500/10 p-2 text-center text-xs opacity-50"
559
+ >
560
+ ...
561
+ </div>
562
+ <div
563
+ class="col-span-6 rounded bg-blue-500/10 p-2 text-center text-xs opacity-50"
564
+ >
565
+ ...
566
+ </div>
567
+ </div>
568
+ <div class="grid-cols-18 grid gap-1">
569
+ <div class="col-span-9 rounded bg-green-500/20 p-2 text-center text-xs">
570
+ 9 cols (tablet)
571
+ </div>
572
+ <div
573
+ class="col-span-9 rounded bg-green-500/10 p-2 text-center text-xs opacity-50"
574
+ >
575
+ ...
576
+ </div>
577
+ </div>
578
+ <div class="grid-cols-18 grid gap-1">
579
+ <div class="col-span-12 rounded bg-purple-500/20 p-2 text-center text-xs">
580
+ 12 cols (desktop)
581
+ </div>
582
+ <div
583
+ class="col-span-6 rounded bg-purple-500/10 p-2 text-center text-xs opacity-50"
584
+ >
585
+ ...
586
+ </div>
587
+ </div>
588
+ </div>
589
+ </div>
590
+
591
+ <!-- Props Table -->
592
+ <div>
593
+ <h4 class="text-muted mb-3 text-sm font-medium uppercase tracking-wide">
594
+ Available Props
595
+ </h4>
596
+ <div class="overflow-x-auto">
597
+ <table class="w-full text-sm">
598
+ <thead>
599
+ <tr class="border-default border-b">
600
+ <th class="px-3 py-2 text-left">Prop</th>
601
+ <th class="px-3 py-2 text-left">Type</th>
602
+ <th class="px-3 py-2 text-left">Description</th>
603
+ </tr>
604
+ </thead>
605
+ <tbody class="divide-default divide-y">
606
+ <tr>
607
+ <td class="px-3 py-2 font-mono text-xs">colStart</td>
608
+ <td class="px-3 py-2 font-mono text-xs">number | ResponsiveValue</td>
609
+ <td class="text-muted px-3 py-2">Starting column (1–18)</td>
610
+ </tr>
611
+ <tr>
612
+ <td class="px-3 py-2 font-mono text-xs">colSpan</td>
613
+ <td class="px-3 py-2 font-mono text-xs">number | ResponsiveValue</td>
614
+ <td class="text-muted px-3 py-2">Number of columns to span</td>
615
+ </tr>
616
+ <tr>
617
+ <td class="px-3 py-2 font-mono text-xs">rowStart</td>
618
+ <td class="px-3 py-2 font-mono text-xs">number | ResponsiveValue</td>
619
+ <td class="text-muted px-3 py-2">Starting row (1–12)</td>
620
+ </tr>
621
+ <tr>
622
+ <td class="px-3 py-2 font-mono text-xs">rowSpan</td>
623
+ <td class="px-3 py-2 font-mono text-xs">number | ResponsiveValue</td>
624
+ <td class="text-muted px-3 py-2">Number of rows to span</td>
625
+ </tr>
626
+ <tr>
627
+ <td class="px-3 py-2 font-mono text-xs">align</td>
628
+ <td class="px-3 py-2 font-mono text-xs">
629
+ 'start' | 'center' | 'end' | 'stretch'
630
+ </td>
631
+ <td class="text-muted px-3 py-2">Vertical alignment</td>
632
+ </tr>
633
+ <tr>
634
+ <td class="px-3 py-2 font-mono text-xs">justify</td>
635
+ <td class="px-3 py-2 font-mono text-xs">
636
+ 'start' | 'center' | 'end' | 'stretch'
637
+ </td>
638
+ <td class="text-muted px-3 py-2">Horizontal alignment</td>
639
+ </tr>
640
+ <tr>
641
+ <td class="px-3 py-2 font-mono text-xs">layer</td>
642
+ <td class="px-3 py-2 font-mono text-xs">
643
+ 'back' | 'mid' | 'front' | 'top'
644
+ </td>
645
+ <td class="text-muted px-3 py-2">Z-index layer (0, 10, 20, 30)</td>
646
+ </tr>
647
+ <tr>
648
+ <td class="px-3 py-2 font-mono text-xs">bleed</td>
649
+ <td class="px-3 py-2 font-mono text-xs">'left' | 'right' | 'both'</td>
650
+ <td class="text-muted px-3 py-2">Edge-to-edge bleed</td>
651
+ </tr>
652
+ <tr>
653
+ <td class="px-3 py-2 font-mono text-xs">aspect</td>
654
+ <td class="px-3 py-2 font-mono text-xs">'1/1' | '4/3' | '16/9' | ...</td>
655
+ <td class="text-muted px-3 py-2">Aspect ratio constraint</td>
656
+ </tr>
657
+ </tbody>
658
+ </table>
659
+ </div>
660
+ </div>
661
+
662
+ <!-- Usage Example -->
663
+ <div>
664
+ <h4 class="text-muted mb-3 text-sm font-medium uppercase tracking-wide">
665
+ Usage Example
666
+ </h4>
667
+ <pre
668
+ class="overflow-x-auto rounded-lg bg-gray-900 p-4 text-sm text-gray-100"
669
+ ><code>&lt;LayoutGridItem
670
+ :col-start="{ default: 1, md: 2, lg: 4 }"
671
+ :col-span="{ default: 6, md: 10, lg: 12 }"
672
+ align="center"
673
+ justify="start"
674
+ layer="front"
675
+ &gt;
676
+ &lt;h1&gt;Responsive Content&lt;/h1&gt;
677
+ &lt;/LayoutGridItem&gt;</code></pre>
678
+ </div>
679
+
680
+ <!-- Grid debug -->
681
+ <div class="bg-elevated flex items-center gap-3 rounded-lg p-4">
682
+ <UKbd>⌘</UKbd>
683
+ <span>+</span>
684
+ <UKbd>G</UKbd>
685
+ <span class="text-muted">Toggle grid overlay — or use the button above</span>
686
+ <UButton
687
+ variant="soft"
688
+ icon="i-lucide-grid-3x3"
689
+ size="sm"
690
+ class="ml-auto"
691
+ @click="gridDebug?.toggle()"
692
+ >
693
+ Toggle Grid
694
+ </UButton>
695
+ </div>
696
+ </div>
697
+ </UCard>
698
+ </section>
699
+
700
+ <!-- 9. LayoutPage -->
701
+ <section id="layout-page" class="space-y-8">
702
+ <div>
703
+ <h2 class="mb-1 text-2xl font-bold">LayoutPage</h2>
704
+ <p class="text-muted">
705
+ Canonical page wrapper for the Swiss Grid System — handles SEO, page title, and
706
+ optional visible header
707
+ </p>
708
+ </div>
709
+
710
+ <UCard>
711
+ <template #header>
712
+ <div class="flex items-center gap-2">
713
+ <UIcon name="i-lucide-file" class="text-primary" />
714
+ <h3 class="text-xl font-semibold">LayoutPage</h3>
715
+ </div>
716
+ <p class="text-muted mt-1 text-sm">
717
+ Fragment component — no wrapper element. Sets
718
+ <code class="font-mono">&lt;title&gt;</code>, provides
719
+ <code class="font-mono">pageTitle</code> to children, and optionally renders a
720
+ header block.
721
+ </p>
722
+ </template>
723
+
724
+ <div class="space-y-6">
725
+ <div>
726
+ <h4 class="text-muted mb-3 text-sm font-medium uppercase tracking-wide">Props</h4>
727
+ <div class="overflow-x-auto">
728
+ <table class="w-full text-sm">
729
+ <thead>
730
+ <tr class="border-default border-b">
731
+ <th class="px-3 py-2 text-left">Prop</th>
732
+ <th class="px-3 py-2 text-left">Type</th>
733
+ <th class="px-3 py-2 text-left">Default</th>
734
+ <th class="px-3 py-2 text-left">Description</th>
735
+ </tr>
736
+ </thead>
737
+ <tbody class="divide-default divide-y">
738
+ <tr>
739
+ <td class="px-3 py-2 font-mono text-xs">title</td>
740
+ <td class="px-3 py-2 font-mono text-xs">string</td>
741
+ <td class="px-3 py-2 font-mono text-xs">required</td>
742
+ <td class="text-muted px-3 py-2">
743
+ Sets
744
+ <code class="font-mono text-xs">&lt;title&gt;</code>
745
+ and visible heading when showHeader is true
746
+ </td>
747
+ </tr>
748
+ <tr>
749
+ <td class="px-3 py-2 font-mono text-xs">description</td>
750
+ <td class="px-3 py-2 font-mono text-xs">string?</td>
751
+ <td class="px-3 py-2 font-mono text-xs">—</td>
752
+ <td class="text-muted px-3 py-2">
753
+ Sets meta description and og:description
754
+ </td>
755
+ </tr>
756
+ <tr>
757
+ <td class="px-3 py-2 font-mono text-xs">showHeader</td>
758
+ <td class="px-3 py-2 font-mono text-xs">boolean</td>
759
+ <td class="px-3 py-2 font-mono text-xs">false</td>
760
+ <td class="text-muted px-3 py-2">
761
+ Render a visible LayoutPageHeader block
762
+ </td>
763
+ </tr>
764
+ </tbody>
765
+ </table>
766
+ </div>
767
+ </div>
768
+
769
+ <div>
770
+ <h4 class="text-muted mb-3 text-sm font-medium uppercase tracking-wide">
771
+ grid.vue layout props (v1.6.0+)
772
+ </h4>
773
+ <p class="text-muted mb-3 text-sm">
774
+ Header, nav, and footer are opt-in. Pass props via
775
+ <code class="font-mono text-xs">definePageMeta</code>:
776
+ </p>
777
+ <div class="overflow-x-auto">
778
+ <table class="w-full text-sm">
779
+ <thead>
780
+ <tr class="border-default border-b">
781
+ <th class="px-3 py-2 text-left">Prop</th>
782
+ <th class="px-3 py-2 text-left">Default</th>
783
+ <th class="px-3 py-2 text-left">Description</th>
784
+ </tr>
785
+ </thead>
786
+ <tbody class="divide-default divide-y">
787
+ <tr>
788
+ <td class="px-3 py-2 font-mono text-xs">showHeader</td>
789
+ <td class="px-3 py-2 font-mono text-xs">false</td>
790
+ <td class="text-muted px-3 py-2">
791
+ Renders
792
+ <code class="font-mono text-xs">&lt;MastHeader&gt;</code>
793
+ </td>
794
+ </tr>
795
+ <tr>
796
+ <td class="px-3 py-2 font-mono text-xs">showNav</td>
797
+ <td class="px-3 py-2 font-mono text-xs">false</td>
798
+ <td class="text-muted px-3 py-2">
799
+ Renders
800
+ <code class="font-mono text-xs">&lt;MastNav&gt;</code>
801
+ </td>
802
+ </tr>
803
+ <tr>
804
+ <td class="px-3 py-2 font-mono text-xs">showFooter</td>
805
+ <td class="px-3 py-2 font-mono text-xs">false</td>
806
+ <td class="text-muted px-3 py-2">
807
+ Renders
808
+ <code class="font-mono text-xs">&lt;MastFooter&gt;</code>
809
+ </td>
810
+ </tr>
811
+ <tr>
812
+ <td class="px-3 py-2 font-mono text-xs">showGridDebug</td>
813
+ <td class="px-3 py-2 font-mono text-xs">false</td>
814
+ <td class="text-muted px-3 py-2">
815
+ Renders
816
+ <code class="font-mono text-xs">&lt;LayoutGridDebug&gt;</code>
817
+ overlay
818
+ </td>
819
+ </tr>
820
+ </tbody>
821
+ </table>
822
+ </div>
823
+ </div>
824
+ </div>
825
+
826
+ <template #footer>
827
+ <TypographyCodeBlock language="typescript" class="text-sm">{{
828
+ layoutPageCodeSample
829
+ }}</TypographyCodeBlock>
830
+ </template>
831
+ </UCard>
832
+ </section>
833
+
834
+ <!-- 10. Section Components -->
835
+ <section id="section-components" class="space-y-8">
836
+ <div>
837
+ <h2 class="mb-1 text-2xl font-bold">Section Components</h2>
838
+ <p class="text-muted">Pre-configured layouts for common page patterns</p>
839
+ </div>
840
+
841
+ <!-- Hero Section -->
842
+ <UCard>
843
+ <template #header>
844
+ <div class="flex items-center gap-2">
845
+ <UIcon name="i-lucide-image" class="text-primary" />
846
+ <h3 class="text-xl font-semibold">LayoutSectionHero</h3>
847
+ </div>
848
+ <p class="text-muted mt-1 text-sm">
849
+ Full-viewport hero section with background, content, and footer slots
850
+ </p>
851
+ </template>
852
+
853
+ <div class="space-y-6">
854
+ <div class="bg-elevated relative aspect-video overflow-hidden rounded-lg">
855
+ <div class="bg-linear-to-br absolute inset-0 from-blue-500/20 to-purple-500/20" />
856
+ <div class="absolute inset-0 flex flex-col">
857
+ <div class="flex flex-1 items-center justify-center">
858
+ <div class="text-center">
859
+ <div class="mb-2 text-2xl font-bold">Hero Content</div>
860
+ <div class="text-muted text-sm">Centered with optional background</div>
861
+ </div>
862
+ </div>
863
+ <div class="p-4 text-center">
864
+ <div class="bg-primary/20 inline-block rounded px-4 py-2 text-sm">
865
+ Footer Slot
866
+ </div>
867
+ </div>
868
+ </div>
869
+ </div>
870
+
871
+ <div>
872
+ <h4 class="text-muted mb-3 text-sm font-medium uppercase tracking-wide">
873
+ Available Slots
874
+ </h4>
875
+ <div class="grid gap-3 md:grid-cols-3">
876
+ <div class="bg-elevated rounded-lg p-3">
877
+ <div class="text-primary font-mono text-sm">#background</div>
878
+ <p class="text-muted mt-1 text-sm">Full-bleed background layer (z-index: 0)</p>
879
+ </div>
880
+ <div class="bg-elevated rounded-lg p-3">
881
+ <div class="text-primary font-mono text-sm">#default</div>
882
+ <p class="text-muted mt-1 text-sm">Main centered content (z-index: 10)</p>
883
+ </div>
884
+ <div class="bg-elevated rounded-lg p-3">
885
+ <div class="text-primary font-mono text-sm">#footer</div>
886
+ <p class="text-muted mt-1 text-sm">Bottom-aligned content (z-index: 10)</p>
887
+ </div>
888
+ </div>
889
+ </div>
890
+
891
+ <pre
892
+ class="overflow-x-auto rounded-lg bg-gray-900 p-4 text-sm text-gray-100"
893
+ ><code>&lt;LayoutSectionHero&gt;
894
+ &lt;template #background&gt;
895
+ &lt;NuxtImg src="/hero.jpg" class="size-full object-cover" /&gt;
896
+ &lt;/template&gt;
897
+
898
+ &lt;h1&gt;Welcome&lt;/h1&gt;
899
+ &lt;p&gt;Subtitle text&lt;/p&gt;
900
+
901
+ &lt;template #footer&gt;
902
+ &lt;UButton&gt;Call to Action&lt;/UButton&gt;
903
+ &lt;/template&gt;
904
+ &lt;/LayoutSectionHero&gt;</code></pre>
905
+ </div>
906
+ </UCard>
907
+
908
+ <!-- Split Section -->
909
+ <UCard>
910
+ <template #header>
911
+ <div class="flex items-center gap-2">
912
+ <UIcon name="i-lucide-columns-2" class="text-primary" />
913
+ <h3 class="text-xl font-semibold">LayoutSectionSplit</h3>
914
+ </div>
915
+ <p class="text-muted mt-1 text-sm">Two-column layout with optional mobile reversal</p>
916
+ </template>
917
+
918
+ <div class="space-y-6">
919
+ <div class="grid gap-4 md:grid-cols-2">
920
+ <div class="flex items-center justify-center rounded-lg bg-blue-500/20 p-8">
921
+ <div class="text-center">
922
+ <div class="font-mono text-sm">#left</div>
923
+ <div class="text-muted text-sm">Left column</div>
924
+ </div>
925
+ </div>
926
+ <div class="flex items-center justify-center rounded-lg bg-purple-500/20 p-8">
927
+ <div class="text-center">
928
+ <div class="font-mono text-sm">#right</div>
929
+ <div class="text-muted text-sm">Right column</div>
930
+ </div>
931
+ </div>
932
+ </div>
933
+
934
+ <div>
935
+ <h4 class="text-muted mb-3 text-sm font-medium uppercase tracking-wide">Props</h4>
936
+ <div class="flex flex-wrap gap-3">
937
+ <div class="bg-elevated rounded-lg px-3 py-2">
938
+ <span class="font-mono text-sm">fullHeight</span>
939
+ <span class="text-muted ml-2">Force 100svh</span>
940
+ </div>
941
+ <div class="bg-elevated rounded-lg px-3 py-2">
942
+ <span class="font-mono text-sm">reverse</span>
943
+ <span class="text-muted ml-2">Swap order on mobile</span>
944
+ </div>
945
+ </div>
946
+ </div>
947
+
948
+ <pre
949
+ class="overflow-x-auto rounded-lg bg-gray-900 p-4 text-sm text-gray-100"
950
+ ><code>&lt;LayoutSectionSplit
951
+ reverse&gt;
952
+ &lt;template #left&gt;
953
+ &lt;NuxtImg src="/image.jpg" class="size-full object-cover" /&gt;
954
+ &lt;/template&gt;
955
+ &lt;template #right&gt;
956
+ &lt;h2&gt;Content Title&lt;/h2&gt;
957
+ &lt;p&gt;Description text...&lt;/p&gt;
958
+ &lt;/template&gt;
959
+ &lt;/LayoutSectionSplit&gt;</code></pre>
960
+ </div>
961
+ </UCard>
962
+
963
+ <!-- Gallery Section -->
964
+ <UCard>
965
+ <template #header>
966
+ <div class="flex items-center gap-2">
967
+ <UIcon name="i-lucide-layout-grid" class="text-primary" />
968
+ <h3 class="text-xl font-semibold">LayoutSectionGallery</h3>
969
+ </div>
970
+ <p class="text-muted mt-1 text-sm">
971
+ Auto-placing grid for collections with responsive columns
972
+ </p>
973
+ </template>
974
+
975
+ <div class="space-y-6">
976
+ <div class="grid grid-cols-2 gap-3 md:grid-cols-3">
977
+ <div
978
+ v-for="item in galleryItems"
979
+ :key="item.id"
980
+ :class="item.color"
981
+ class="flex items-center justify-center rounded-lg p-6 font-medium text-white"
982
+ >
983
+ {{ item.title }}
984
+ </div>
985
+ </div>
986
+
987
+ <div>
988
+ <h4 class="text-muted mb-3 text-sm font-medium uppercase tracking-wide">Props</h4>
989
+ <div class="overflow-x-auto">
990
+ <table class="w-full text-sm">
991
+ <thead>
992
+ <tr class="border-default border-b">
993
+ <th class="px-3 py-2 text-left">Prop</th>
994
+ <th class="px-3 py-2 text-left">Type</th>
995
+ <th class="px-3 py-2 text-left">Default</th>
996
+ <th class="px-3 py-2 text-left">Description</th>
997
+ </tr>
998
+ </thead>
999
+ <tbody class="divide-default divide-y">
1000
+ <tr>
1001
+ <td class="px-3 py-2 font-mono text-xs">items</td>
1002
+ <td class="px-3 py-2 font-mono text-xs">T[]</td>
1003
+ <td class="px-3 py-2 font-mono text-xs">required</td>
1004
+ <td class="text-muted px-3 py-2">Array of items to render</td>
1005
+ </tr>
1006
+ <tr>
1007
+ <td class="px-3 py-2 font-mono text-xs">columns</td>
1008
+ <td class="px-3 py-2 font-mono text-xs">2 | 3 | 4 | 6</td>
1009
+ <td class="px-3 py-2 font-mono text-xs">3</td>
1010
+ <td class="text-muted px-3 py-2">Desktop column count</td>
1011
+ </tr>
1012
+ <tr>
1013
+ <td class="px-3 py-2 font-mono text-xs">itemRowSpan</td>
1014
+ <td class="px-3 py-2 font-mono text-xs">number</td>
1015
+ <td class="px-3 py-2 font-mono text-xs">4</td>
1016
+ <td class="text-muted px-3 py-2">Grid rows per item</td>
1017
+ </tr>
1018
+ </tbody>
1019
+ </table>
1020
+ </div>
1021
+ </div>
1022
+
1023
+ <pre
1024
+ class="overflow-x-auto rounded-lg bg-gray-900 p-4 text-sm text-gray-100"
1025
+ ><code>&lt;LayoutSectionGallery
1026
+ :items="images" :columns="3"&gt;
1027
+ &lt;template #item="{ item, index }"&gt;
1028
+ &lt;NuxtImg :src="item.src" class="size-full object-cover" /&gt;
1029
+ &lt;/template&gt;
1030
+ &lt;/LayoutSectionGallery&gt;</code></pre>
1031
+ </div>
1032
+ </UCard>
1033
+ </section>
1034
+
1035
+ <!-- 11. Motion Components -->
1036
+ <section id="motion-components" class="space-y-8">
1037
+ <div>
1038
+ <h2 class="mb-1 text-2xl font-bold">Motion Components</h2>
1039
+ <p class="text-muted">
1040
+ Animation, scroll, and velocity components from the motion layer
1041
+ </p>
1042
+ </div>
1043
+
1044
+ <!-- useSmoothScroll composable -->
1045
+ <UCard>
1046
+ <template #header>
1047
+ <div class="flex items-center gap-2">
1048
+ <UIcon name="i-lucide-activity" class="text-primary" />
1049
+ <h3 class="text-xl font-semibold">useSmoothScroll</h3>
1050
+ </div>
1051
+ <p class="text-muted mt-1 text-sm">
1052
+ Per-page composable for Locomotive Scroll state — progress, velocity, direction, and
1053
+ scroll controls
1054
+ </p>
1055
+ </template>
1056
+
1057
+ <div class="space-y-6">
1058
+ <div>
1059
+ <h4 class="text-muted mb-3 text-sm font-medium uppercase tracking-wide">Returns</h4>
1060
+ <div class="overflow-x-auto">
1061
+ <table class="w-full text-sm">
1062
+ <thead>
1063
+ <tr class="border-default border-b">
1064
+ <th class="px-3 py-2 text-left">Name</th>
1065
+ <th class="px-3 py-2 text-left">Type</th>
1066
+ <th class="px-3 py-2 text-left">Description</th>
1067
+ </tr>
1068
+ </thead>
1069
+ <tbody class="divide-default divide-y">
1070
+ <tr>
1071
+ <td class="px-3 py-2 font-mono text-xs">progress</td>
1072
+ <td class="px-3 py-2 font-mono text-xs">Ref&lt;number&gt;</td>
1073
+ <td class="text-muted px-3 py-2">Scroll progress 0–1</td>
1074
+ </tr>
1075
+ <tr>
1076
+ <td class="px-3 py-2 font-mono text-xs">velocity</td>
1077
+ <td class="px-3 py-2 font-mono text-xs">Ref&lt;number&gt;</td>
1078
+ <td class="text-muted px-3 py-2">Signed scroll velocity</td>
1079
+ </tr>
1080
+ <tr>
1081
+ <td class="px-3 py-2 font-mono text-xs">direction</td>
1082
+ <td class="px-3 py-2 font-mono text-xs">Ref&lt;number&gt;</td>
1083
+ <td class="text-muted px-3 py-2">1 = down, -1 = up, 0 = idle</td>
1084
+ </tr>
1085
+ <tr>
1086
+ <td class="px-3 py-2 font-mono text-xs">scrollY</td>
1087
+ <td class="px-3 py-2 font-mono text-xs">Ref&lt;number&gt;</td>
1088
+ <td class="text-muted px-3 py-2">Absolute scroll position in px</td>
1089
+ </tr>
1090
+ <tr>
1091
+ <td class="px-3 py-2 font-mono text-xs">scrollTo(target, opts?)</td>
1092
+ <td class="px-3 py-2 font-mono text-xs">Function</td>
1093
+ <td class="text-muted px-3 py-2">
1094
+ Scroll to selector, element, or Y position
1095
+ </td>
1096
+ </tr>
1097
+ <tr>
1098
+ <td class="px-3 py-2 font-mono text-xs">scrollToTop(opts?)</td>
1099
+ <td class="px-3 py-2 font-mono text-xs">Function</td>
1100
+ <td class="text-muted px-3 py-2">Animated scroll to page top</td>
1101
+ </tr>
1102
+ <tr>
1103
+ <td class="px-3 py-2 font-mono text-xs">snapToTop()</td>
1104
+ <td class="px-3 py-2 font-mono text-xs">Function</td>
1105
+ <td class="text-muted px-3 py-2">Instant jump to top (no animation)</td>
1106
+ </tr>
1107
+ <tr>
1108
+ <td class="px-3 py-2 font-mono text-xs">lockScrolling()</td>
1109
+ <td class="px-3 py-2 font-mono text-xs">Function</td>
1110
+ <td class="text-muted px-3 py-2">Disable scroll (e.g. for modals)</td>
1111
+ </tr>
1112
+ <tr>
1113
+ <td class="px-3 py-2 font-mono text-xs">unlockScrolling()</td>
1114
+ <td class="px-3 py-2 font-mono text-xs">Function</td>
1115
+ <td class="text-muted px-3 py-2">Re-enable scroll</td>
1116
+ </tr>
1117
+ </tbody>
1118
+ </table>
1119
+ </div>
1120
+ </div>
1121
+
1122
+ <TypographyCodeBlock language="typescript" class="text-sm">{{
1123
+ `const { progress, velocity, direction, scrollY, scrollTo, scrollToTop, snapToTop, lockScrolling,
1124
+ unlockScrolling } = useSmoothScroll()
1125
+
1126
+ // Scroll to a section
1127
+ scrollTo('#hero', { offset: -80, duration: 1.5 })
1128
+
1129
+ // Watch velocity for effects
1130
+ watch(velocity, (v) => console.log('velocity:', v))`
1131
+ }}</TypographyCodeBlock>
1132
+ </div>
1133
+ </UCard>
1134
+
1135
+ <!-- MotionTextReveal -->
1136
+ <UCard>
1137
+ <template #header>
1138
+ <div class="flex items-center gap-2">
1139
+ <UIcon name="i-lucide-text-cursor-input" class="text-primary" />
1140
+ <h3 class="text-xl font-semibold">MotionTextReveal</h3>
1141
+ </div>
1142
+ <p class="text-muted mt-1 text-sm">
1143
+ Scroll-triggered character, word, or line reveal powered by v-gsap-nuxt SplitText
1144
+ </p>
1145
+ </template>
1146
+
1147
+ <div class="space-y-6">
1148
+ <div class="space-y-4 py-4">
1149
+ <ClientOnly>
1150
+ <MotionTextReveal
1151
+ text="Character reveal — type: chars"
1152
+ type="chars"
1153
+ class="text-highlighted text-2xl font-bold"
1154
+ />
1155
+ <MotionTextReveal
1156
+ text="Word by word reveal — type: words"
1157
+ type="words"
1158
+ class="text-highlighted text-2xl font-bold"
1159
+ />
1160
+ <MotionTextReveal
1161
+ text="Line by line reveal — type: lines"
1162
+ type="lines"
1163
+ class="text-highlighted text-2xl font-bold"
1164
+ />
1165
+ </ClientOnly>
1166
+ </div>
1167
+
1168
+ <div>
1169
+ <h4 class="text-muted mb-3 text-sm font-medium uppercase tracking-wide">Props</h4>
1170
+ <div class="overflow-x-auto">
1171
+ <table class="w-full text-sm">
1172
+ <thead>
1173
+ <tr class="border-default border-b">
1174
+ <th class="px-3 py-2 text-left">Prop</th>
1175
+ <th class="px-3 py-2 text-left">Type</th>
1176
+ <th class="px-3 py-2 text-left">Default</th>
1177
+ </tr>
1178
+ </thead>
1179
+ <tbody class="divide-default divide-y">
1180
+ <tr>
1181
+ <td class="px-3 py-2 font-mono text-xs">text</td>
1182
+ <td class="px-3 py-2 font-mono text-xs">string</td>
1183
+ <td class="px-3 py-2 font-mono text-xs">required</td>
1184
+ </tr>
1185
+ <tr>
1186
+ <td class="px-3 py-2 font-mono text-xs">type</td>
1187
+ <td class="px-3 py-2 font-mono text-xs">'chars' | 'words' | 'lines'</td>
1188
+ <td class="px-3 py-2 font-mono text-xs">'chars'</td>
1189
+ </tr>
1190
+ <tr>
1191
+ <td class="px-3 py-2 font-mono text-xs">stagger</td>
1192
+ <td class="px-3 py-2 font-mono text-xs">number</td>
1193
+ <td class="px-3 py-2 font-mono text-xs">0.03</td>
1194
+ </tr>
1195
+ <tr>
1196
+ <td class="px-3 py-2 font-mono text-xs">duration</td>
1197
+ <td class="px-3 py-2 font-mono text-xs">number</td>
1198
+ <td class="px-3 py-2 font-mono text-xs">0.8</td>
1199
+ </tr>
1200
+ <tr>
1201
+ <td class="px-3 py-2 font-mono text-xs">start</td>
1202
+ <td class="px-3 py-2 font-mono text-xs">string</td>
1203
+ <td class="px-3 py-2 font-mono text-xs">'top 80%'</td>
1204
+ </tr>
1205
+ </tbody>
1206
+ </table>
1207
+ </div>
1208
+ </div>
1209
+ </div>
1210
+
1211
+ <template #footer>
1212
+ <TypographyCodeBlock language="vue" class="text-sm"
1213
+ >{{ ` <MotionTextReveal text="Hello World" type="words" :stagger="0.05" />` }}
1214
+ </TypographyCodeBlock>
1215
+ </template>
1216
+ </UCard>
1217
+
1218
+ <!-- MotionScrollProgress -->
1219
+ <UCard>
1220
+ <template #header>
1221
+ <div class="flex items-center gap-2">
1222
+ <UIcon name="i-lucide-loader" class="text-primary" />
1223
+ <h3 class="text-xl font-semibold">MotionScrollProgress</h3>
1224
+ </div>
1225
+ <p class="text-muted mt-1 text-sm">
1226
+ Linear or circular scroll progress indicator tied to
1227
+ <code class="font-mono">useSmoothScroll</code>
1228
+ </p>
1229
+ </template>
1230
+
1231
+ <div class="space-y-6">
1232
+ <div>
1233
+ <h4 class="text-muted mb-3 text-sm font-medium uppercase tracking-wide">
1234
+ Linear (default)
1235
+ </h4>
1236
+ <MotionScrollProgress type="linear" :height="6" />
1237
+ </div>
1238
+ <div>
1239
+ <h4 class="text-muted mb-3 text-sm font-medium uppercase tracking-wide">
1240
+ Circular
1241
+ </h4>
1242
+ <MotionScrollProgress type="circular" :size="80" :stroke-width="6" />
1243
+ </div>
1244
+
1245
+ <div>
1246
+ <h4 class="text-muted mb-3 text-sm font-medium uppercase tracking-wide">Props</h4>
1247
+ <div class="flex flex-wrap gap-3">
1248
+ <div class="bg-elevated rounded-lg px-3 py-2">
1249
+ <span class="font-mono text-sm">type</span
1250
+ ><span class="text-muted ml-2">'linear' | 'circular'</span>
1251
+ </div>
1252
+ <div class="bg-elevated rounded-lg px-3 py-2">
1253
+ <span class="font-mono text-sm">height</span
1254
+ ><span class="text-muted ml-2">px (linear)</span>
1255
+ </div>
1256
+ <div class="bg-elevated rounded-lg px-3 py-2">
1257
+ <span class="font-mono text-sm">size</span
1258
+ ><span class="text-muted ml-2">px (circular)</span>
1259
+ </div>
1260
+ <div class="bg-elevated rounded-lg px-3 py-2">
1261
+ <span class="font-mono text-sm">strokeWidth</span
1262
+ ><span class="text-muted ml-2">px (circular)</span>
1263
+ </div>
1264
+ <div class="bg-elevated rounded-lg px-3 py-2">
1265
+ <span class="font-mono text-sm">showPercentage</span
1266
+ ><span class="text-muted ml-2">boolean</span>
1267
+ </div>
1268
+ <div class="bg-elevated rounded-lg px-3 py-2">
1269
+ <span class="font-mono text-sm">colors</span
1270
+ ><span class="text-muted ml-2">[start, mid, end]</span>
1271
+ </div>
1272
+ </div>
1273
+ </div>
1274
+ </div>
1275
+
1276
+ <template #footer>
1277
+ <TypographyCodeBlock language="vue" class="text-sm">{{
1278
+ scrollProgressCodeSample
1279
+ }}</TypographyCodeBlock>
1280
+ </template>
1281
+ </UCard>
1282
+
1283
+ <!-- MotionParallax -->
1284
+ <UCard>
1285
+ <template #header>
1286
+ <div class="flex items-center gap-2">
1287
+ <UIcon name="i-lucide-layers" class="text-primary" />
1288
+ <h3 class="text-xl font-semibold">MotionParallax</h3>
1289
+ </div>
1290
+ <p class="text-muted mt-1 text-sm">
1291
+ GSAP ScrollTrigger parallax — scroll past to see the depth effect
1292
+ </p>
1293
+ </template>
1294
+
1295
+ <div class="space-y-6">
1296
+ <div class="bg-elevated relative h-48 overflow-hidden rounded-xl">
1297
+ <MotionParallax :speed="0.4" class="h-full">
1298
+ <div
1299
+ class="bg-linear-to-br from-primary/30 flex h-full w-full items-center justify-center to-purple-500/30"
1300
+ >
1301
+ <span class="text-highlighted text-lg font-semibold"
1302
+ >Parallax Content (speed: 0.4)</span
1303
+ >
1304
+ </div>
1305
+ </MotionParallax>
1306
+ </div>
1307
+
1308
+ <div>
1309
+ <h4 class="text-muted mb-3 text-sm font-medium uppercase tracking-wide">Props</h4>
1310
+ <div class="overflow-x-auto">
1311
+ <table class="w-full text-sm">
1312
+ <thead>
1313
+ <tr class="border-default border-b">
1314
+ <th class="px-3 py-2 text-left">Prop</th>
1315
+ <th class="px-3 py-2 text-left">Type</th>
1316
+ <th class="px-3 py-2 text-left">Default</th>
1317
+ <th class="px-3 py-2 text-left">Description</th>
1318
+ </tr>
1319
+ </thead>
1320
+ <tbody class="divide-default divide-y">
1321
+ <tr>
1322
+ <td class="px-3 py-2 font-mono text-xs">speed</td>
1323
+ <td class="px-3 py-2 font-mono text-xs">number</td>
1324
+ <td class="px-3 py-2 font-mono text-xs">0.5</td>
1325
+ <td class="text-muted px-3 py-2">-1 to 1 (negative = slower)</td>
1326
+ </tr>
1327
+ <tr>
1328
+ <td class="px-3 py-2 font-mono text-xs">direction</td>
1329
+ <td class="px-3 py-2 font-mono text-xs">'vertical' | 'horizontal'</td>
1330
+ <td class="px-3 py-2 font-mono text-xs">'vertical'</td>
1331
+ <td class="text-muted px-3 py-2">Axis of movement</td>
1332
+ </tr>
1333
+ <tr>
1334
+ <td class="px-3 py-2 font-mono text-xs">rotate</td>
1335
+ <td class="px-3 py-2 font-mono text-xs">number</td>
1336
+ <td class="px-3 py-2 font-mono text-xs">0</td>
1337
+ <td class="text-muted px-3 py-2">Degrees to rotate on scroll</td>
1338
+ </tr>
1339
+ <tr>
1340
+ <td class="px-3 py-2 font-mono text-xs">scale</td>
1341
+ <td class="px-3 py-2 font-mono text-xs">number</td>
1342
+ <td class="px-3 py-2 font-mono text-xs">0</td>
1343
+ <td class="text-muted px-3 py-2">Scale delta added on scroll</td>
1344
+ </tr>
1345
+ <tr>
1346
+ <td class="px-3 py-2 font-mono text-xs">scrub</td>
1347
+ <td class="px-3 py-2 font-mono text-xs">number</td>
1348
+ <td class="px-3 py-2 font-mono text-xs">0.5</td>
1349
+ <td class="text-muted px-3 py-2">ScrollTrigger scrub lag</td>
1350
+ </tr>
1351
+ <tr>
1352
+ <td class="px-3 py-2 font-mono text-xs">as</td>
1353
+ <td class="px-3 py-2 font-mono text-xs">string</td>
1354
+ <td class="px-3 py-2 font-mono text-xs">'div'</td>
1355
+ <td class="text-muted px-3 py-2">Wrapper element tag</td>
1356
+ </tr>
1357
+ </tbody>
1358
+ </table>
1359
+ </div>
1360
+ </div>
1361
+ </div>
1362
+
1363
+ <template #footer>
1364
+ <TypographyCodeBlock language="vue" class="text-sm"
1365
+ >{{ `<MotionParallax :speed="0.3" :rotate="10">
1366
+ <NuxtImg src="/hero.jpg" class="size-full object-cover" /> </MotionParallax
1367
+ >` }}</TypographyCodeBlock
1368
+ >
1369
+ </template>
1370
+ </UCard>
1371
+
1372
+ <!-- MotionVelocityEffect -->
1373
+ <UCard>
1374
+ <template #header>
1375
+ <div class="flex items-center gap-2">
1376
+ <UIcon name="i-lucide-zap" class="text-primary" />
1377
+ <h3 class="text-xl font-semibold">MotionVelocityEffect</h3>
1378
+ </div>
1379
+ <p class="text-muted mt-1 text-sm">
1380
+ Apply scroll-velocity-driven visual distortions — skew, blur, scale, letterSpacing,
1381
+ and more
1382
+ </p>
1383
+ </template>
1384
+
1385
+ <div class="space-y-6">
1386
+ <div class="grid gap-4 md:grid-cols-2">
1387
+ <div class="bg-elevated rounded-lg p-4 text-center">
1388
+ <p class="text-muted mb-3 text-xs uppercase tracking-wide">effect: skew</p>
1389
+ <MotionVelocityEffect effect="skew" class="text-highlighted text-2xl font-bold">
1390
+ Skew on Scroll
1391
+ </MotionVelocityEffect>
1392
+ </div>
1393
+ <div class="bg-elevated rounded-lg p-4 text-center">
1394
+ <p class="text-muted mb-3 text-xs uppercase tracking-wide">
1395
+ effect: letterSpacing
1396
+ </p>
1397
+ <MotionVelocityEffect
1398
+ effect="letterSpacing"
1399
+ class="text-highlighted text-2xl font-bold"
1400
+ >
1401
+ Letter Spacing
1402
+ </MotionVelocityEffect>
1403
+ </div>
1404
+ </div>
1405
+
1406
+ <div>
1407
+ <h4 class="text-muted mb-3 text-sm font-medium uppercase tracking-wide">
1408
+ Available Effects
1409
+ </h4>
1410
+ <div class="flex flex-wrap gap-2">
1411
+ <UBadge
1412
+ v-for="effect in [
1413
+ 'skew',
1414
+ 'scale',
1415
+ 'blur',
1416
+ 'opacity',
1417
+ 'letterSpacing',
1418
+ 'rotate',
1419
+ 'translateY',
1420
+ 'hueRotate',
1421
+ ]"
1422
+ :key="effect"
1423
+ variant="subtle"
1424
+ color="neutral"
1425
+ >
1426
+ {{ effect }}
1427
+ </UBadge>
1428
+ </div>
1429
+ </div>
1430
+ </div>
1431
+
1432
+ <template #footer>
1433
+ <TypographyCodeBlock language="vue" class="text-sm"
1434
+ >{{ `<MotionVelocityEffect effect="skew" :intensity="5">
1435
+ <h1 class="text-6xl font-black">Fast Scroll</h1> </MotionVelocityEffect
1436
+ >` }}</TypographyCodeBlock
1437
+ >
1438
+ </template>
1439
+ </UCard>
1440
+
1441
+ <!-- MotionStaggered -->
1442
+ <UCard>
1443
+ <template #header>
1444
+ <div class="flex items-center gap-2">
1445
+ <UIcon name="i-lucide-list-ordered" class="text-primary" />
1446
+ <h3 class="text-xl font-semibold">MotionStaggered</h3>
1447
+ </div>
1448
+ <p class="text-muted mt-1 text-sm">
1449
+ CSS-based staggered entry animation on mount — no GSAP required
1450
+ </p>
1451
+ </template>
1452
+
1453
+ <div class="space-y-6">
1454
+ <MotionStaggered class="grid grid-cols-4 gap-3" :stagger-delay="80">
1455
+ <div class="bg-elevated rounded-lg p-4 text-center text-sm font-medium">Item 1</div>
1456
+ <div class="bg-elevated rounded-lg p-4 text-center text-sm font-medium">Item 2</div>
1457
+ <div class="bg-elevated rounded-lg p-4 text-center text-sm font-medium">Item 3</div>
1458
+ <div class="bg-elevated rounded-lg p-4 text-center text-sm font-medium">Item 4</div>
1459
+ </MotionStaggered>
1460
+
1461
+ <div>
1462
+ <h4 class="text-muted mb-3 text-sm font-medium uppercase tracking-wide">Props</h4>
1463
+ <div class="flex flex-wrap gap-3">
1464
+ <div class="bg-elevated rounded-lg px-3 py-2">
1465
+ <span class="font-mono text-sm">staggerDelay</span
1466
+ ><span class="text-muted ml-2">ms between items (100)</span>
1467
+ </div>
1468
+ <div class="bg-elevated rounded-lg px-3 py-2">
1469
+ <span class="font-mono text-sm">initialDelay</span
1470
+ ><span class="text-muted ml-2">ms before first item (0)</span>
1471
+ </div>
1472
+ <div class="bg-elevated rounded-lg px-3 py-2">
1473
+ <span class="font-mono text-sm">animation</span
1474
+ ><span class="text-muted ml-2">CSS class name ('fadeIn')</span>
1475
+ </div>
1476
+ </div>
1477
+ </div>
1478
+ </div>
1479
+
1480
+ <template #footer>
1481
+ <TypographyCodeBlock language="vue" class="text-sm"
1482
+ >{{ `<MotionStaggered
1483
+ class="grid grid-cols-3 gap-4"
1484
+ :stagger-delay="100"
1485
+ :initial-delay="200"
1486
+ >
1487
+ <ArticleCard
1488
+ v-for="post in posts"
1489
+ :key="post.id"
1490
+ v-bind="post"
1491
+ /> </MotionStaggered
1492
+ >` }}</TypographyCodeBlock
1493
+ >
1494
+ </template>
1495
+ </UCard>
1496
+
1497
+ <!-- MotionScrollStats -->
1498
+ <UCard>
1499
+ <template #header>
1500
+ <div class="flex items-center gap-2">
1501
+ <UIcon name="i-lucide-gauge" class="text-primary" />
1502
+ <h3 class="text-xl font-semibold">MotionScrollStats</h3>
1503
+ </div>
1504
+ <p class="text-muted mt-1 text-sm">
1505
+ Debug overlay showing live scroll state — velocity, progress, direction, and scroll
1506
+ Y
1507
+ </p>
1508
+ </template>
1509
+
1510
+ <div class="space-y-4">
1511
+ <p class="text-muted text-sm">
1512
+ Add to any page during development to inspect scroll state. Fades when idle, appears
1513
+ on scroll.
1514
+ </p>
1515
+ <div>
1516
+ <h4 class="text-muted mb-3 text-sm font-medium uppercase tracking-wide">Props</h4>
1517
+ <div class="overflow-x-auto">
1518
+ <table class="w-full text-sm">
1519
+ <thead>
1520
+ <tr class="border-default border-b">
1521
+ <th class="px-3 py-2 text-left">Prop</th>
1522
+ <th class="px-3 py-2 text-left">Type</th>
1523
+ <th class="px-3 py-2 text-left">Default</th>
1524
+ </tr>
1525
+ </thead>
1526
+ <tbody class="divide-default divide-y">
1527
+ <tr>
1528
+ <td class="px-3 py-2 font-mono text-xs">show</td>
1529
+ <td class="px-3 py-2 font-mono text-xs">
1530
+ ('velocity' | 'progress' | 'direction' | 'scrollY')[]
1531
+ </td>
1532
+ <td class="px-3 py-2 font-mono text-xs">
1533
+ ['velocity', 'progress', 'direction']
1534
+ </td>
1535
+ </tr>
1536
+ <tr>
1537
+ <td class="px-3 py-2 font-mono text-xs">position</td>
1538
+ <td class="px-3 py-2 font-mono text-xs">
1539
+ 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right'
1540
+ </td>
1541
+ <td class="px-3 py-2 font-mono text-xs">'bottom-right'</td>
1542
+ </tr>
1543
+ <tr>
1544
+ <td class="px-3 py-2 font-mono text-xs">compact</td>
1545
+ <td class="px-3 py-2 font-mono text-xs">boolean</td>
1546
+ <td class="px-3 py-2 font-mono text-xs">false</td>
1547
+ </tr>
1548
+ </tbody>
1549
+ </table>
1550
+ </div>
1551
+ </div>
1552
+ </div>
1553
+
1554
+ <template #footer>
1555
+ <TypographyCodeBlock language="vue" class="text-sm">{{
1556
+ scrollStatsCodeSample
1557
+ }}</TypographyCodeBlock>
1558
+ </template>
1559
+ </UCard>
1560
+
1561
+ <!-- MotionMarquee -->
1562
+ <UCard>
1563
+ <template #header>
1564
+ <div class="flex items-center gap-2">
1565
+ <UIcon name="i-lucide-arrow-right-from-line" class="text-primary" />
1566
+ <h3 class="text-xl font-semibold">MotionMarquee</h3>
1567
+ </div>
1568
+ <p class="text-muted mt-1 text-sm">
1569
+ Infinite scroll ticker — velocity-aware, pause-on-hover, configurable direction
1570
+ </p>
1571
+ </template>
1572
+
1573
+ <div class="space-y-6">
1574
+ <div class="border-default overflow-hidden rounded-lg border py-3">
1575
+ <MotionMarquee :speed="40" gap="2rem" velocity-based :velocity-sensitivity="0.5">
1576
+ <span
1577
+ v-for="item in [
1578
+ 'Core',
1579
+ '◆',
1580
+ 'UI',
1581
+ '◆',
1582
+ 'Layout',
1583
+ '◆',
1584
+ 'Motion',
1585
+ '◆',
1586
+ 'Forms',
1587
+ '◆',
1588
+ 'Theme',
1589
+ '◆',
1590
+ 'Content',
1591
+ '◆',
1592
+ ]"
1593
+ :key="item"
1594
+ class="text-muted whitespace-nowrap text-xs font-semibold uppercase tracking-widest"
1595
+ >{{ item }}</span
1596
+ >
1597
+ </MotionMarquee>
1598
+ </div>
1599
+
1600
+ <div>
1601
+ <h4 class="text-muted mb-3 text-sm font-medium uppercase tracking-wide">Props</h4>
1602
+ <div class="flex flex-wrap gap-3">
1603
+ <div class="bg-elevated rounded-lg px-3 py-2">
1604
+ <span class="font-mono text-sm">speed</span
1605
+ ><span class="text-muted ml-2">px/s (45)</span>
1606
+ </div>
1607
+ <div class="bg-elevated rounded-lg px-3 py-2">
1608
+ <span class="font-mono text-sm">direction</span
1609
+ ><span class="text-muted ml-2">'left' | 'right'</span>
1610
+ </div>
1611
+ <div class="bg-elevated rounded-lg px-3 py-2">
1612
+ <span class="font-mono text-sm">gap</span
1613
+ ><span class="text-muted ml-2">CSS spacing</span>
1614
+ </div>
1615
+ <div class="bg-elevated rounded-lg px-3 py-2">
1616
+ <span class="font-mono text-sm">pauseOnHover</span
1617
+ ><span class="text-muted ml-2">boolean</span>
1618
+ </div>
1619
+ <div class="bg-elevated rounded-lg px-3 py-2">
1620
+ <span class="font-mono text-sm">velocityBased</span
1621
+ ><span class="text-muted ml-2">boolean</span>
1622
+ </div>
1623
+ <div class="bg-elevated rounded-lg px-3 py-2">
1624
+ <span class="font-mono text-sm">velocitySensitivity</span
1625
+ ><span class="text-muted ml-2">number</span>
1626
+ </div>
1627
+ </div>
1628
+ </div>
1629
+ </div>
1630
+ </UCard>
1631
+ </section>
1632
+
1633
+ <!-- 12. LinksGroup -->
1634
+ <section id="links-group" class="space-y-8">
1635
+ <div>
1636
+ <h2 class="mb-1 text-2xl font-bold">LinksGroup</h2>
1637
+ <p class="text-muted">
1638
+ Hover one item to dim the rest — works with any direct children
1639
+ </p>
1640
+ </div>
1641
+
1642
+ <UCard>
1643
+ <template #header>
1644
+ <div class="flex items-center gap-2">
1645
+ <UIcon name="i-lucide-mouse-pointer-click" class="text-primary" />
1646
+ <h3 class="text-xl font-semibold">LinksGroup</h3>
1647
+ </div>
1648
+ <p class="text-muted mt-1 text-sm">
1649
+ Wraps children in a hover-to-focus group with configurable dim opacity and
1650
+ transition duration
1651
+ </p>
1652
+ </template>
1653
+
1654
+ <div class="space-y-8">
1655
+ <!-- Nav Links -->
1656
+ <div>
1657
+ <h4 class="text-muted mb-3 text-sm font-medium uppercase tracking-wide">
1658
+ Navigation Links
1659
+ </h4>
1660
+ <LinksGroup class="flex gap-6">
1661
+ <a href="#" class="text-highlighted text-lg font-medium">Home</a>
1662
+ <a href="#" class="text-highlighted text-lg font-medium">About</a>
1663
+ <a href="#" class="text-highlighted text-lg font-medium">Work</a>
1664
+ <a href="#" class="text-highlighted text-lg font-medium">Blog</a>
1665
+ <a href="#" class="text-highlighted text-lg font-medium">Contact</a>
1666
+ </LinksGroup>
1667
+ </div>
1668
+
1669
+ <!-- Buttons -->
1670
+ <div>
1671
+ <h4 class="text-muted mb-3 text-sm font-medium uppercase tracking-wide">Buttons</h4>
1672
+ <LinksGroup class="flex gap-3">
1673
+ <UButton variant="solid">Primary</UButton>
1674
+ <UButton variant="outline">Outline</UButton>
1675
+ <UButton variant="soft">Soft</UButton>
1676
+ <UButton variant="ghost">Ghost</UButton>
1677
+ </LinksGroup>
1678
+ </div>
1679
+
1680
+ <!-- Cards Grid -->
1681
+ <div>
1682
+ <h4 class="text-muted mb-3 text-sm font-medium uppercase tracking-wide">
1683
+ Card Grid
1684
+ </h4>
1685
+ <LinksGroup class="grid grid-cols-3 gap-4" :duration="300">
1686
+ <div class="border-default bg-elevated rounded-lg border p-6 text-center">
1687
+ <UIcon name="i-lucide-code" class="text-primary mb-2 text-2xl" />
1688
+ <p class="font-medium">Development</p>
1689
+ </div>
1690
+ <div class="border-default bg-elevated rounded-lg border p-6 text-center">
1691
+ <UIcon name="i-lucide-palette" class="text-primary mb-2 text-2xl" />
1692
+ <p class="font-medium">Design</p>
1693
+ </div>
1694
+ <div class="border-default bg-elevated rounded-lg border p-6 text-center">
1695
+ <UIcon name="i-lucide-rocket" class="text-primary mb-2 text-2xl" />
1696
+ <p class="font-medium">Deploy</p>
1697
+ </div>
1698
+ </LinksGroup>
1699
+ </div>
1700
+
1701
+ <!-- Custom Opacity -->
1702
+ <div>
1703
+ <h4 class="text-muted mb-3 text-sm font-medium uppercase tracking-wide">
1704
+ Custom Dim (0.1)
1705
+ </h4>
1706
+ <LinksGroup class="flex gap-4" :dim-opacity="0.1">
1707
+ <span class="text-3xl">🚀</span>
1708
+ <span class="text-3xl">💡</span>
1709
+ <span class="text-3xl">⭐</span>
1710
+ <span class="text-3xl">🔥</span>
1711
+ <span class="text-3xl">🌈</span>
1712
+ </LinksGroup>
1713
+ </div>
1714
+ </div>
1715
+
1716
+ <template #footer>
1717
+ <TypographyCodeBlock language="vue" class="text-sm">
1718
+ {{ `<LinksGroup class="flex gap-6">
1719
+ <a href="/home">Home</a>
1720
+ <a href="/about">About</a>
1721
+ <a href="/contact">Contact</a> </LinksGroup
1722
+ >` }}
1723
+ </TypographyCodeBlock>
1724
+ </template>
1725
+ </UCard>
1726
+ </section>
1727
+
1728
+ <!-- 13. UI Components -->
1729
+ <section id="ui-components" class="space-y-8">
1730
+ <div>
1731
+ <h2 class="mb-1 text-2xl font-bold">UI Components</h2>
1732
+ <p class="text-muted">
1733
+ Nuxt UI component showcase — buttons, badges, cards, kbd, progress
1734
+ </p>
1735
+ </div>
1736
+
1737
+ <!-- Buttons -->
1738
+ <UCard>
1739
+ <template #header>
1740
+ <div class="flex items-center gap-2">
1741
+ <UIcon name="i-lucide-mouse-pointer" class="text-primary" />
1742
+ <h3 class="text-xl font-semibold">Buttons</h3>
1743
+ </div>
1744
+ </template>
1745
+
1746
+ <div class="space-y-6">
1747
+ <div>
1748
+ <h4 class="text-muted mb-3 text-sm font-medium uppercase tracking-wide">
1749
+ Variants
1750
+ </h4>
1751
+ <div class="flex flex-wrap gap-3">
1752
+ <UButton variant="solid">Solid</UButton>
1753
+ <UButton variant="outline">Outline</UButton>
1754
+ <UButton variant="soft">Soft</UButton>
1755
+ <UButton variant="subtle">Subtle</UButton>
1756
+ <UButton variant="ghost">Ghost</UButton>
1757
+ <UButton variant="link">Link</UButton>
1758
+ </div>
1759
+ </div>
1760
+
1761
+ <div>
1762
+ <h4 class="text-muted mb-3 text-sm font-medium uppercase tracking-wide">Sizes</h4>
1763
+ <div class="flex flex-wrap items-center gap-3">
1764
+ <UButton size="xs">Extra Small</UButton>
1765
+ <UButton size="sm">Small</UButton>
1766
+ <UButton size="md">Medium</UButton>
1767
+ <UButton size="lg">Large</UButton>
1768
+ <UButton size="xl">Extra Large</UButton>
1769
+ </div>
1770
+ </div>
1771
+
1772
+ <div>
1773
+ <h4 class="text-muted mb-3 text-sm font-medium uppercase tracking-wide">Colors</h4>
1774
+ <div class="flex flex-wrap gap-3">
1775
+ <UButton color="primary">Primary</UButton>
1776
+ <UButton color="secondary">Secondary</UButton>
1777
+ <UButton color="neutral">Neutral</UButton>
1778
+ <UButton color="success">Success</UButton>
1779
+ <UButton color="warning">Warning</UButton>
1780
+ <UButton color="error">Error</UButton>
1781
+ <UButton color="info">Info</UButton>
1782
+ </div>
1783
+ </div>
1784
+
1785
+ <div>
1786
+ <h4 class="text-muted mb-3 text-sm font-medium uppercase tracking-wide">
1787
+ With Icons
1788
+ </h4>
1789
+ <div class="flex flex-wrap gap-3">
1790
+ <UButton icon="i-lucide-rocket">Launch</UButton>
1791
+ <UButton trailing-icon="i-lucide-arrow-right">Continue</UButton>
1792
+ <UButton icon="i-lucide-download" variant="outline">Download</UButton>
1793
+ <UButton
1794
+ icon="i-simple-icons-github"
1795
+ color="neutral"
1796
+ variant="ghost"
1797
+ aria-label="GitHub"
1798
+ />
1799
+ </div>
1800
+ </div>
1801
+ </div>
1802
+ </UCard>
1803
+
1804
+ <!-- Badges -->
1805
+ <UCard>
1806
+ <template #header>
1807
+ <div class="flex items-center gap-2">
1808
+ <UIcon name="i-lucide-tag" class="text-primary" />
1809
+ <h3 class="text-xl font-semibold">Badges</h3>
1810
+ </div>
1811
+ </template>
1812
+
1813
+ <div class="space-y-6">
1814
+ <div>
1815
+ <h4 class="text-muted mb-3 text-sm font-medium uppercase tracking-wide">
1816
+ Variants
1817
+ </h4>
1818
+ <div class="flex flex-wrap gap-3">
1819
+ <UBadge variant="solid">Solid</UBadge>
1820
+ <UBadge variant="outline">Outline</UBadge>
1821
+ <UBadge variant="soft">Soft</UBadge>
1822
+ <UBadge variant="subtle">Subtle</UBadge>
1823
+ </div>
1824
+ </div>
1825
+
1826
+ <div>
1827
+ <h4 class="text-muted mb-3 text-sm font-medium uppercase tracking-wide">Colors</h4>
1828
+ <div class="flex flex-wrap gap-3">
1829
+ <UBadge color="primary">Primary</UBadge>
1830
+ <UBadge color="secondary">Secondary</UBadge>
1831
+ <UBadge color="neutral">Neutral</UBadge>
1832
+ <UBadge color="success">Success</UBadge>
1833
+ <UBadge color="warning">Warning</UBadge>
1834
+ <UBadge color="error">Error</UBadge>
1835
+ <UBadge color="info">Info</UBadge>
1836
+ </div>
1837
+ </div>
1838
+ </div>
1839
+ </UCard>
1840
+
1841
+ <!-- Kbd + Progress -->
1842
+ <div class="grid gap-6 md:grid-cols-2">
1843
+ <UCard>
1844
+ <template #header>
1845
+ <div class="flex items-center gap-2">
1846
+ <UIcon name="i-lucide-keyboard" class="text-primary" />
1847
+ <h3 class="text-xl font-semibold">Kbd</h3>
1848
+ </div>
1849
+ </template>
1850
+ <div class="flex flex-wrap items-center gap-4">
1851
+ <div class="flex items-center gap-1">
1852
+ <UKbd>⌘</UKbd><span class="text-muted">+</span>
1853
+ <UKbd>K</UKbd>
1854
+ </div>
1855
+ <div class="flex items-center gap-1">
1856
+ <UKbd>Ctrl</UKbd><span class="text-muted">+</span>
1857
+ <UKbd>S</UKbd>
1858
+ </div>
1859
+ <div class="flex items-center gap-1">
1860
+ <UKbd>⌥</UKbd><span class="text-muted">+</span> <UKbd>⇧</UKbd
1861
+ ><span class="text-muted">+</span>
1862
+ <UKbd>F</UKbd>
1863
+ </div>
1864
+ </div>
1865
+ </UCard>
1866
+
1867
+ <UCard>
1868
+ <template #header>
1869
+ <div class="flex items-center gap-2">
1870
+ <UIcon name="i-lucide-bar-chart-2" class="text-primary" />
1871
+ <h3 class="text-xl font-semibold">Progress</h3>
1872
+ </div>
1873
+ </template>
1874
+ <div class="space-y-4">
1875
+ <UProgress :value="25" color="primary" />
1876
+ <UProgress :value="50" color="success" />
1877
+ <UProgress :value="75" color="warning" />
1878
+ <UProgress :value="90" color="error" />
1879
+ </div>
1880
+ </UCard>
1881
+ </div>
1882
+ </section>
1883
+
1884
+ <!-- Back to top + nav -->
1885
+ <div class="border-default space-y-4 border-t pt-8">
1886
+ <div class="flex flex-wrap justify-center gap-3">
1887
+ <UButton to="/" variant="outline" icon="i-lucide-arrow-left"> Back to Home </UButton>
1888
+ <UButton
1889
+ href="#typography-headlines"
1890
+ variant="ghost"
1891
+ color="neutral"
1892
+ icon="i-lucide-arrow-up"
1893
+ >
1894
+ Back to Top
1895
+ </UButton>
1896
+ <UButton
1897
+ to="https://github.com/kieranmansfield/starter-template"
1898
+ target="_blank"
1899
+ variant="ghost"
1900
+ color="neutral"
1901
+ icon="i-simple-icons-github"
1902
+ >
1903
+ View Source
1904
+ </UButton>
1905
+ </div>
1906
+ <p class="text-muted text-center text-xs">
1907
+ kmcom-nuxt-layers v1.6.3 — {{ tocItems.length }} sections
1908
+ </p>
1909
+ </div>
1910
+ </div>
1911
+ </UContainer>
1912
+ </div>
1913
+ </template>