@struq/skill 0.0.0-stage → 0.2.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 (96) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +133 -2
  3. package/bin/struq.mjs +132 -0
  4. package/package.json +41 -4
  5. package/skills/struq/SKILL.md +237 -0
  6. package/skills/struq/cinematic/README.md +409 -0
  7. package/skills/struq/cinematic/checklists/01-preproduction.md +15 -0
  8. package/skills/struq/cinematic/checklists/02-implementation.md +17 -0
  9. package/skills/struq/cinematic/checklists/03-polish.md +17 -0
  10. package/skills/struq/cinematic/examples/code/nextjs/README.md +13 -0
  11. package/skills/struq/cinematic/examples/code/nextjs/app/cinematic-experience.tsx +13 -0
  12. package/skills/struq/cinematic/examples/code/nextjs/app/components/LenisRoot.tsx +42 -0
  13. package/skills/struq/cinematic/examples/code/nextjs/app/page.tsx +6 -0
  14. package/skills/struq/cinematic/examples/code/shared/CameraRig.tsx +65 -0
  15. package/skills/struq/cinematic/examples/code/shared/ExperienceCanvas.tsx +20 -0
  16. package/skills/struq/cinematic/examples/code/shared/ExperienceDirector.tsx +57 -0
  17. package/skills/struq/cinematic/examples/code/shared/ExperienceOverlay.tsx +37 -0
  18. package/skills/struq/cinematic/examples/code/shared/ExperiencePage.tsx +52 -0
  19. package/skills/struq/cinematic/examples/code/shared/GsapFrameLoop.tsx +32 -0
  20. package/skills/struq/cinematic/examples/code/shared/InteriorRoot.tsx +30 -0
  21. package/skills/struq/cinematic/examples/code/shared/README.md +20 -0
  22. package/skills/struq/cinematic/examples/code/shared/SubjectRig.tsx +58 -0
  23. package/skills/struq/cinematic/examples/code/shared/build-experience-timeline.ts +237 -0
  24. package/skills/struq/cinematic/examples/code/shared/direction.ts +52 -0
  25. package/skills/struq/cinematic/examples/code/shared/gsap-client.ts +32 -0
  26. package/skills/struq/cinematic/examples/code/shared/math.ts +12 -0
  27. package/skills/struq/cinematic/examples/code/shared/registry.ts +58 -0
  28. package/skills/struq/cinematic/examples/code/shared/runtime.ts +52 -0
  29. package/skills/struq/cinematic/examples/code/shared/styles.css +127 -0
  30. package/skills/struq/cinematic/examples/code/shared/useExperienceInput.ts +42 -0
  31. package/skills/struq/cinematic/examples/code/vite/README.md +14 -0
  32. package/skills/struq/cinematic/examples/code/vite/src/App.tsx +11 -0
  33. package/skills/struq/cinematic/examples/code/vite/src/LenisRoot.tsx +37 -0
  34. package/skills/struq/cinematic/examples/code/vite/src/main.tsx +9 -0
  35. package/skills/struq/cinematic/examples/concise/01-chapter-spec-example.md +42 -0
  36. package/skills/struq/cinematic/examples/concise/02-handoff-example.md +25 -0
  37. package/skills/struq/cinematic/examples/concise/03-audit-finding-example.md +13 -0
  38. package/skills/struq/cinematic/examples/verbose/01-full-experience-direction.md +687 -0
  39. package/skills/struq/cinematic/examples/verbose/02-full-audit-example.md +362 -0
  40. package/skills/struq/cinematic/references/01-core-mental-model.md +221 -0
  41. package/skills/struq/cinematic/references/02-vocabulary.md +384 -0
  42. package/skills/struq/cinematic/references/03-experience-architecture.md +302 -0
  43. package/skills/struq/cinematic/references/04-timeline-choreography.md +264 -0
  44. package/skills/struq/cinematic/references/05-handoff-contracts.md +241 -0
  45. package/skills/struq/cinematic/references/06-three-rig-architecture.md +286 -0
  46. package/skills/struq/cinematic/references/07-stack-integration.md +228 -0
  47. package/skills/struq/cinematic/references/08-gsap-plugin-patterns.md +218 -0
  48. package/skills/struq/cinematic/references/09-tuning-harness.md +202 -0
  49. package/skills/struq/cinematic/references/10-quality-systems.md +206 -0
  50. package/skills/struq/cinematic/references/11-agent-workflows.md +246 -0
  51. package/skills/struq/cinematic/references/12-audit-rubric.md +176 -0
  52. package/skills/struq/cinematic/references/13-official-docs.md +53 -0
  53. package/skills/struq/cinematic/templates/01-experience-brief.md +105 -0
  54. package/skills/struq/cinematic/templates/02-experience-contract.md +80 -0
  55. package/skills/struq/cinematic/templates/03-chapter-spec.md +103 -0
  56. package/skills/struq/cinematic/templates/04-handoff-contract.md +102 -0
  57. package/skills/struq/cinematic/templates/05-ownership-matrix.md +29 -0
  58. package/skills/struq/cinematic/templates/06-shot-presets.md +59 -0
  59. package/skills/struq/cinematic/templates/07-implementation-slice.md +66 -0
  60. package/skills/struq/cinematic/templates/08-tuning-register.md +36 -0
  61. package/skills/struq/cinematic/templates/09-acceptance-tests.md +57 -0
  62. package/skills/struq/references/anti-patterns.md +265 -0
  63. package/skills/struq/references/baseline-prompt.md +118 -0
  64. package/skills/struq/references/brand.md +143 -0
  65. package/skills/struq/references/brief-router.md +219 -0
  66. package/skills/struq/references/composition.md +191 -0
  67. package/skills/struq/references/depth-parallax.md +235 -0
  68. package/skills/struq/references/direction.md +188 -0
  69. package/skills/struq/references/feel-layer.md +107 -0
  70. package/skills/struq/references/gsap-api.md +293 -0
  71. package/skills/struq/references/iconography.md +255 -0
  72. package/skills/struq/references/imagery.md +144 -0
  73. package/skills/struq/references/loaders.md +287 -0
  74. package/skills/struq/references/micro-interactions.md +270 -0
  75. package/skills/struq/references/mobile-composition.md +70 -0
  76. package/skills/struq/references/nav-header.md +296 -0
  77. package/skills/struq/references/page-architecture.md +134 -0
  78. package/skills/struq/references/page-entrances.md +198 -0
  79. package/skills/struq/references/performance.md +235 -0
  80. package/skills/struq/references/pinning-scrub.md +341 -0
  81. package/skills/struq/references/pitfalls.md +290 -0
  82. package/skills/struq/references/route-transitions.md +281 -0
  83. package/skills/struq/references/scaling.md +151 -0
  84. package/skills/struq/references/scroll-reveals.md +280 -0
  85. package/skills/struq/references/seo.md +219 -0
  86. package/skills/struq/references/setup.md +397 -0
  87. package/skills/struq/references/showcase.md +87 -0
  88. package/skills/struq/references/stack-targets.md +78 -0
  89. package/skills/struq/references/struq-imagery.md +107 -0
  90. package/skills/struq/references/svg-motion.md +390 -0
  91. package/skills/struq/references/transitions.md +160 -0
  92. package/skills/struq/references/triage.md +71 -0
  93. package/skills/struq/references/typography.md +720 -0
  94. package/skills/struq/references/vibe-presets.md +287 -0
  95. package/skills/struq/references/webgl-r3f.md +274 -0
  96. package/skills/struq/references/webgl-scenes.md +593 -0
