kmcom-nuxt-layers 2.2.6 → 2.2.9

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 (202) hide show
  1. package/docs/FEEDS.md +197 -0
  2. package/docs/LAYERS-FIXES.md +101 -0
  3. package/docs/MIGRATION.md +627 -0
  4. package/docs/feed-layer.md +374 -0
  5. package/docs/patch-picture-provider-type.md +52 -0
  6. package/docs/shaderGuide.md +2071 -0
  7. package/docs/types-architecture.md +234 -0
  8. package/layers/animations/app/components/Motion/CountUp.vue +1 -2
  9. package/layers/animations/app/components/Motion/Magnetic.vue +1 -2
  10. package/layers/animations/app/components/Motion/Marquee.vue +2 -5
  11. package/layers/animations/app/components/Motion/MarqueeText.vue +1 -2
  12. package/layers/animations/app/components/Motion/Tilt.vue +1 -2
  13. package/layers/animations/app/composables/useCountUp.ts +4 -1
  14. package/layers/animations/app/composables/useMagneticElement.ts +1 -3
  15. package/layers/animations/app/composables/useMarqueeCopies.ts +3 -3
  16. package/layers/animations/app/types/animations.ts +8 -0
  17. package/layers/animations/app/types/index.ts +1 -0
  18. package/layers/animations/package.json +4 -1
  19. package/layers/canvas/app/components/ShaderCanvas.vue +4 -4
  20. package/layers/canvas/app/composables/useRendererCapabilities.ts +19 -15
  21. package/layers/canvas/app/types/index.ts +1 -0
  22. package/layers/canvas/package.json +2 -1
  23. package/layers/canvas/tsconfig.json +2 -1
  24. package/layers/content/app/components/Blog/Card.vue +5 -5
  25. package/layers/content/app/components/Gallery/AmbientImage.vue +3 -3
  26. package/layers/content/app/components/Gallery/Card.vue +3 -3
  27. package/layers/content/app/components/NuxtContent/Detail.vue +5 -1
  28. package/layers/content/app/components/NuxtContent/Surround.vue +5 -3
  29. package/layers/content/app/components/NuxtContent/Toc.vue +1 -1
  30. package/layers/content/app/components/Portfolio/Card.vue +5 -5
  31. package/layers/content/app/components/content/Figure.vue +3 -3
  32. package/layers/content/app/types/index.ts +1 -0
  33. package/layers/content/package.json +2 -1
  34. package/layers/core/app/composables/useErrorLog.ts +9 -11
  35. package/layers/core/app/utils/helpers.ts +14 -12
  36. package/layers/core/nuxt.config.ts +1 -0
  37. package/layers/feeds/app/plugins/feed-head.ts +1 -2
  38. package/layers/feeds/package.json +2 -1
  39. package/layers/feeds/public/feed/style.css +256 -0
  40. package/layers/feeds/server/routes/feed/discovery.get.ts +1 -2
  41. package/layers/feeds/server/utils/content-adapter.ts +3 -2
  42. package/layers/forms/app/components/Form/Field.vue +4 -4
  43. package/layers/forms/app/types/index.ts +1 -0
  44. package/layers/forms/package.json +2 -1
  45. package/layers/layout/app/components/Layout/Grid/Item.vue +33 -19
  46. package/layers/layout/app/components/Layout/Page/Container.vue +11 -11
  47. package/layers/layout/app/components/Layout/Page/Header.vue +1 -1
  48. package/layers/layout/app/components/Layout/Page/index.vue +1 -1
  49. package/layers/layout/app/components/Layout/Section/Gallery.vue +6 -1
  50. package/layers/layout/app/components/Layout/Section/Title.vue +1 -1
  51. package/layers/layout/app/types/index.ts +1 -0
  52. package/layers/layout/package.json +2 -1
  53. package/layers/mailer/app/types/index.ts +1 -0
  54. package/layers/mailer/app/types/mailer.ts +25 -0
  55. package/layers/mailer/package.json +2 -1
  56. package/layers/motion/package.json +2 -1
  57. package/layers/navigation/app/components/Links/Group.vue +1 -0
  58. package/layers/navigation/app/components/Links/Named.vue +2 -0
  59. package/layers/navigation/app/types/index.ts +1 -0
  60. package/layers/navigation/package.json +4 -1
  61. package/layers/page-transitions/package.json +4 -1
  62. package/layers/routing/app/types/app-config.d.ts +3 -1
  63. package/layers/routing/app/types/index.ts +1 -0
  64. package/layers/routing/package.json +2 -1
  65. package/layers/scripts/app/composables/useGtm.ts +1 -1
  66. package/layers/scripts/app/types/index.ts +1 -0
  67. package/layers/scripts/app/types/scripts.ts +14 -0
  68. package/layers/scripts/package.json +2 -1
  69. package/layers/scroll/app/components/Motion/ScrollScene.vue +3 -1
  70. package/layers/scroll/app/composables/useScrollSteps.ts +2 -9
  71. package/layers/scroll/app/composables/useSectionProgress.ts +2 -1
  72. package/layers/scroll/app/plugins/locomotive-scroll.client.ts +1 -8
  73. package/layers/scroll/app/types/index.ts +1 -0
  74. package/layers/scroll/app/types/scroll.ts +32 -0
  75. package/layers/scroll/package.json +3 -0
  76. package/layers/seo/package.json +2 -1
  77. package/layers/shader/app/components/Material/Fresnel.client.vue +1 -1
  78. package/layers/shader/app/components/Material/Image.client.vue +1 -1
  79. package/layers/shader/app/components/Material/Node.client.vue +7 -7
  80. package/layers/shader/app/components/Material/Noise.client.vue +1 -1
  81. package/layers/shader/app/components/Node/Color.client.vue +17 -20
  82. package/layers/shader/app/components/Node/Noise.client.vue +31 -34
  83. package/layers/shader/app/components/Pipeline/Aurora.client.vue +4 -8
  84. package/layers/shader/app/components/Pipeline/BilinearGradient.client.vue +8 -11
  85. package/layers/shader/app/components/Pipeline/BillowNoise.client.vue +4 -8
  86. package/layers/shader/app/components/Pipeline/BrightnessContrast.client.vue +6 -2
  87. package/layers/shader/app/components/Pipeline/CellularNoise.client.vue +4 -8
  88. package/layers/shader/app/components/Pipeline/Checkerboard.client.vue +4 -8
  89. package/layers/shader/app/components/Pipeline/Circle.client.vue +5 -8
  90. package/layers/shader/app/components/Pipeline/Clouds.client.vue +4 -8
  91. package/layers/shader/app/components/Pipeline/ColorBurnBlend.client.vue +2 -19
  92. package/layers/shader/app/components/Pipeline/ColorDodgeBlend.client.vue +2 -19
  93. package/layers/shader/app/components/Pipeline/ColourRamp.client.vue +5 -9
  94. package/layers/shader/app/components/Pipeline/ConicGradient.client.vue +5 -8
  95. package/layers/shader/app/components/Pipeline/Cross.client.vue +4 -8
  96. package/layers/shader/app/components/Pipeline/CurlNoise.client.vue +3 -7
  97. package/layers/shader/app/components/Pipeline/DarkenBlend.client.vue +2 -19
  98. package/layers/shader/app/components/Pipeline/DayNightCycle.client.vue +5 -8
  99. package/layers/shader/app/components/Pipeline/DiagonalGradient.client.vue +5 -8
  100. package/layers/shader/app/components/Pipeline/DiamondGradient.client.vue +5 -8
  101. package/layers/shader/app/components/Pipeline/DifferenceBlend.client.vue +2 -19
  102. package/layers/shader/app/components/Pipeline/DomainWarpedNoise.client.vue +4 -8
  103. package/layers/shader/app/components/Pipeline/Dots.client.vue +4 -8
  104. package/layers/shader/app/components/Pipeline/DuoTone.client.vue +5 -9
  105. package/layers/shader/app/components/Pipeline/ExclusionBlend.client.vue +3 -23
  106. package/layers/shader/app/components/Pipeline/ExponentialFog.client.vue +4 -7
  107. package/layers/shader/app/components/Pipeline/FilmBurn.client.vue +4 -7
  108. package/layers/shader/app/components/Pipeline/Flame.client.vue +4 -8
  109. package/layers/shader/app/components/Pipeline/FocalGradient.client.vue +5 -8
  110. package/layers/shader/app/components/Pipeline/GodRays.client.vue +4 -7
  111. package/layers/shader/app/components/Pipeline/GradientNoise.client.vue +4 -8
  112. package/layers/shader/app/components/Pipeline/Grid.client.vue +4 -8
  113. package/layers/shader/app/components/Pipeline/Halation.client.vue +3 -7
  114. package/layers/shader/app/components/Pipeline/HardLightBlend.client.vue +2 -19
  115. package/layers/shader/app/components/Pipeline/Haze.client.vue +4 -7
  116. package/layers/shader/app/components/Pipeline/Hexagon.client.vue +4 -8
  117. package/layers/shader/app/components/Pipeline/LensFlare.client.vue +4 -7
  118. package/layers/shader/app/components/Pipeline/LightenBlend.client.vue +2 -19
  119. package/layers/shader/app/components/Pipeline/LinearGradient4.client.vue +2 -2
  120. package/layers/shader/app/components/Pipeline/Marble.client.vue +4 -8
  121. package/layers/shader/app/components/Pipeline/MonochromeTint.client.vue +3 -7
  122. package/layers/shader/app/components/Pipeline/MultiplyBlend.client.vue +2 -19
  123. package/layers/shader/app/components/Pipeline/NoisyGradient.client.vue +4 -8
  124. package/layers/shader/app/components/Pipeline/NoisyGradientBlend.client.vue +4 -8
  125. package/layers/shader/app/components/Pipeline/OverlayBlend.client.vue +2 -19
  126. package/layers/shader/app/components/Pipeline/Polygon.client.vue +4 -8
  127. package/layers/shader/app/components/Pipeline/RaymarchTunnel.client.vue +4 -7
  128. package/layers/shader/app/components/Pipeline/Rectangle.client.vue +4 -8
  129. package/layers/shader/app/components/Pipeline/RidgedNoise.client.vue +4 -8
  130. package/layers/shader/app/components/Pipeline/Ring.client.vue +4 -8
  131. package/layers/shader/app/components/Pipeline/ScreenBlend.client.vue +2 -19
  132. package/layers/shader/app/components/Pipeline/SkyAtmosphere.client.vue +6 -9
  133. package/layers/shader/app/components/Pipeline/SoftLightBlend.client.vue +2 -19
  134. package/layers/shader/app/components/Pipeline/SplitTone.client.vue +4 -8
  135. package/layers/shader/app/components/Pipeline/Star.client.vue +4 -8
  136. package/layers/shader/app/components/Pipeline/Stripes.client.vue +4 -8
  137. package/layers/shader/app/components/Pipeline/Tint.client.vue +4 -7
  138. package/layers/shader/app/components/Pipeline/Triangle.client.vue +4 -8
  139. package/layers/shader/app/components/Pipeline/ValueNoise.client.vue +4 -8
  140. package/layers/shader/app/components/Pipeline/VoronoiEdges.client.vue +4 -8
  141. package/layers/shader/app/components/Pipeline/Water.client.vue +5 -8
  142. package/layers/shader/app/components/Pipeline/WaveBendLayer.client.vue +4 -7
  143. package/layers/shader/app/components/Pipeline/WaveColourLayer.client.vue +3 -7
  144. package/layers/shader/app/components/Pipeline/Wood.client.vue +4 -8
  145. package/layers/shader/app/components/Preset/Aurora.client.vue +15 -21
  146. package/layers/shader/app/components/Preset/Flow.client.vue +2 -1
  147. package/layers/shader/app/components/Preset/GradientMesh.client.vue +2 -1
  148. package/layers/shader/app/components/Preset/Nebula.client.vue +2 -1
  149. package/layers/shader/app/components/Preset/Ocean.client.vue +2 -1
  150. package/layers/shader/app/components/Preset/ThemeAurora.client.vue +30 -90
  151. package/layers/shader/app/components/Preset/ThemeBubble.client.vue +30 -91
  152. package/layers/shader/app/components/Preset/ThemeFlow.client.vue +30 -90
  153. package/layers/shader/app/components/Preset/ThemeGradient.client.vue +30 -91
  154. package/layers/shader/app/components/Preset/ThemeLavaLamp.client.vue +30 -90
  155. package/layers/shader/app/components/Preset/ThemePlasma.client.vue +30 -90
  156. package/layers/shader/app/components/Preset/ThemeWave.client.vue +30 -90
  157. package/layers/shader/app/components/Shader/Background.client.vue +4 -4
  158. package/layers/shader/app/components/Shader/Host.client.vue +31 -33
  159. package/layers/shader/app/components/Shader/Runtime.client.vue +15 -23
  160. package/layers/shader/app/composables/useAmbientMaterials.ts +53 -51
  161. package/layers/shader/app/composables/useShaderMixBlend.ts +26 -0
  162. package/layers/shader/app/composables/useThemePreset.ts +75 -0
  163. package/layers/shader/app/shaders/common/noise.ts +2 -7
  164. package/layers/shader/app/shaders/types.ts +6 -6
  165. package/layers/shader/app/types/tsl.ts +7 -25
  166. package/layers/shader/app/types/uniforms.ts +2 -1
  167. package/layers/shader/app/utils/tsl/color.ts +7 -1
  168. package/layers/shader/package.json +2 -1
  169. package/layers/theme/app/components/ThemePicker/Colors.vue +1 -3
  170. package/layers/theme/app/types/app-config.d.ts +4 -2
  171. package/layers/theme/app/types/index.ts +1 -0
  172. package/layers/theme/app/types/theme.ts +3 -18
  173. package/layers/theme/package.json +2 -1
  174. package/layers/theme/server/plugins/theme-fouc.ts +1 -1
  175. package/layers/transitions/package.json +4 -1
  176. package/layers/typography/app/components/Typography/CodeBlock.vue +2 -2
  177. package/layers/typography/app/components/Typography/Headline.vue +2 -2
  178. package/layers/typography/app/components/Typography/HeadlineScreen.vue +1 -1
  179. package/layers/typography/app/components/Typography/QuoteBlock.vue +4 -1
  180. package/layers/typography/app/components/Typography/TextStroke.vue +2 -0
  181. package/layers/typography/app/components/Typography/index.vue +36 -27
  182. package/layers/typography/app/composables/typography.ts +27 -21
  183. package/layers/typography/app/types/colors.ts +9 -29
  184. package/layers/typography/app/types/index.ts +2 -0
  185. package/layers/typography/package.json +4 -1
  186. package/layers/ui/package.json +2 -1
  187. package/layers/visual/app/app.config.ts +5 -2
  188. package/layers/visual/app/components/Accent/Blob.vue +20 -20
  189. package/layers/visual/app/components/Accent/Scene.vue +2 -2
  190. package/layers/visual/app/components/Base/Modal.vue +2 -2
  191. package/layers/visual/app/components/Gradient/Background.vue +2 -2
  192. package/layers/visual/app/components/Gradient/Text.vue +2 -2
  193. package/layers/visual/app/components/Media/Picture.vue +3 -1
  194. package/layers/visual/app/components/Progress/Bar.vue +6 -6
  195. package/layers/visual/app/components/Tint/Overlay.vue +14 -14
  196. package/layers/visual/app/composables/accent.ts +10 -8
  197. package/layers/visual/app/composables/tint.ts +7 -7
  198. package/layers/visual/app/types/index.ts +6 -0
  199. package/layers/visual/app/types/media.ts +4 -2
  200. package/layers/visual/app/types/tint.ts +2 -1
  201. package/layers/visual/package.json +4 -1
  202. package/package.json +6 -2
