kmcom-nuxt-layers 4.0.1 → 5.0.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.
Files changed (99) hide show
  1. package/docs/PEER-DEPENDENCY-MISMATCHES.md +48 -0
  2. package/docs/VITE-PLUS-MIGRATION.md +246 -0
  3. package/docs/superpowers/plans/2026-09-03-layout-layer-fluid-rebuild.md +8 -8
  4. package/docs/superpowers/specs/2026-08-30-layer-taxonomy-tier-7-design.md +1 -1
  5. package/docs/superpowers/specs/2026-08-31-swiss-grid-layer-design.md +3 -3
  6. package/docs/superpowers/specs/2026-09-03-layout-layer-fluid-rebuild-design.md +3 -3
  7. package/layers/content/app/components/Blog/Article.vue +1 -1
  8. package/layers/content/app/components/Gallery/Detail.vue +8 -8
  9. package/layers/content/app/components/Gallery/Grid.vue +8 -8
  10. package/layers/content/app/components/Gallery/ImageDetail.vue +6 -6
  11. package/layers/content/app/components/Gallery/Lightbox.vue +3 -3
  12. package/layers/content/app/components/NuxtContent/Detail.vue +1 -1
  13. package/layers/content/app/components/NuxtContent/List.vue +1 -1
  14. package/layers/content/app/components/Portfolio/ColorPalette.vue +5 -5
  15. package/layers/content/app/components/Portfolio/Detail.vue +1 -1
  16. package/layers/content/app/components/Portfolio/List.vue +1 -1
  17. package/layers/content/app/components/Portfolio/Typography.vue +5 -5
  18. package/layers/content/app/components/content/Figure.vue +1 -1
  19. package/layers/core/app/assets/css/layout.css +1 -1
  20. package/layers/core/app/components/DiagnosticsPage.vue +15 -15
  21. package/layers/core/app/components/Element.test.ts +1 -1
  22. package/layers/core/app/components/ElementTw.test.ts +1 -1
  23. package/layers/core/app/components/ErrorBoundary.vue +5 -5
  24. package/layers/core/app/composables/useElementGrid.test.ts +1 -1
  25. package/layers/core/app/composables/useElementInteraction.test.ts +1 -1
  26. package/layers/core/app/composables/useElementLayout.test.ts +1 -1
  27. package/layers/core/app/composables/useElementSizing.test.ts +1 -1
  28. package/layers/core/app/composables/useElementSurface.test.ts +1 -1
  29. package/layers/core/app/composables/useLayoutAttrs.test.ts +1 -1
  30. package/layers/core/app/error.vue +1 -1
  31. package/layers/core/app/pages/[...slug].vue +2 -2
  32. package/layers/core/app/utils/browserInfo.test.ts +1 -1
  33. package/layers/core/app/utils/featureClasses.test.ts +1 -1
  34. package/layers/core/app/utils/scrollGuardClamp.test.ts +1 -1
  35. package/layers/core/app/utils/styleToTailwindClasses.test.ts +1 -1
  36. package/layers/data/forms/app/utils/contact-schema.test.ts +1 -1
  37. package/layers/data/forms/app/utils/fieldProps.test.ts +1 -1
  38. package/layers/data/metadata/providers/comicvine/server/utils/metadata-comicvine/normalise.test.ts +1 -1
  39. package/layers/data/metadata/providers/google-books/server/utils/metadata-google-books/client.test.ts +1 -1
  40. package/layers/data/metadata/providers/google-books/server/utils/metadata-google-books/normalise.test.ts +1 -1
  41. package/layers/data/metadata/providers/openlibrary/server/utils/metadata-openlibrary/client.test.ts +1 -1
  42. package/layers/data/metadata/providers/openlibrary/server/utils/metadata-openlibrary/normalise.test.ts +1 -1
  43. package/layers/data/metadata/providers/themoviedb/server/utils/metadata-tmdb/client.test.ts +1 -1
  44. package/layers/data/metadata/providers/themoviedb/server/utils/metadata-tmdb/normalise.test.ts +1 -1
  45. package/layers/data/metadata/server/utils/metadata/cache.test.ts +1 -1
  46. package/layers/data/metadata/server/utils/metadata/provider-registry.test.ts +1 -1
  47. package/layers/data/metadata/server/utils/metadata/search.test.ts +1 -1
  48. package/layers/delivery/feeds/app/assets/css/feeds.css +23 -11
  49. package/layers/delivery/feeds/app/components/Feeds/Index.vue +10 -10
  50. package/layers/delivery/feeds/app/components/Feeds/RouteCard.vue +1 -1
  51. package/layers/delivery/feeds/public/feed/style.css +16 -16
  52. package/layers/delivery/feeds/server/utils/content-adapter.test.ts +1 -1
  53. package/layers/delivery/feeds/server/utils/feed-author.test.ts +1 -1
  54. package/layers/delivery/feeds/server/utils/feed-config.test.ts +1 -1
  55. package/layers/delivery/feeds/server/utils/formats.test.ts +1 -1
  56. package/layers/delivery/scripts/app/components/BaselineStatus.vue +3 -1
  57. package/layers/delivery/seo/app/utils/seoConfig.test.ts +1 -1
  58. package/layers/design-system/theming/app/assets/css/theme.css +0 -1
  59. package/layers/design-system/theming/app/components/ThemePicker/AccentButton.vue +2 -2
  60. package/layers/design-system/theming/app/components/ThemePicker/Menu.vue +3 -3
  61. package/layers/design-system/theming/app/composables/useAccentColor.ts +4 -1
  62. package/layers/design-system/theming/app/plugins/theme.client.ts +15 -13
  63. package/layers/design-system/theming/app/utils/themeAdapter.ts +1 -1
  64. package/layers/design-system/theming/nuxt.config.ts +1 -1
  65. package/layers/design-system/theming/server/utils/accent-css.test.ts +1 -1
  66. package/layers/design-system/theming/server/utils/fouc-config.test.ts +1 -1
  67. package/layers/design-system/typography/app/components/Typography/TextStroke.vue +1 -1
  68. package/layers/design-system/visual/app/assets/css/visual.css +0 -1
  69. package/layers/design-system/visual/app/components/Accent/Scene.vue +2 -2
  70. package/layers/design-system/visual/app/components/Tint/Overlay.vue +1 -1
  71. package/layers/design-system/visual/app/utils/colorTokens.test.ts +1 -1
  72. package/layers/design-system/visual/app/utils/gradientStyle.test.ts +1 -1
  73. package/layers/design-system/visual/app/utils/responsiveSizes.test.ts +1 -1
  74. package/layers/motion/animations/app/components/Motion/Marquee.vue +1 -1
  75. package/layers/motion/animations/app/components/Motion/MarqueeText.vue +3 -3
  76. package/layers/motion/scroll/app/components/Motion/HorizontalScroll.vue +1 -1
  77. package/layers/motion/scroll/app/components/Motion/PinnedSection.vue +2 -2
  78. package/layers/motion/scroll/app/components/Motion/ScrollProgress.vue +2 -2
  79. package/layers/motion/scroll/app/components/Motion/ScrollStats.vue +6 -6
  80. package/layers/motion/transitions/app/assets/css/transitions.css +12 -12
  81. package/layers/render/canvas/nuxt.config.ts +1 -1
  82. package/layers/render/canvas/package.json +2 -1
  83. package/layers/render/shader/app/assets/css/shader.css +5 -5
  84. package/layers/render/shader/app/shaders/common/grain.ts +1 -1
  85. package/layers/render/shader/app/types/tsl.ts +1 -1
  86. package/layers/render/shader/app/utils/tsl/index.ts +2 -0
  87. package/layers/structure/grid/app/assets/css/grid.css +2 -0
  88. package/layers/structure/grid/app/composables/useGridTracks.test.ts +1 -1
  89. package/layers/structure/grid/app/types/tracks.test.ts +1 -1
  90. package/layers/structure/grid/app/utils/placement.test.ts +1 -1
  91. package/layers/structure/layout/app/components/Layout/Grid/Debug.vue +1 -1
  92. package/layers/structure/layout/app/components/Layout/Page/Header.vue +3 -3
  93. package/layers/structure/layout/app/components/Layout/Page/index.vue +16 -11
  94. package/layers/structure/layout/app/utils/gridPlacementStyle.test.ts +1 -1
  95. package/layers/structure/navigation/app/components/Mast/Nav.vue +1 -1
  96. package/layers/structure/navigation/app/components/Mast/NavModal.vue +2 -2
  97. package/layers/structure/navigation/app/utils/site.test.ts +1 -1
  98. package/layers/structure/routing/app/utils/resolveRoute.test.ts +1 -1
  99. package/package.json +26 -45