@@ -0,0 +1,384 @@
1
+ # Vocabulary for Cinematic Web Experiences
2
+
3
+ Use these terms to make direction specific. Each definition includes the practical question it answers.
4
+
5
+ ## Experience structure
6
+
7
+ ### Experience thesis
8
+ A one-paragraph statement of what the viewer does, how the world responds, and how the emotional intensity develops. It prevents the project from becoming an effect collection.
9
+
10
+ ### Persistent stage
11
+ A viewport-bound visual layer that remains alive while several narrative chapters manipulate its state.
12
+
13
+ ### Chapter
14
+ A controlled interval of experience state with a purpose, local progress, key poses, interaction envelope, and handoff.
15
+
16
+ ### Sequence
17
+ A group of related beats that produces one perceptual action, such as entering a product interior.
18
+
19
+ ### Beat
20
+ A meaningful event the viewer can perceive: a word lands, the camera settles, a shape locks into place, or a light reveals a feature.
21
+
22
+ ### Cue
23
+ A named timeline position or condition that starts a beat.
24
+
25
+ ### Key pose
26
+ A deliberately authored state of camera, subject, type, lighting, and atmosphere. Timelines interpolate between key poses.
27
+
28
+ ### Hold
29
+ An interval where major motion reduces so the viewer can understand, read, or feel the composition.
30
+
31
+ ### Accent
32
+ A brief increase in motion, contrast, sound, scale, or deformation used to emphasize a beat.
33
+
34
+ ### Anticipation
35
+ A preparatory motion that signals an upcoming action, such as a small pullback before a fast push-through.
36
+
37
+ ### Overshoot
38
+ A motion passing slightly beyond its final value before resolving. It creates energy but should match the material and tone.
39
+
40
+ ### Resolution
41
+ The settling state after a transformation or handoff.
42
+
43
+ ### Scroll-distance budget
44
+ The physical amount of scroll allocated to a chapter or sequence, commonly expressed in viewport heights.
45
+
46
+ ### Progress segmentation
47
+ Dividing local progress into named phase windows, for example entrance `0.00 to 0.18`, development `0.18 to 0.65`, and handoff `0.82 to 1.00`.
48
+
49
+ ### Narrative density
50
+ The number of meaningful visual changes per unit of scroll or time. Excess density produces fatigue and weakens emphasis.
51
+
52
+ ### Rhythm
53
+ The pattern of motion, holds, accents, and changes in intensity across the experience.
54
+
55
+ ### Pacing
56
+ How quickly narrative information and visual transformations progress.
57
+
58
+ ## Continuity and transitions
59
+
60
+ ### Handoff
61
+ The interval in which state ownership transfers from one chapter to another.
62
+
63
+ ### Handoff contract
64
+ The written specification for outgoing state, incoming state, shared properties, overlap, ownership, occlusion, reverse behavior, and completion.
65
+
66
+ ### Bridge element
67
+ An object, word, line, mask, light, texture, or camera relationship that exists on both sides of a transition.
68
+
69
+ ### State continuity
70
+ The requirement that a shared property's outgoing final state equals the incoming initial state.
71
+
72
+ ### Spatial carry
73
+ Continuing an object's trajectory while its context changes.
74
+
75
+ ### Match cut
76
+ Aligning shape, composition, scale, direction, or motion between outgoing and incoming states.
77
+
78
+ ### Occlusion wipe
79
+ Passing an object or surface in front of the camera so a state change can occur behind it.
80
+
81
+ ### Foreground wipe
82
+ Using a DOM or WebGL foreground layer to cover and reveal the viewport.
83
+
84
+ ### Camera pass-through
85
+ Moving the camera through or extremely close to geometry to hide a scene change or create spatial continuity.
86
+
87
+ ### Portal transition
88
+ Displaying another state or scene through a mask, aperture, material, or render target.
89
+
90
+ ### Morphological handoff
91
+ Transforming one vector or mesh form into the principal form of the next chapter.
92
+
93
+ ### Typography bridge
94
+ Using a word, glyph, line, or typographic block as the persistent transition object.
95
+
96
+ ### Light bridge
97
+ Beginning the incoming chapter's lighting before its geometry or content is fully revealed.
98
+
99
+ ### Texture bridge
100
+ Using the outgoing render or visual surface as a texture in the incoming state.
101
+
102
+ ### World-space continuity
103
+ Maintaining an object's spatial relationship in the 3D world across a transition.
104
+
105
+ ### Screen-space continuity
106
+ Maintaining a visual element's position or trajectory relative to the viewport, even if its world transform changes.
107
+
108
+ ### Transition cover
109
+ A visual condition that makes a discontinuous state change invisible, such as full occlusion, motion blur, darkness, or a fast macro pass.
110
+
111
+ ## Timeline language
112
+
113
+ ### Master timeline
114
+ The high-level timeline that composes chapter and handoff timelines. It should coordinate rather than contain every raw tween.
115
+
116
+ ### Chapter timeline
117
+ A timeline responsible for the authored state changes within one chapter.
118
+
119
+ ### Handoff timeline
120
+ A timeline responsible specifically for ownership transfer and bridge continuity between chapters.
121
+
122
+ ### Child timeline
123
+ A reusable timeline inserted into a parent timeline.
124
+
125
+ ### Semantic label
126
+ A named timeline point such as `camera:commit` or `handoff:occluded`.
127
+
128
+ ### Relative positioning
129
+ Placing a tween relative to a label or previous action instead of at an unexplained absolute time.
130
+
131
+ ### Overlap
132
+ Starting one beat before another has fully resolved.
133
+
134
+ ### Stagger
135
+ Offsetting related elements. A stagger should communicate reading order, direction, hierarchy, or material behavior rather than being applied by default.
136
+
137
+ ### Scrub
138
+ Mapping scroll progress to a timeline playhead.
139
+
140
+ ### Smoothing
141
+ Reducing abrupt changes in a signal. Lenis smoothing, ScrollTrigger scrub smoothing, and manual damping should be assigned intentionally rather than stacked without control. Pair them the way the main skill does in [`../../references/feel-layer.md`](../../references/feel-layer.md): lower the Lenis lerp, lower the scrub number, and use `scrub: true` for attached layers and a small number for floating ones.
142
+
143
+ ### Easing
144
+ The mathematical shape of a known transition between values.
145
+
146
+ ### Damping
147
+ Continuous convergence toward a moving target, commonly used for pointer and camera reaction.
148
+
149
+ ### Dead zone
150
+ An input range that produces no visual response, useful for preventing jitter.
151
+
152
+ ### Hysteresis
153
+ Different thresholds for entering and leaving a state, preventing rapid state flicker around a boundary.
154
+
155
+ ### Snap point
156
+ A target progress or chapter state toward which the scroll position may settle.
157
+
158
+ ### Critical interval
159
+ A phase where the authored narrative must dominate and reactive effects should attenuate.
160
+
161
+ ## Camera and composition
162
+
163
+ ### Blocking
164
+ Planning where the camera and subjects exist and how they move through space.
165
+
166
+ ### Staging
167
+ Directing attention using composition, depth, scale, light, type, and movement.
168
+
169
+ ### Establishing shot
170
+ A shot that gives spatial or conceptual context.
171
+
172
+ ### Hero shot
173
+ The clearest, most iconic presentation of the principal subject.
174
+
175
+ ### Insert shot
176
+ A focused detail shot used to reveal a feature or clue.
177
+
178
+ ### Macro shot
179
+ An extreme close-up that emphasizes texture, material, or transition geometry.
180
+
181
+ ### Resolution shot
182
+ The final composition that settles the chapter or experience.
183
+
184
+ ### Dolly
185
+ Moving the camera forward or backward.
186
+
187
+ ### Truck
188
+ Moving the camera horizontally.
189
+
190
+ ### Pedestal
191
+ Moving the camera vertically.
192
+
193
+ ### Pan
194
+ Rotating the camera left or right.
195
+
196
+ ### Tilt
197
+ Rotating the camera up or down.
198
+
199
+ ### Roll
200
+ Rotating around the camera's forward axis.
201
+
202
+ ### Orbit
203
+ Moving around a subject while maintaining a target relationship.
204
+
205
+ ### Crane move
206
+ A composed vertical and spatial camera movement.
207
+
208
+ ### Push-in
209
+ A deliberate move toward the subject to increase attention or intensity.
210
+
211
+ ### Pull-out
212
+ A move away from the subject to reveal context or release tension.
213
+
214
+ ### Zoom
215
+ Changing focal length or field of view. It is visually different from moving the camera.
216
+
217
+ ### Dolly zoom
218
+ Combining camera movement with an opposing field-of-view change to alter perceived depth.
219
+
220
+ ### Rack focus
221
+ Changing focus distance between depth planes.
222
+
223
+ ### Parallax reveal
224
+ Using relative movement between near and far layers to reveal depth or content.
225
+
226
+ ### Camera target
227
+ The point or target rig the camera aims toward. Author it alongside position.
228
+
229
+ ### Look-ahead
230
+ A target offset based on movement direction or velocity that anticipates where the viewer is going.
231
+
232
+ ### Composition safe area
233
+ A screen region reserved for type, controls, or responsive cropping.
234
+
235
+ ### Visual axis
236
+ The dominant directional line through a composition or sequence.
237
+
238
+ ### Vanishing point
239
+ The perspective convergence point that can be used to guide camera and typography motion.
240
+
241
+ ## Three.js and transform systems
242
+
243
+ ### Scene graph
244
+ The hierarchy of objects whose local transforms combine into world transforms.
245
+
246
+ ### Rig
247
+ A parent transform created to own one category of movement.
248
+
249
+ ### Narrative rig
250
+ A rig controlled by authored chapter or handoff timelines.
251
+
252
+ ### Interaction rig
253
+ A child rig controlled by pointer, hover, drag, or device input.
254
+
255
+ ### Procedural rig
256
+ A rig controlled by elapsed time, noise, simulation, or idle animation.
257
+
258
+ ### Placement rig
259
+ A rig used for chapter-level positioning and composition.
260
+
261
+ ### Model root
262
+ The imported asset root. Keep authored placement separate from internal model animation whenever possible.
263
+
264
+ ### Camera rig
265
+ A transform hierarchy that separates narrative movement, interaction, shake, and the physical camera.
266
+
267
+ ### Local space
268
+ Coordinates relative to an object's parent.
269
+
270
+ ### World space
271
+ Coordinates after the full scene-graph hierarchy is resolved.
272
+
273
+ ### Screen space
274
+ Coordinates relative to the viewport.
275
+
276
+ ### Anchor
277
+ A named transform or point used for camera targets, DOM alignment, attachments, or transitions.
278
+
279
+ ### Proxy object
280
+ A plain JavaScript object whose numeric values are animated by GSAP and then applied to WebGL uniforms or composed state.
281
+
282
+ ### Render target
283
+ A texture destination for rendered output, used for portals, cross-scene transitions, feedback, reflections, and compositing.
284
+
285
+ ### Post-processing pass
286
+ A full-screen effect applied after scene rendering, such as bloom, depth of field, distortion, color grading, or grain.
287
+
288
+ ### Shader uniform
289
+ A value passed to shader code, commonly used for time, progress, pointer, velocity, color, and transition state.
290
+
291
+ ## Input and interaction
292
+
293
+ ### Input ownership
294
+ The rule that assigns each input to a category of behavior.
295
+
296
+ ### Input arbitration
297
+ Resolving conflicts when several inputs could affect the same experience state.
298
+
299
+ ### Interaction envelope
300
+ The states or progress range in which an interaction is available and how its influence fades in or out.
301
+
302
+ ### Interaction gating
303
+ Reducing or disabling an interaction during a critical narrative interval.
304
+
305
+ ### Macro interaction
306
+ An input that changes chapter or primary state, usually scroll, click, drag, or route navigation.
307
+
308
+ ### Micro interaction
309
+ A local response that supports feedback or tactility without changing the narrative state.
310
+
311
+ ### Magnetic response
312
+ A controlled attraction toward a pointer or target.
313
+
314
+ ### Inertial response
315
+ Continued movement after input changes.
316
+
317
+ ### Velocity mapping
318
+ Converting input velocity into a visual parameter using clamping, normalization, easing, and decay.
319
+
320
+ ### Intent detection
321
+ Distinguishing deliberate navigation from incidental input.
322
+
323
+ ### Gesture lock
324
+ Temporarily assigning control to one direction or interaction mode after intent is detected.
325
+
326
+ ## Quality and implementation
327
+
328
+ ### Direction data
329
+ Centralized, editable values that describe shots, timings, transforms, materials, and interaction strengths.
330
+
331
+ ### Tuning harness
332
+ Development controls used to inspect, scrub, isolate, slow, and capture experience states.
333
+
334
+ ### Vertical slice
335
+ One complete chapter and handoff implemented across DOM, WebGL, interaction, responsive behavior, and cleanup.
336
+
337
+ ### Performance tier
338
+ A capability category used to select effects and asset quality.
339
+
340
+ ### Graceful degradation
341
+ Replacing an expensive mechanism while preserving the intended composition and narrative.
342
+
343
+ ### Reduced-motion choreography
344
+ An intentionally authored version that reduces spatial travel, velocity, and parallax while retaining hierarchy and continuity.
345
+
346
+ ### Frame budget
347
+ The available processing time per frame. At 60 Hz, the total frame duration is approximately 16.7 ms, including browser work.
348
+
349
+ ### Draw call
350
+ A rendering submission to the GPU. Excessive draw calls can limit performance even when geometry is simple.
351
+
352
+ ### Overdraw
353
+ Rendering multiple layers over the same pixels, common with transparent particles and full-screen post effects.
354
+
355
+ ### Lifecycle cleanup
356
+ Killing timelines and ScrollTriggers, removing ticker callbacks and listeners, disposing WebGL resources, and restoring document state on unmount or route change.
357
+
358
+ ## Better direction phrases
359
+
360
+ Replace vague wording with observable behavior.
361
+
362
+ Instead of:
363
+
364
+ > Make the hero more cinematic.
365
+
366
+ Use:
367
+
368
+ > Hold the subject in a low-contrast silhouette for the first 12% of progress. Between 0.12 and 0.28, push the camera from `heroWide` to `heroThreeQuarter`, raise the key light from 0.2 to 1.0, and reveal the title by line with an 80 ms directional stagger. Let the camera settle 150 ms before the final line reaches full opacity.
369
+
370
+ Instead of:
371
+
372
+ > Add a smooth transition.
373
+
374
+ Use:
375
+
376
+ > Use the circular product aperture as a bridge. From 0.78 to 0.90, align it to the viewport center and reduce pointer influence. From 0.86 to 1.00, dolly through the aperture while the incoming environment begins rendering behind it. Swap the environment only after the aperture covers at least 94% of the viewport.
377
+
378
+ Instead of:
379
+
380
+ > Pin every section.
381
+
382
+ Use:
383
+
384
+ > Keep the visual stage viewport-locked across chapters 1 to 4. Use semantic document regions as scroll ranges, but preserve the same canvas, camera rig, central subject, lighting hierarchy, and transition state throughout.
@@ -0,0 +1,302 @@
1
+ # Experience Architecture
2
+
3
+ ## Architectural goals
4
+
5
+ The architecture must make these operations easy:
6
+
7
+ - define a new chapter without rewriting the orchestrator,
8
+ - inspect the active state,
9
+ - scrub any chapter independently,
10
+ - combine narrative and reactive motion without property conflicts,
11
+ - reverse through a transition safely,
12
+ - switch responsive choreography,
13
+ - cleanly unmount a route,
14
+ - tune values without hunting through components.
15
+
16
+ A useful architecture separates **direction data**, **runtime state**, **visual systems**, and **timeline construction**.
17
+
18
+ ## Suggested project structure
19
+
20
+ ```text
21
+ src/
22
+ ├── app/ or routes/
23
+ ├── experience/
24
+ │ ├── direction/
25
+ │ │ ├── chapters.ts
26
+ │ │ ├── shots.ts
27
+ │ │ ├── handoffs.ts
28
+ │ │ ├── motion.ts
29
+ │ │ └── responsive.ts
30
+ │ ├── runtime/
31
+ │ │ ├── ExperienceProvider.tsx
32
+ │ │ ├── experience-state.ts
33
+ │ │ ├── experience-registry.ts
34
+ │ │ ├── progress-router.ts
35
+ │ │ ├── input-system.ts
36
+ │ │ └── lifecycle.ts
37
+ │ ├── timelines/
38
+ │ │ ├── build-master-timeline.ts
39
+ │ │ ├── build-intro.ts
40
+ │ │ ├── chapters/
41
+ │ │ └── handoffs/
42
+ │ ├── stage/
43
+ │ │ ├── ExperienceCanvas.tsx
44
+ │ │ ├── CameraRig.tsx
45
+ │ │ ├── LightingRig.tsx
46
+ │ │ ├── SubjectRig.tsx
47
+ │ │ ├── environments/
48
+ │ │ └── effects/
49
+ │ ├── dom/
50
+ │ │ ├── ExperienceOverlay.tsx
51
+ │ │ ├── ChapterCopy.tsx
52
+ │ │ ├── SvgBridges.tsx
53
+ │ │ └── InterfaceLayer.tsx
54
+ │ ├── debug/
55
+ │ │ ├── ExperienceHUD.tsx
56
+ │ │ ├── TimelineScrubber.tsx
57
+ │ │ └── PerformancePanel.tsx
58
+ │ └── types.ts
59
+ └── styles/
60
+ ```
61
+
62
+ Do not enforce this tree mechanically. Preserve the separation of responsibilities even when the project uses a different naming scheme.
63
+
64
+ ## Direction data
65
+
66
+ Direction data describes the intended experience without containing component logic.
67
+
68
+ ```ts
69
+ export type ShotPreset = {
70
+ camera: {
71
+ position: [number, number, number];
72
+ target: [number, number, number];
73
+ fov: number;
74
+ roll?: number;
75
+ };
76
+ subject?: {
77
+ position: [number, number, number];
78
+ rotation: [number, number, number];
79
+ scale: number | [number, number, number];
80
+ };
81
+ focus?: {
82
+ distance: number;
83
+ aperture: number;
84
+ };
85
+ exposure?: number;
86
+ notes: string;
87
+ };
88
+
89
+ export type ChapterDirection = {
90
+ id: string;
91
+ scrollVh: number;
92
+ phases: Record<string, [number, number]>;
93
+ incomingShot: string;
94
+ heroShot: string;
95
+ outgoingShot: string;
96
+ interactionEnvelope: [number, number];
97
+ copyCues: string[];
98
+ bridgeToNext?: string;
99
+ };
100
+ ```
101
+
102
+ Direction data should be serializable when possible. That makes it easier to inspect, expose in controls, save presets, and let an agent update values safely.
103
+
104
+ ## Runtime state
105
+
106
+ Use mutable runtime state for values that change every frame. Do not push every pointer or progress update through React state.
107
+
108
+ A simple state object can be enough:
109
+
110
+ ```ts
111
+ export type ExperienceRuntime = {
112
+ globalProgress: number;
113
+ activeChapterId: string;
114
+ chapterProgress: number;
115
+ elapsedTime: number;
116
+ deltaTime: number;
117
+ scrollVelocity: number;
118
+ scrollDirection: -1 | 0 | 1;
119
+ pointer: { x: number; y: number; speed: number };
120
+ transition: {
121
+ id: string | null;
122
+ progress: number;
123
+ phase: 'idle' | 'entering' | 'active' | 'leaving';
124
+ };
125
+ };
126
+ ```
127
+
128
+ React state remains appropriate for semantic UI state, accessibility state, route state, and values that must trigger a render. Refs, external stores, or mutable objects are more appropriate for high-frequency visual values.
129
+
130
+ ## Registry pattern
131
+
132
+ Timelines often need to animate objects owned by different React components. Avoid global DOM selectors and brittle imports. Use a registry of named targets.
133
+
134
+ ```ts
135
+ export type ExperienceTargets = {
136
+ cameraNarrativeRig?: THREE.Group;
137
+ cameraTarget?: THREE.Object3D;
138
+ subjectPlacementRig?: THREE.Group;
139
+ subjectMaterial?: THREE.ShaderMaterial;
140
+ heroTitle?: HTMLElement;
141
+ bridgePath?: SVGPathElement;
142
+ };
143
+ ```
144
+
145
+ Components register targets when mounted and unregister them when disposed. Timeline builders receive the registry rather than querying the entire document.
146
+
147
+ Benefits:
148
+
149
+ - clear dependencies,
150
+ - easier testing,
151
+ - fewer selector collisions,
152
+ - safer route cleanup,
153
+ - direct Three.js object animation,
154
+ - more useful missing-target errors.
155
+
156
+ ## Progress router
157
+
158
+ The progress router converts global or scroll-based progress into local chapter and handoff progress.
159
+
160
+ ```ts
161
+ export function rangeProgress(
162
+ value: number,
163
+ start: number,
164
+ end: number,
165
+ ): number {
166
+ if (end <= start) return value >= end ? 1 : 0;
167
+ return Math.min(1, Math.max(0, (value - start) / (end - start)));
168
+ }
169
+ ```
170
+
171
+ For large experiences, store chapter ranges centrally:
172
+
173
+ ```ts
174
+ const narrativeRanges = {
175
+ arrival: [0.00, 0.18],
176
+ reveal: [0.18, 0.42],
177
+ transform: [0.42, 0.72],
178
+ resolve: [0.72, 1.00],
179
+ } as const;
180
+ ```
181
+
182
+ ScrollTrigger can also own each chapter's local progress. Choose one model and document the source of truth.
183
+
184
+ ### Global master mapping
185
+
186
+ Use when:
187
+
188
+ - the experience is one uninterrupted scroll narrative,
189
+ - many systems need a common global progress,
190
+ - transitions overlap deeply,
191
+ - a global scrubber is important.
192
+
193
+ ### Per-chapter ScrollTriggers
194
+
195
+ Use when:
196
+
197
+ - chapters have independent semantic sections,
198
+ - lazy activation matters,
199
+ - chapters can be mounted separately,
200
+ - content height is dynamic.
201
+
202
+ A hybrid is common: per-chapter triggers feed local progress into a route-level state model.
203
+
204
+ ## Timeline builder pattern
205
+
206
+ Timeline builders should be pure enough to recreate safely.
207
+
208
+ ```ts
209
+ export function buildChapterReveal({
210
+ gsap,
211
+ targets,
212
+ direction,
213
+ }: BuildTimelineArgs) {
214
+ const tl = gsap.timeline({ paused: true });
215
+
216
+ tl.addLabel('chapter:enter', 0)
217
+ .fromTo(
218
+ targets.heroTitle,
219
+ { autoAlpha: 0, yPercent: 120 },
220
+ { autoAlpha: 1, yPercent: 0, duration: 0.18, ease: 'power3.out' },
221
+ 'chapter:enter+=0.04',
222
+ )
223
+ .to(
224
+ targets.cameraNarrativeRig.position,
225
+ {
226
+ x: direction.heroShot.camera.position[0],
227
+ y: direction.heroShot.camera.position[1],
228
+ z: direction.heroShot.camera.position[2],
229
+ duration: 0.32,
230
+ ease: 'power2.inOut',
231
+ },
232
+ 'chapter:enter',
233
+ )
234
+ .addLabel('subject:established', 0.32)
235
+ .addLabel('handoff:armed', 0.82)
236
+ .addLabel('chapter:resolved', 1);
237
+
238
+ return tl;
239
+ }
240
+ ```
241
+
242
+ Use a normalized timeline duration of `1` for scroll-driven chapters when that makes phase reasoning easier. For time-driven intros and route transitions, use natural seconds.
243
+
244
+ ## DOM and WebGL coordination
245
+
246
+ DOM and WebGL should share semantic cues, not necessarily the same implementation layer.
247
+
248
+ Example:
249
+
250
+ ```text
251
+ cue: subject:established
252
+ - camera reaches hero shot
253
+ - subject key light reaches 80%
254
+ - title line 1 settles
255
+ - metadata becomes interactive
256
+ ```
257
+
258
+ A GSAP timeline can animate DOM and Three.js objects directly. Alternatively, it can animate proxy values consumed by R3F. Use direct animation for simple object transforms and proxy/state channels for shader values or composed effects.
259
+
260
+ ## Route lifecycle
261
+
262
+ A route-level experience must define:
263
+
264
+ - when scroll is locked or unlocked,
265
+ - when assets are ready enough to begin,
266
+ - intro timeline behavior,
267
+ - route-leave transition,
268
+ - ScrollTrigger creation and refresh,
269
+ - Lenis start/stop behavior,
270
+ - history restoration,
271
+ - timeline and ticker cleanup,
272
+ - WebGL resource disposal,
273
+ - document class and style restoration.
274
+
275
+ A route transition should not leave the previous experience's scroll spacers, ticker functions, event listeners, or render targets alive.
276
+
277
+ ## Error handling and readiness
278
+
279
+ Do not silently build timelines against missing targets. Validate the registry:
280
+
281
+ ```ts
282
+ function requireTarget<T>(value: T | undefined, name: string): T {
283
+ if (!value) throw new Error(`Missing experience target: ${name}`);
284
+ return value;
285
+ }
286
+ ```
287
+
288
+ Create timelines only after required assets and targets are ready. For partial readiness, define which elements are optional and which are blockers.
289
+
290
+ ## Architecture acceptance tests
291
+
292
+ The architecture is healthy when:
293
+
294
+ - a chapter can be scrubbed independently,
295
+ - a handoff can be reversed repeatedly without jumping,
296
+ - pointer movement cannot overwrite camera narrative movement,
297
+ - a mobile shot can be swapped without changing timeline logic,
298
+ - route unmount removes all animation and frame callbacks,
299
+ - tuning values are discoverable in direction files,
300
+ - the current chapter, cue, and owners can be inspected,
301
+ - disabling post-processing does not break the narrative,
302
+ - reduced motion retains hierarchy and continuity.