@@ -0,0 +1,234 @@
1
+ # Type System Architecture — `kmcom-nuxt-layers`
2
+
3
+ ## Guiding Principle
4
+
5
+ Types have two distinct jobs in this monorepo:
6
+
7
+ - **Internal types** — owned by a single layer, not exported, can change freely
8
+ - **Cross-layer contracts** — shared between two or more layers, or exposed to consuming apps; changes here are breaking changes
9
+
10
+ The rule: **if only one layer needs it, it lives in that layer. If two or more layers need it, it lives in root `types/`.**
11
+
12
+ ---
13
+
14
+ ## Directory Structure
15
+
16
+ ```
17
+ kmcom-nuxt-layers/
18
+
19
+ ├── types/ # Cross-layer contracts & public API
20
+ │ ├── theme.ts # Token shapes, mode/palette/contrast enums
21
+ │ ├── motion.ts # Shared motion contracts (e.g. scroll lock events)
22
+ │ ├── events.ts # Event bus payload types (cross-layer)
23
+ │ ├── runtime.ts # runtimeConfig shape types
24
+ │ └── index.ts # Public barrel — consuming apps import from here
25
+
26
+ ├── layers/
27
+ │ ├── core/
28
+ │ │ └── types/
29
+ │ │ ├── device.ts # Browser/device detection internals
30
+ │ │ ├── network.ts # Network status types
31
+ │ │ └── index.ts
32
+ │ │
33
+ │ ├── ui/
34
+ │ │ └── types/
35
+ │ │ ├── components.ts # Component prop shapes
36
+ │ │ ├── typography.ts # Type scale, font role types
37
+ │ │ └── index.ts
38
+ │ │
39
+ │ ├── layout/
40
+ │ │ └── types/
41
+ │ │ ├── grid.ts # 18-col grid config types
42
+ │ │ ├── sections.ts # Section/page component prop shapes
43
+ │ │ └── index.ts
44
+ │ │
45
+ │ ├── motion/
46
+ │ │ └── types/
47
+ │ │ ├── transitions.ts # Transition component prop shapes
48
+ │ │ ├── scroll.ts # Scroll composable internals
49
+ │ │ └── index.ts
50
+ │ │
51
+ │ ├── shader/
52
+ │ │ └── types/
53
+ │ │ ├── blocks.ts # Block category interfaces (Primitives, Generators, etc.)
54
+ │ │ ├── pipeline.ts # ShaderPipeline / useShaderStage internals
55
+ │ │ ├── colour.ts # Colour utility types (oklch, hsla, hex, rgb)
56
+ │ │ └── index.ts
57
+ │ │
58
+ │ └── theme/
59
+ │ └── types/
60
+ │ ├── modes.ts # dark/light/system mode internals
61
+ │ ├── colour.ts # Accent/palette resolution internals
62
+ │ └── index.ts
63
+
64
+ └── package.json
65
+ ```
66
+
67
+ ---
68
+
69
+ ## Root `types/` — Cross-Layer Contracts
70
+
71
+ These are the types that define how layers talk to each other. Treat them as a public API — changes here may require updates across multiple layers and in consuming apps.
72
+
73
+ ### `theme.ts`
74
+
75
+ Consumed by: `ui`, `layout`, `motion`, `shader`, `theme`
76
+
77
+ ```ts
78
+ export type ColourMode = 'light' | 'dark' | 'system'
79
+ export type ContrastLevel = 'standard' | 'high'
80
+ export type MotionPreference = 'full' | 'reduced' | 'none'
81
+ export type TransparencyPreference = 'full' | 'reduced' | 'none'
82
+
83
+ export interface ThemeState {
84
+ mode: ColourMode
85
+ palette: string // e.g. 'default' | 'ocean' | custom slug
86
+ contrast: ContrastLevel
87
+ motion: MotionPreference
88
+ transparency: TransparencyPreference
89
+ }
90
+
91
+ export interface ThemeTokens {
92
+ // Add resolved CSS custom property shapes here as the system matures
93
+ [key: string]: string
94
+ }
95
+ ```
96
+
97
+ ### `events.ts`
98
+
99
+ Consumed by: any layer using the event bus (e.g. `motion` scroll lock, `core` loading states)
100
+
101
+ ```ts
102
+ export interface ScrollLockEvent {
103
+ locked: boolean
104
+ source: string // which layer/component emitted it
105
+ }
106
+
107
+ export interface LoadingStateEvent {
108
+ loading: boolean
109
+ id?: string
110
+ }
111
+
112
+ // Extend as new cross-layer events are introduced
113
+ export type LayerEvent =
114
+ | { type: 'scroll:lock'; payload: ScrollLockEvent }
115
+ | { type: 'loading:state'; payload: LoadingStateEvent }
116
+ ```
117
+
118
+ ### `motion.ts`
119
+
120
+ Consumed by: `motion`, `layout` (section entry animations), `shader` (transition hooks)
121
+
122
+ ```ts
123
+ export interface MotionConfig {
124
+ duration: number
125
+ ease: string
126
+ delay?: number
127
+ }
128
+
129
+ export interface TransitionConfig extends MotionConfig {
130
+ enterFrom?: Record<string, string | number>
131
+ enterTo?: Record<string, string | number>
132
+ leaveFrom?: Record<string, string | number>
133
+ leaveTo?: Record<string, string | number>
134
+ }
135
+ ```
136
+
137
+ ### `runtime.ts`
138
+
139
+ Consumed by: `core`, any layer that reads `useRuntimeConfig()`
140
+
141
+ ```ts
142
+ export interface PublicRuntimeConfig {
143
+ apiBase: string
144
+ // Extend per project — this is the shared baseline
145
+ }
146
+ ```
147
+
148
+ ### `index.ts` — Public Barrel
149
+
150
+ ```ts
151
+ // What consuming apps are allowed to import
152
+ export type {
153
+ ColourMode,
154
+ ContrastLevel,
155
+ MotionPreference,
156
+ TransparencyPreference,
157
+ ThemeState,
158
+ } from './theme'
159
+ export type { ScrollLockEvent, LoadingStateEvent, LayerEvent } from './events'
160
+ export type { MotionConfig, TransitionConfig } from './motion'
161
+ export type { PublicRuntimeConfig } from './runtime'
162
+ ```
163
+
164
+ ---
165
+
166
+ ## Per-Layer `types/` — Internal Types
167
+
168
+ Internal types are **not re-exported from root `types/index.ts`**. They are only accessible within their own layer. There is no rule against a layer importing from root `types/` — that's expected — but root `types/` should never import from a layer.
169
+
170
+ ### Dependency direction
171
+
172
+ ```
173
+ consuming app
174
+
175
+ root types/ ← cross-layer contracts
176
+
177
+ layer/types/ ← internal, layer-owned
178
+ ```
179
+
180
+ **Never:** `root types/` ← `layer/types/`
181
+ **Never:** `layer-a/types/` ← `layer-b/types/`
182
+
183
+ If two layers both need a type that currently lives in one of them — move it to root `types/`.
184
+
185
+ ---
186
+
187
+ ## Recommended Type Packages
188
+
189
+ ### Add now
190
+
191
+ | Package | Rationale |
192
+ | -------------- | ------------------------------------------------------------------------------------------------------------------------ |
193
+ | `type-fest` | Utility types: `PartialDeep`, `RequireAtLeastOne`, `Simplify`, `SetOptional`. Eliminates most hand-rolled utility types. |
194
+ | `@types/three` | Required for shader layer — Three.js/TSL types for `ShaderNodeObject`, `MeshStandardNodeMaterial`, etc. |
195
+ | `csstype` | Typed CSS properties — useful in the design system and any style object work in UI/Layout layers. |
196
+
197
+ ### Consider later
198
+
199
+ | Package | Rationale |
200
+ | ------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------- |
201
+ | `zod` | Runtime validation for `runtimeConfig` shapes and any API responses in a Data layer. Pairs with `z.infer<>` to derive TypeScript types from schemas. |
202
+ | `ts-pattern` | Exhaustive pattern matching — useful in event bus handlers and shader block routing logic. |
203
+
204
+ ### Skip
205
+
206
+ | Package | Why |
207
+ | -------------------- | --------------------------------------------------------------- |
208
+ | `io-ts` / `runtypes` | Same space as Zod, less ecosystem momentum, more complex API. |
209
+ | `@types/gsap` | GSAP ships its own types — no separate `@types` package needed. |
210
+
211
+ ---
212
+
213
+ ## Migration Checklist
214
+
215
+ When moving existing types into this structure:
216
+
217
+ - [ ] Audit all `.ts` files and `.vue` `<script>` blocks for locally defined types
218
+ - [ ] Classify each type: internal (one layer) or cross-layer (two or more)
219
+ - [ ] Move cross-layer types to root `types/` and update all imports
220
+ - [ ] Move internal types to `layer/types/index.ts` and update local imports
221
+ - [ ] Add `type-fest`, `@types/three`, `csstype` to `package.json`
222
+ - [ ] Ensure root `types/index.ts` barrel only exports what consuming apps should see
223
+ - [ ] Verify no layer `types/` files are importing from another layer `types/` — any such coupling should be resolved via root `types/`
224
+ - [ ] Add a TSDoc comment to each type in root `types/` explaining which layers consume it
225
+
226
+ ---
227
+
228
+ ## Conventions
229
+
230
+ - **Type-only imports:** always use `import type { ... }` for type-only imports to keep the bundle clean
231
+ - **No circular deps:** root `types/` has zero imports from layers; layers may import from root `types/`
232
+ - **TSDoc all root types:** internal types can be lightly documented; root types should always have a JSDoc/TSDoc comment
233
+ - **Barrel per layer:** every `layer/types/` has an `index.ts` — no deep imports into layer type files from outside that layer
234
+ - **Naming:** prefer `interface` for object shapes (extensible), `type` for unions/aliases
@@ -21,8 +21,7 @@
21
21
  as?: string