@@ -48,7 +48,7 @@
48
48
  v-if="asPortfolio(item).image"
49
49
  :src="asPortfolio(item).image"
50
50
  :alt="item.title"
51
- class="w-full rounded-lg mb-8"
51
+ class="mb-8 w-full rounded-lg"
52
52
  />
53
53
  </template>
54
54
 
@@ -56,7 +56,7 @@
56
56
  v-if="item.image"
57
57
  :src="item.image"
58
58
  :alt="item.title"
59
- class="w-full h-48 object-cover rounded"
59
+ class="h-48 w-full rounded object-cover"
60
60
  />
61
61
  <template #footer>
62
62
  <div class="flex flex-wrap gap-1.5">
@@ -8,24 +8,24 @@
8
8
 
9
9
  <template>
10
10
  <div v-if="typography.length" class="space-y-6">
11
- <h3 class="text-2xl font-semibold tracking-tight text-highlighted">Typography</h3>
11
+ <h3 class="text-highlighted text-2xl font-semibold tracking-tight">Typography</h3>
12
12
  <div class="mt-8 flex flex-col gap-24">
13
13
  <div v-for="font in typography" :key="font.name" class="flex flex-col gap-6">
14
14
  <div class="flex items-baseline justify-between gap-4">
15
- <p class="font-name font-semibold text-highlighted tracking-tight truncate">
15
+ <p class="font-name text-highlighted truncate font-semibold tracking-tight">
16
16
  {{ font.name }}