22
22
  }>()
23
23
 
24
- // const el = ref<HTMLElement | null>(null)
25
- const el = useTemplateRef<HTMLElement | null>(null)
24
+ const el = useTemplateRef<HTMLElement>('el')
26
25
  const { displayValue, isComplete } = useCountUp(el, {
27
26
  to,
28
27
  from,
@@ -11,8 +11,7 @@
11
11
  stiffness?: number
12
12
  }>()
13
13
 
14
- // const el = ref<HTMLElement | null>(null)
15
- const el = useTemplateRef<HTMLElement | null>(null)
14
+ const el = useTemplateRef<HTMLElement>('el')
16
15
  const { isActive } = useMagneticElement(el, { strength, radius, damping, stiffness })
17
16
  </script>
18
17
 
@@ -52,11 +52,8 @@
52
52
  const { gsap } = useGsap()
53
53
  const { velocity: scrollVelocity, direction: scrollDirection } = useSmoothScroll()
54
54
 
55
- // const containerRef = ref<HTMLElement | null>(null)
56
- const containerRef = useTemplateRef<HTMLElement | null>(null)
57
-
58
- // const contentRef = ref<HTMLElement | null>(null)
59
- const contentRef = useTemplateRef<HTMLElement | null>(null)
55
+ const containerRef = useTemplateRef<HTMLElement>('containerRef')
56
+ const contentRef = useTemplateRef<HTMLElement>('contentRef')
60
57
 
61
58
  const tweenRef = ref<gsap.core.Tween | null>(null)
62
59
 
@@ -35,8 +35,7 @@
35
35
  const { gsap, ScrollTrigger } = useGsap()
36
36
  const { velocityFactor } = useMarqueeVelocity({ damping, stiffness, velocityMapping })
37
37
 
38
- // const containerRef = ref<HTMLElement[]>([])
39
- const containerRef = useTemplateRef<HTMLElement[]>([])
38
+ const containerRef = useTemplateRef<HTMLElement[]>('containerRef')
40
39
 
41
40
  const copyRefs = ref<HTMLSpanElement[]>([])
42
41
 
@@ -11,8 +11,7 @@
11
11
  stiffness?: number
12
12
  }>()
13
13
 
14
- // const el = ref<HTMLElement | null>(null)
15
- const el = useTemplateRef<HTMLElement | null>(null)
14
+ const el = useTemplateRef<HTMLElement>('el')
16
15
  useTiltEffect(el, { maxTilt, perspective, damping, stiffness })
17
16
  </script>
18
17
 
@@ -10,7 +10,10 @@ type UseCountUpOptions = {
10
10
  once?: boolean
11
11
  }
12
12
 
13
- export function useCountUp(elementRef: MaybeRefOrGetter<HTMLElement | null>, opts: UseCountUpOptions) {
13
+ export function useCountUp(
14
+ elementRef: MaybeRefOrGetter<HTMLElement | null>,
15
+ opts: UseCountUpOptions
16
+ ) {
14
17
  const { gsap, ScrollTrigger } = useGsap()
15
18
 
16
19
  const displayValue = ref(String(opts.from ?? 0))
@@ -27,12 +27,10 @@ export function useMagneticElement(
27
27
  let targetX = 0
28
28
  let targetY = 0
29
29
 
30
+ isActive.value = dist < radius
30
31
  if (dist < radius) {
31
- isActive.value = true
32
32
  targetX = dx * strength
33
33
  targetY = dy * strength
34
- } else {
35
- isActive.value = false
36
34
  }
37
35
 
38
36
  currentX.value += (targetX - currentX.value) * stiffness
@@ -1,7 +1,7 @@
1
- import type { MaybeRef } from 'vue'
1
+ import type { MaybeRef, ShallowRef } from 'vue'
2
2
 
3
3
  export function useMarqueeCopies(
4
- containerRefs: Ref<HTMLElement[]>,
4
+ containerRefs: Readonly<ShallowRef<HTMLElement[] | null>>,
5
5
  copyRefs: Ref<HTMLSpanElement[]>,
6
6
  rowCount: MaybeRef<number>
7
7
  ) {
@@ -14,7 +14,7 @@ export function useMarqueeCopies(
14
14
  const n = unref(rowCount)
15
15
  for (let i = 0; i < n; i++) {
16
16
  const copy = copyRefs.value[i]
17
- const container = containerRefs.value[i]
17
+ const container = containerRefs.value?.[i]
18
18
  if (!copy || !container) continue
19
19
  const singleWidth = copy.offsetWidth
20
20
  if (singleWidth === 0) continue
@@ -0,0 +1,8 @@
1
+ export type UseCountUpOptions = {
2
+ to: number
3
+ from?: number
4
+ duration?: number
5
+ ease?: string
6
+ format?: (n: number) => string
7
+ once?: boolean
8
+ }
@@ -0,0 +1 @@
1
+ export type * from './animations'
@@ -2,5 +2,8 @@
2
2
  "name": "kmcom-layer-animations",
3
3
  "version": "0.0.1",
4
4
  "type": "module",
5
- "main": "./nuxt.config.ts"
5
+ "main": "./nuxt.config.ts",
6
+ "scripts": {
7
+ "lint": "eslint ."
8
+ }
6
9
  }
@@ -1,5 +1,5 @@
1
1
  <script setup lang="ts">
2
- import { TresCanvas } from '@tresjs/core'
2
+ import { TresCanvas, type TresContext, type TresRendererSetupContext } from '@tresjs/core'
3
3
  import {
4
4
  ACESFilmicToneMapping,
5
5
  CineonToneMapping,
@@ -37,7 +37,7 @@
37
37
  }>()
38
38
 
39
39
  const emit = defineEmits<{
40
- ready: [context: any]
40
+ ready: [context: TresContext]
41
41
  }>()
42
42
 
43
43
  const config = useAppConfig()
@@ -69,7 +69,7 @@
69
69
 
70
70
  // WebGPU renderer factory — TresJS v5 calls renderer.init() automatically
71
71
  // when the returned object has isRenderer === true (three/webgpu Renderer base class)
72
- function webgpuRendererFactory({ canvas }: { canvas: any }) {
72
+ function webgpuRendererFactory({ canvas }: TresRendererSetupContext) {
73
73
  const r = new WebGPURenderer({
74
74
  canvas: unref(canvas),
75
75
  antialias,
@@ -85,7 +85,7 @@
85
85
 
86
86
  const rendererBinding = computed(() => (webgpu ? { renderer: webgpuRendererFactory } : {}))
87
87
 
88
- function onReady(context: any) {
88
+ function onReady(context: TresContext) {
89
89
  emit('ready', context)
90
90
  }
91
91
  </script>
@@ -1,3 +1,5 @@
1
+ import type { WebGPURenderer } from 'three/webgpu'
2
+ import type { WebGLRenderer } from 'three'
1
3
  import {
2
4
  QUALITY_PRESETS,
3
5
  type QualityLevel,
@@ -12,7 +14,7 @@ export function useRendererCapabilities() {
12
14
  const capabilities = ref<RendererCapabilities | null>(null)
13
15
  const isReady = ref(false)
14
16
 
15
- function detectFromRenderer(renderer: any) {
17
+ function detectFromRenderer(renderer: WebGPURenderer | WebGLRenderer) {
16
18
  const isWebGPU = renderer.constructor?.name === 'WebGPURenderer'
17
19
  const glCaps = renderer.capabilities
18
20
 
@@ -29,19 +31,21 @@ export function useRendererCapabilities() {
29
31
  devicePixelRatio: renderer.getPixelRatio?.() ?? 1,
30
32
  isWebGPU: true,
31
33
  }
32
- } else {
33
- capabilities.value = {
34
- backend: 'webgl',
35
- maxTextureSize: glCaps.maxTextureSize,
36
- maxTextures: glCaps.maxTextures,
37
- maxVertexUniforms: glCaps.maxVertexUniforms,
38
- maxFragmentUniforms: glCaps.maxFragmentUniforms,
39
- floatTextures: glCaps.isWebGL2 || false,
40
- anisotropy: glCaps.getMaxAnisotropy(),
41
- precision: glCaps.precision as 'lowp' | 'mediump' | 'highp',
42
- devicePixelRatio: renderer.getPixelRatio(),
43
- isWebGPU: false,
44
- }
34
+ isReady.value = true
35
+ return
36
+ }
37
+
38
+ capabilities.value = {
39
+ backend: 'webgl',
40
+ maxTextureSize: glCaps.maxTextureSize,
41
+ maxTextures: glCaps.maxTextures,
42
+ maxVertexUniforms: glCaps.maxVertexUniforms,
43
+ maxFragmentUniforms: glCaps.maxFragmentUniforms,
44
+ floatTextures: glCaps.isWebGL2 || false,
45
+ anisotropy: glCaps.getMaxAnisotropy(),
46
+ precision: glCaps.precision as 'lowp' | 'mediump' | 'highp',
47
+ devicePixelRatio: renderer.getPixelRatio(),
48
+ isWebGPU: false,
45
49
  }
46
50
 
47
51
  isReady.value = true
@@ -70,7 +74,7 @@ export async function checkWebGPUSupport(): Promise<boolean> {
70
74
  }
71
75
 
72
76
  try {
73
- const adapter = await (navigator as any).gpu.requestAdapter()
77
+ const adapter = await navigator.gpu.requestAdapter()
74
78
  return adapter !== null
75
79
  } catch {
76
80
  return false
@@ -0,0 +1 @@
1
+ export * from './renderer'
@@ -6,7 +6,8 @@
6
6
  "scripts": {
7
7
  "dev": "nuxi dev",
8
8
  "dev:playground": "PLAYGROUND_LAYERS=core,canvas pnpm -F playground dev",
9
- "typecheck": "vue-tsc --noEmit -p ../../tsconfig.typecheck.json"
9
+ "typecheck": "vue-tsc --noEmit -p ../../tsconfig.typecheck.json",
10
+ "lint": "eslint ."
10
11
  },
11
12
  "dependencies": {
12
13
  "@tresjs/cientos": "catalog:",
@@ -1,7 +1,8 @@
1
1
  {
2
2
  "extends": "../../apps/playground/tsconfig.json",
3
3
  "compilerOptions": {
4
- "strict": true
4
+ "strict": true,
5
+ "types": ["@webgpu/types"]
5
6
  },
6
7
  "exclude": ["node_modules"]
7
8
  }
@@ -1,12 +1,12 @@
1
1
  <script setup lang="ts">
2
2
  const {
3
3
  title,
4
- description,
5
- date,
6
- image,
7
- badge,
4
+ description = undefined,
5
+ date = undefined,
6
+ image = undefined,
7
+ badge = undefined,
8
8
  authors = [],
9
- to,
9
+ to = undefined,
10
10
  } = defineProps<{
11
11
  title: string
12
12
  description?: string
@@ -2,9 +2,9 @@
2
2
  const {
3
3
  src,
4
4
  alt = '',
5
- width,
6
- height,
7
- caption,
5
+ width = undefined,
6
+ height = undefined,
7
+ caption = undefined,
8
8
  } = defineProps<{
9
9
  src: string
10
10
  alt?: string
@@ -1,11 +1,11 @@
1
1
  <script setup lang="ts">
2
2
  const {
3
3
  title,
4
- description,
5
- coverImage,
4
+ description = undefined,
5
+ coverImage = undefined,
6
6
  imageCount = 0,
7
7
  tags = [],
8
- to,
8
+ to = undefined,
9
9
  } = defineProps<{
10
10
  title: string
11
11
  description?: string
@@ -1,5 +1,6 @@
1
1
  <script setup lang="ts">
2
2
  import type { PageCollections } from '@nuxt/content'
3
+ import type { ContentSurroundLink } from '@nuxt/ui'
3
4
 
4
5
  const {
5
6
  collection,
@@ -16,6 +17,9 @@
16
17
  const { data: item, status } = await useCollectionItem(collection, slug)
17
18
  const { data: surround } = await useCollectionSurround(collection, slug)
18
19
 
20
+ const surroundLinks = computed(
21
+ () => (surround.value ?? undefined) as ContentSurroundLink[] | undefined
22
+ )
19
23
  const itemImage = computed(() => (item.value as { image?: string } | null)?.image)
20
24
 
21
25
  useSeoMeta({
@@ -47,7 +51,7 @@
47
51
  <slot name="after-content" :item />
48
52
 
49
53
  <USeparator class="my-8" />
50
- <NuxtContentSurround :surround="surround as any" />
54
+ <NuxtContentSurround :surround="surroundLinks" />
51
55
  </UPageBody>
52
56
 
53
57
  <template v-if="!hideToc" #right>
@@ -1,13 +1,15 @@
1
1
  <script setup lang="ts">
2
- const { surround } = defineProps<{
3
- surround?: unknown[]
2
+ import type { ContentSurroundLink } from '@nuxt/ui'
3
+
4
+ const { surround = undefined } = defineProps<{
5
+ surround?: ContentSurroundLink[]
4
6
  }>()
5
7
  </script>
6
8
 
7
9
  <template>
8
10
  <UContentSurround
9
11
  v-if="surround"
10
- :surround="surround as any"
12
+ :surround
11
13
  prev-icon="i-lucide-arrow-left"
12
14
  next-icon="i-lucide-arrow-right"
13
15
  />
@@ -1,7 +1,7 @@
1
1
  <script setup lang="ts">
2
2
  import type { TocLink } from '@nuxt/content'
3
3
 
4
- const { links, title = 'Table of Contents' } = defineProps<{
4
+ const { links = undefined, title = 'Table of Contents' } = defineProps<{
5
5
  links?: TocLink[]
6
6
  title?: string
7
7
  }>()
@@ -1,12 +1,12 @@
1
1
  <script setup lang="ts">
2
2
  const {
3
3
  title,
4
- description,
5
- image,
4
+ description = undefined,
5
+ image = undefined,
6
6
  tags = [],
7
- client,
8
- year,
9
- to,
7
+ client = undefined,
8
+ year = undefined,
9
+ to = undefined,
10
10
  } = defineProps<{
11
11
  title: string
12
12
  description?: string
@@ -2,9 +2,9 @@
2
2
  const {
3
3
  src,
4
4
  alt = '',
5
- caption,
6
- width,
7
- height,
5
+ caption = undefined,
6
+ width = undefined,
7
+ height = undefined,
8
8
  } = defineProps<{
9
9
  src: string
10
10
  alt?: string
@@ -0,0 +1 @@
1
+ export type * from './content'
@@ -10,7 +10,8 @@
10
10
  "dev:prepare": "nuxt prepare .playground",
11
11
  "build": "CONTENT_STANDALONE=true nuxi build",
12
12
  "generate": "CONTENT_STANDALONE=true nuxi generate",
13
- "preview": "nuxt preview .playground"
13
+ "preview": "nuxt preview .playground",
14
+ "lint": "eslint ."
14
15
  },
15
16
  "devDependencies": {
16
17
  "@nuxt/content": "catalog:"