17
17
  </p>
18
- <p v-if="font.usage" class="text-sm text-muted shrink-0">{{ font.usage }}</p>
18
+ <p v-if="font.usage" class="text-muted shrink-0 text-sm">{{ font.usage }}</p>
19
19
  </div>
20
20
  <p class="font-sample text-muted tracking-wide">ABCDEFGHabcdefgh 0123456789</p>
21
21
  <div class="flex items-center gap-4">
22
- <span class="text-xs font-mono text-muted uppercase tracking-widest opacity-50">
22
+ <span class="text-muted font-mono text-xs tracking-widest uppercase opacity-50">
23
23
  Weights
24
24
  </span>
25
25
  <span
26
26
  v-for="weight in font.weights"
27
27
  :key="weight"
28
- class="text-xs font-mono text-muted uppercase tracking-widest"
28
+ class="text-muted font-mono text-xs tracking-widest uppercase"
29
29
  >
30
30
  {{ weight }}
31
31
  </span>
@@ -17,7 +17,7 @@
17
17
  <template>
18
18
  <figure class="my-6">
19
19
  <img :src :alt :width :height class="w-full rounded-lg" />
20
- <figcaption v-if="caption" class="mt-2 text-center text-sm text-muted italic">
20
+ <figcaption v-if="caption" class="text-muted mt-2 text-center text-sm italic">
21
21
  {{ caption }}
22
22
  </figcaption>
23
23
  </figure>
@@ -14,7 +14,7 @@
14
14
  hr {
15
15
  margin: 1rem 0;
16
16
  border: 0;
17
- border-top: 1px solid #ccc;
17
+ border-top: 1px solid oklch(84.52% 0 0deg);
18
18
  }
19
19
 
20
20
  img,
@@ -30,7 +30,7 @@
30
30
  <ClientOnly>
31
31
  <div class="space-y-8">
32
32
  <div class="text-center">
33
- <h1 class="text-4xl font-bold mb-2">Core Layer Diagnostics</h1>
33
+ <h1 class="mb-2 text-4xl font-bold">Core Layer Diagnostics</h1>
34
34
  <p class="text-gray-500 dark:text-gray-400">Feature detection and system information</p>
35
35
  </div>
36
36
 
@@ -124,7 +124,7 @@
124
124
  </template>
125
125
  <div class="space-y-2">
126
126
  <div class="flex items-center gap-2">
127
- <span class="font-medium w-24">Type:</span>
127
+ <span class="w-24 font-medium">Type:</span>
128
128
  <span v-if="isMobile" class="text-primary">Mobile</span>
129
129
  <span v-else-if="isTablet" class="text-primary">Tablet</span>
130
130
  <span v-else-if="isDesktop" class="text-primary">Desktop</span>
@@ -138,16 +138,16 @@
138
138
  </template>
139
139
  <div class="space-y-2">
140
140
  <div class="flex items-center gap-2">
141
- <span class="font-medium w-24">Status:</span>
141
+ <span class="w-24 font-medium">Status:</span>
142
142
  <span v-if="isOnline" class="text-green-500">Online</span>
143
143
  <span v-else class="text-red-500">Offline</span>
144
144
  </div>
145
145
  <div class="flex items-center gap-2">
146
- <span class="font-medium w-24">Type:</span>
146
+ <span class="w-24 font-medium">Type:</span>
147
147
  <span>{{ effectiveType || 'unknown' }}</span>
148
148
  </div>
149
149
  <div class="flex items-center gap-2">
150
- <span class="font-medium w-24">Quality:</span>
150
+ <span class="w-24 font-medium">Quality:</span>
151
151
  <span
152
152
  :class="{
153
153
  'text-green-500': connectionQuality === 'excellent',
@@ -160,13 +160,13 @@
160
160
  </span>
161
161
  </div>
162
162
  <div class="flex items-center gap-2">
163
- <span class="font-medium w-24">Speed:</span>
163
+ <span class="w-24 font-medium">Speed:</span>
164
164
  <span v-if="isFast" class="text-green-500">Fast</span>
165
165
  <span v-else-if="isSlow" class="text-red-500">Slow</span>
166
166
  <span v-else>Normal</span>
167
167
  </div>
168
168
  <div v-if="saveData" class="flex items-center gap-2">
169
- <span class="font-medium w-24">Data Saver:</span>
169
+ <span class="w-24 font-medium">Data Saver:</span>
170
170
  <span class="text-yellow-500">Enabled</span>
171
171
  </div>
172
172
  </div>
@@ -178,16 +178,16 @@
178
178
  </template>
179
179
  <div class="space-y-2">
180
180
  <div class="flex items-center gap-2">
181
- <span class="font-medium w-24">Mode:</span>
182
- <span class="uppercase text-primary">{{ mode }}</span>
181
+ <span class="w-24 font-medium">Mode:</span>
182
+ <span class="text-primary uppercase">{{ mode }}</span>
183
183
  </div>
184
184
  <div class="flex items-center gap-2">
185
- <span class="font-medium w-24">Environment:</span>
185
+ <span class="w-24 font-medium">Environment:</span>
186
186
  <span v-if="isClient" class="text-primary">Client</span>
187
187
  <span v-else-if="isServer" class="text-primary">Server</span>
188
188
  </div>
189
189
  <div class="flex items-center gap-2">
190
- <span class="font-medium w-24">Hydrated:</span>
190
+ <span class="w-24 font-medium">Hydrated:</span>
191
191
  <span v-if="isHydrated" class="text-green-500">Yes</span>
192
192
  <span v-else class="text-yellow-500">No</span>
193
193
  </div>
@@ -200,17 +200,17 @@
200
200
  </template>
201
201
  <div class="space-y-2">
202
202
  <div class="flex items-center gap-2">
203
- <span class="font-medium w-24">Installed:</span>
203
+ <span class="w-24 font-medium">Installed:</span>
204
204
  <span v-if="isInstalled" class="text-green-500">Yes</span>
205
205
  <span v-else class="text-gray-500">No</span>
206
206
  </div>
207
207
  <div class="flex items-center gap-2">
208
- <span class="font-medium w-24">Installable:</span>
208
+ <span class="w-24 font-medium">Installable:</span>
209
209
  <span v-if="canInstall" class="text-green-500">Yes</span>
210
210
  <span v-else class="text-gray-500">No</span>
211
211
  </div>
212
212
  <div v-if="needRefresh" class="flex items-center gap-2">
213
- <span class="font-medium w-24">Update:</span>
213
+ <span class="w-24 font-medium">Update:</span>
214
214
  <span class="text-yellow-500">Available</span>
215
215
  </div>
216
216
  </div>
@@ -218,7 +218,7 @@
218
218
  </div>
219
219
 
220
220
  <template #fallback>
221
- <div class="text-center text-muted py-16">Loading diagnostics…</div>
221
+ <div class="text-muted py-16 text-center">Loading diagnostics…</div>
222
222
  </template>
223
223
  </ClientOnly>
224
224
  </UContainer>
@@ -1,6 +1,6 @@
1
1
  import { defineComponent, h } from 'vue'
2
2
  import { mount } from '@vue/test-utils'
3
- import { describe, expect, it } from 'vitest'
3
+ import { describe, expect, it } from 'vite-plus/test'
4
4
 
5
5
  import Element from './Element.vue'
6
6
 
@@ -1,6 +1,6 @@
1
1
  import { defineComponent, h } from 'vue'
2
2
  import { mount } from '@vue/test-utils'
3
- import { describe, expect, it } from 'vitest'
3
+ import { describe, expect, it } from 'vite-plus/test'
4
4
 
5
5
  import ElementTw from './ElementTw.vue'
6
6
 
@@ -61,25 +61,25 @@
61
61
  <template #error="{ error, clearError }">
62
62
  <slot name="error" :error :clear-error>
63
63
  <!-- Default error UI -->
64
- <div class="rounded-lg border border-error bg-error/10 p-4">
64
+ <div class="border-error bg-error/10 rounded-lg border p-4">
65
65
  <div class="flex items-start gap-3">
66
66
  <!-- Error icon -->
67
67
  <span
68
- class="iconify i-lucide:alert-circle mt-0.5 shrink-0 text-error"
68
+ class="iconify i-lucide:alert-circle text-error mt-0.5 shrink-0"
69
69
  aria-hidden="true"
70
70
  />
71
71
 
72
72
  <!-- Error content -->
73
73
  <div class="flex-1 space-y-2">
74
74
  <!-- Error message -->
75
- <p class="text-sm font-medium text-error">
75
+ <p class="text-error text-sm font-medium">
76
76
  {{ message }}
77
77
  </p>
78
78
 
79
79
  <!-- Error details (dev only) -->
80
80
  <details v-if="showDetails && import.meta.dev" class="text-xs">
81
- <summary class="cursor-pointer text-muted">Show error details</summary>
82
- <pre class="mt-2 overflow-x-auto rounded bg-elevated p-2">{{ error }}</pre>
81
+ <summary class="text-muted cursor-pointer">Show error details</summary>
82
+ <pre class="bg-elevated mt-2 overflow-x-auto rounded p-2">{{ error }}</pre>
83
83
  </details>
84
84
 
85
85
  <!-- Retry button -->
@@ -1,4 +1,4 @@
1
- import { describe, expect, it } from 'vitest'
1
+ import { describe, expect, it } from 'vite-plus/test'
2
2
 
3
3
  import { useElementGrid } from './useElementGrid'
4
4
 
@@ -1,4 +1,4 @@
1
- import { describe, expect, it } from 'vitest'
1
+ import { describe, expect, it } from 'vite-plus/test'
2
2
 
3
3
  import { useElementInteraction } from './useElementInteraction'
4
4
 
@@ -1,4 +1,4 @@
1
- import { describe, expect, it } from 'vitest'
1
+ import { describe, expect, it } from 'vite-plus/test'
2
2
 
3
3
  import { useElementLayout } from './useElementLayout'
4
4
 
@@ -1,4 +1,4 @@
1
- import { describe, expect, it } from 'vitest'
1
+ import { describe, expect, it } from 'vite-plus/test'
2
2
 
3
3
  import { useElementSizing } from './useElementSizing'
4
4
 
@@ -1,4 +1,4 @@
1
- import { describe, expect, it } from 'vitest'
1
+ import { describe, expect, it } from 'vite-plus/test'
2
2
 
3
3
  import { useElementSurface } from './useElementSurface'
4
4
 
@@ -1,4 +1,4 @@
1
- import { describe, expect, it } from 'vitest'
1
+ import { describe, expect, it } from 'vite-plus/test'
2
2
 
3
3
  import { useLayoutAttrs } from './useLayoutAttrs'
4
4
 
@@ -34,7 +34,7 @@
34
34
  <template #description>
35
35
  <div class="space-y-2">
36
36
  <p class="text-muted">{{ message }}</p>
37
- <code v-if="error?.statusMessage" class="block rounded bg-elevated px-2 py-1 text-sm">
37
+ <code v-if="error?.statusMessage" class="bg-elevated block rounded px-2 py-1 text-sm">
38
38
  {{ error.statusMessage }}
39
39
  </code>
40
40
  </div>
@@ -88,10 +88,10 @@
88
88
  <UEmpty :icon :title :description size="xl">
89
89
  <!-- Show attempted path -->
90
90
  <template v-if="config.showPath !== false" #description>
91
- <p class="mb-2 text-muted">
91
+ <p class="text-muted mb-2">
92
92
  {{ description }}
93
93
  </p>
94
- <code class="rounded bg-elevated px-2 py-1 text-sm">
94
+ <code class="bg-elevated rounded px-2 py-1 text-sm">
95
95
  {{ attemptedPath }}
96
96
  </code>
97
97
  </template>
@@ -1,4 +1,4 @@
1
- import { describe, expect, it } from 'vitest'
1
+ import { describe, expect, it } from 'vite-plus/test'
2
2
 
3
3
  import { getBrowserVersionParts, isBrowserAtLeast, parseBrowserInfo } from './browserInfo'
4
4
 
@@ -1,4 +1,4 @@
1
- import { describe, expect, it } from 'vitest'
1
+ import { describe, expect, it } from 'vite-plus/test'
2
2
 
3
3
  import type { FeatureDetection } from '../types/detection'
4
4
  import { getFeatureClassNames } from './featureClasses'
@@ -1,4 +1,4 @@
1
- import { describe, expect, it } from 'vitest'
1
+ import { describe, expect, it } from 'vite-plus/test'
2
2
 
3
3
  import { isOverflowing, shouldExclude } from './scrollGuardClamp'
4
4
 
@@ -1,4 +1,4 @@
1
- import { describe, expect, it } from 'vitest'
1
+ import { describe, expect, it } from 'vite-plus/test'
2
2
 
3
3
  import { styleToTailwindClasses } from './styleToTailwindClasses'
4
4
 
@@ -1,4 +1,4 @@
1
- import { describe, expect, it } from 'vitest'
1
+ import { describe, expect, it } from 'vite-plus/test'
2
2
 
3
3
  import { contactSchema } from './contact-schema'
4
4
 
@@ -1,4 +1,4 @@
1
- import { describe, expect, it } from 'vitest'
1
+ import { describe, expect, it } from 'vite-plus/test'
2
2
 
3
3
  import type { FieldConfig } from '../types/fields'
4
4
  import {
@@ -1,4 +1,4 @@
1
- import { describe, expect, it } from 'vitest'
1
+ import { describe, expect, it } from 'vite-plus/test'
2
2
 
3
3
  import { normaliseComicVineIssue, normaliseComicVineVolume } from './normalise'
4
4
  import type { ComicVineIssue, ComicVineVolume } from './types'
@@ -1,4 +1,4 @@
1
- import { describe, expect, it } from 'vitest'
1
+ import { describe, expect, it } from 'vite-plus/test'
2
2
 
3
3
  import { googleBooksCoverUrl, googleBooksMediaType } from './client'
4
4
 
@@ -1,4 +1,4 @@
1
- import { describe, expect, it, vi } from 'vitest'
1
+ import { describe, expect, it, vi } from 'vite-plus/test'
2
2
 
3
3
  import { googleBooksCoverUrl, googleBooksMediaType } from './client'
4
4
  import { normaliseGoogleBooksVolume } from './normalise'
@@ -1,4 +1,4 @@
1
- import { describe, expect, it } from 'vitest'
1
+ import { describe, expect, it } from 'vite-plus/test'
2
2
 
3
3
  import { openLibraryCoverUrl } from './client'
4
4
 
@@ -1,4 +1,4 @@
1
- import { describe, expect, it, vi } from 'vitest'
1
+ import { describe, expect, it, vi } from 'vite-plus/test'
2
2
 
3
3
  import { openLibraryCoverUrl } from './client'
4
4
  import {
@@ -1,4 +1,4 @@
1
- import { describe, expect, it, vi } from 'vitest'
1
+ import { describe, expect, it, vi } from 'vite-plus/test'
2
2
 
3
3
  vi.stubGlobal('useRuntimeConfig', () => ({
4
4
  metadataTmdb: {
@@ -1,4 +1,4 @@
1
- import { describe, expect, it, vi } from 'vitest'
1
+ import { describe, expect, it, vi } from 'vite-plus/test'
2
2
 
3
3
  import { tmdbImageUrl } from './client'
4
4
  import { normaliseTmdbMovie, normaliseTmdbSearchResult, normaliseTmdbTV } from './normalise'
@@ -1,4 +1,4 @@
1
- import { describe, expect, it } from 'vitest'
1
+ import { describe, expect, it } from 'vite-plus/test'
2
2
 
3
3
  import { hashQuery, makeCacheKey } from './cache'
4
4
 
@@ -1,5 +1,5 @@
1
1
  import type { MetadataProvider } from '#layers/metadata/shared/types'
2
- import { describe, expect, it } from 'vitest'
2
+ import { describe, expect, it } from 'vite-plus/test'
3
3
 
4
4
  import { getProvider, getProviders, registerProvider } from './provider-registry'
5
5
 
@@ -3,7 +3,7 @@ import type {
3
3
  MetadataSearchInput,
4
4
  MetadataSearchResult,
5
5
  } from '#layers/metadata/shared/types'
6
- import { beforeEach, describe, expect, it, vi } from 'vitest'
6
+ import { beforeEach, describe, expect, it, vi } from 'vite-plus/test'
7
7
 
8
8
  import { hashQuery, makeCacheKey } from './cache'
9
9
 
@@ -17,42 +17,54 @@
17
17
  }
18
18
 
19
19
  .feed-badge-rss {
20
- background-color: color-mix(in srgb, var(--color-orange-500, #f97316) 12%, transparent);
21
- color: var(--color-orange-600, #ea580c);
20
+ background-color: color-mix(
21
+ in srgb,
22
+ var(--color-orange-500, oklch(70.49% 0.1867 47.6deg)) 12%,
23
+ transparent
24
+ );
25
+ color: var(--color-orange-600, oklch(64.61% 0.1943 41.12deg));
22
26
  }
23
27
 
24
28
  .feed-badge-atom {
25
- background-color: color-mix(in srgb, var(--color-purple-500, #a855f7) 12%, transparent);
26
- color: var(--color-purple-600, #9333ea);
29
+ background-color: color-mix(
30
+ in srgb,
31
+ var(--color-purple-500, oklch(62.68% 0.2325 303.9deg)) 12%,
32
+ transparent
33
+ );
34
+ color: var(--color-purple-600, oklch(55.75% 0.2525 302.32deg));
27
35
  }
28
36
 
29
37
  .feed-badge-json {
30
- background-color: color-mix(in srgb, var(--color-yellow-500, #eab308) 12%, transparent);
31
- color: var(--color-yellow-600, #ca8a04);
38
+ background-color: color-mix(
39
+ in srgb,
40
+ var(--color-yellow-500, oklch(79.52% 0.1617 86.05deg)) 12%,
41
+ transparent
42
+ );
43
+ color: var(--color-yellow-600, oklch(68.06% 0.1423 75.83deg));
32
44
  }
33
45
 
34
46
  @media (prefers-color-scheme: dark) {
35
47
  .feed-badge-rss {
36
- color: var(--color-orange-400, #fb923c);
48
+ color: var(--color-orange-400, oklch(75.76% 0.159 55.93deg));
37
49
  }
38
50
 
39
51
  .feed-badge-atom {
40
- color: var(--color-purple-400, #c084fc);
52
+ color: var(--color-purple-400, oklch(72.17% 0.1767 305.5deg));
41
53
  }
42
54
 
43
55
  .feed-badge-json {
44
- color: var(--color-yellow-400, #facc15);
56
+ color: var(--color-yellow-400, oklch(86.06% 0.1731 91.94deg));
45
57
  }
46
58
  }
47
59
 
48
60
  /* Feed preview code block — used in playground and consuming apps */
49
61
  .feed-preview {
50
62
  border-radius: var(--ui-radius, 0.375rem);
51
- background-color: var(--color-gray-950, #030712);
63
+ background-color: var(--color-gray-950, oklch(12.96% 0.0274 261.69deg));
52
64
  padding: 1rem;
53
65
  max-height: 24rem;
54
66
  overflow: auto;
55
- color: var(--color-gray-100, #f3f4f6);
67
+ color: var(--color-gray-100, oklch(96.7% 0.0029 264.54deg));
56
68
  font-size: 0.75rem;
57
69
  line-height: 1.6;
58
70
  font-family: var(--font-mono, ui-monospace, monospace);
@@ -25,10 +25,10 @@
25
25
  >
26
26
  <div class="pointer-events-none absolute inset-0">
27
27
  <div
28
- class="absolute -right-20 top-0 h-72 w-72 rounded-full bg-orange-400/20 blur-3xl dark:bg-orange-500/15"
28
+ class="absolute top-0 -right-20 h-72 w-72 rounded-full bg-orange-400/20 blur-3xl dark:bg-orange-500/15"
29
29
  />
30
30
  <div
31
- class="absolute -left-20 bottom-0 h-80 w-80 rounded-full bg-sky-400/12 blur-3xl dark:bg-sky-500/10"
31
+ class="absolute bottom-0 -left-20 h-80 w-80 rounded-full bg-sky-400/12 blur-3xl dark:bg-sky-500/10"
32
32
  />
33
33
  <div
34
34
  class="absolute inset-x-8 top-0 h-px bg-linear-to-r from-transparent via-orange-400/35 to-transparent"
@@ -39,7 +39,7 @@
39
39
  <div class="feeds-split grid gap-6">
40
40
  <div class="space-y-6">
41
41
  <div
42
- class="inline-flex items-center gap-2 rounded-full border border-amber-200/80 bg-white/80 px-3 py-1 text-[0.68rem] font-semibold uppercase tracking-[0.35em] text-amber-700 shadow-sm backdrop-blur dark:border-slate-700 dark:bg-slate-900/60 dark:text-amber-200"
42
+ class="inline-flex items-center gap-2 rounded-full border border-amber-200/80 bg-white/80 px-3 py-1 text-[0.68rem] font-semibold tracking-[0.35em] text-amber-700 uppercase shadow-sm backdrop-blur dark:border-slate-700 dark:bg-slate-900/60 dark:text-amber-200"
43
43
  >
44
44
  <UIcon name="i-lucide-rss" class="text-sm" />
45
45
  Feeds layer
@@ -63,7 +63,7 @@
63
63
  class="rounded-2xl border border-slate-200/80 bg-white/75 p-4 shadow-sm backdrop-blur dark:border-slate-800 dark:bg-slate-900/45"
64
64
  >
65
65
  <p
66
- class="text-[0.68rem] font-semibold uppercase tracking-[0.3em] text-slate-500 dark:text-slate-400"
66
+ class="text-[0.68rem] font-semibold tracking-[0.3em] text-slate-500 uppercase dark:text-slate-400"
67
67
  >
68
68
  Default
69
69
  </p>
@@ -79,7 +79,7 @@
79
79
  class="rounded-2xl border border-slate-200/80 bg-white/75 p-4 shadow-sm backdrop-blur dark:border-slate-800 dark:bg-slate-900/45"
80
80
  >
81
81
  <p
82
- class="text-[0.68rem] font-semibold uppercase tracking-[0.3em] text-slate-500 dark:text-slate-400"
82
+ class="text-[0.68rem] font-semibold tracking-[0.3em] text-slate-500 uppercase dark:text-slate-400"
83
83
  >
84
84
  Exposed
85
85
  </p>
@@ -95,7 +95,7 @@
95
95
  class="rounded-2xl border border-slate-200/80 bg-white/75 p-4 shadow-sm backdrop-blur dark:border-slate-800 dark:bg-slate-900/45"
96
96
  >
97
97
  <p
98
- class="text-[0.68rem] font-semibold uppercase tracking-[0.3em] text-slate-500 dark:text-slate-400"
98
+ class="text-[0.68rem] font-semibold tracking-[0.3em] text-slate-500 uppercase dark:text-slate-400"
99
99
  >
100
100
  Limit
101
101
  </p>
@@ -113,7 +113,7 @@
113
113
  class="flex flex-wrap items-center gap-3 rounded-2xl border border-slate-200/80 bg-white/70 px-4 py-3 text-sm shadow-sm backdrop-blur dark:border-slate-800 dark:bg-slate-900/45"
114
114
  >
115
115
  <span
116
- class="text-xs font-semibold uppercase tracking-[0.3em] text-slate-500 dark:text-slate-400"
116
+ class="text-xs font-semibold tracking-[0.3em] text-slate-500 uppercase dark:text-slate-400"
117
117
  >
118
118
  Site
119
119
  </span>
@@ -134,7 +134,7 @@
134
134
  >
135
135
  <div class="flex items-center justify-between gap-3">
136
136
  <p
137
- class="text-[0.68rem] font-semibold uppercase tracking-[0.35em] text-slate-500 dark:text-slate-400"
137
+ class="text-[0.68rem] font-semibold tracking-[0.35em] text-slate-500 uppercase dark:text-slate-400"
138
138
  >
139
139
  Global routes
140
140
  </p>
@@ -162,7 +162,7 @@
162
162
  <div class="flex flex-wrap items-end justify-between gap-4">
163
163
  <div>
164
164
  <p
165
- class="text-[0.68rem] font-semibold uppercase tracking-[0.35em] text-slate-500 dark:text-slate-400"
165
+ class="text-[0.68rem] font-semibold tracking-[0.35em] text-slate-500 uppercase dark:text-slate-400"
166
166
  >
167
167
  Collection routes
168
168
  </p>
@@ -190,7 +190,7 @@
190
190
  >
191
191
  <div>
192
192
  <p
193
- class="text-[0.68rem] font-semibold uppercase tracking-[0.35em] text-slate-500 dark:text-slate-400"
193
+ class="text-[0.68rem] font-semibold tracking-[0.35em] text-slate-500 uppercase dark:text-slate-400"
194
194
  >
195
195
  Collection
196
196
  </p>
@@ -50,7 +50,7 @@
50
50
  <UCard
51
51
  :to="route.path"
52
52
  :ui="{ body: 'p-0' }"
53
- class="group relative overflow-hidden border-slate-200/80 bg-white/90 shadow-none transition duration-200 hover:-translate-y-0.5 hover:border-slate-300 hover:shadow-md dark:border-slate-800 dark:bg-slate-950/55 dark:hover:border-slate-700 @container"
53
+ class="group @container relative overflow-hidden border-slate-200/80 bg-white/90 shadow-none transition duration-200 hover:-translate-y-0.5 hover:border-slate-300 hover:shadow-md dark:border-slate-800 dark:bg-slate-950/55 dark:hover:border-slate-700"
54
54
  >
55
55
  <div class="absolute inset-y-0 left-0 w-1" :class="routeTone.strip" />
56
56
  <div :class="compact ? 'flex items-center gap-3 p-3' : 'flex items-center gap-3 p-4'">