@struq/skill 0.0.0-stage → 0.2.2

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 +141 -2
  3. package/cli/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,409 @@
1
+ # Struq Directed Mode
2
+
3
+ Directed mode is what Struq switches into when a page must behave as one continuous directed WebGL experience instead of a stack of animated sections. In this mode you act as a senior interaction director, motion architect and WebGL engineer. Scroll, time, pointer input, DOM typography, SVG, camera movement, 3D objects, shaders, lighting and route transitions share one deliberate narrative system.
4
+
5
+ Stack: Next.js or Vite, React, Lenis, GSAP with ScrollTrigger and its plugins, React Three Fiber, Three.js, and Motion for React.
6
+
7
+ ## When to enter directed mode
8
+
9
+ Enter directed mode only when at least one of these is true:
10
+
11
+ 1. A persistent WebGL stage spans multiple chapters (the canvas, camera and subject stay alive while the content changes).
12
+ 2. DOM and 3D must visually intersect across scroll (a word becomes the portal, a card becomes an aperture, a label tracks a model anchor).
13
+ 3. The brief is explicitly an "experience" rather than a marketing page.
14
+
15
+ If none of these is true, stay in the normal Struq flow at [`../SKILL.md`](../SKILL.md). A marketing site with type, palette, Lenis plus GSAP reveals, a pinned showpiece or a route transition does not need directed mode, and the ceremony below would slow it down.
16
+
17
+ A page that only has a decorative WebGL hero (one scene, no chapters) also stays in the normal flow. Use [`../references/webgl-r3f.md`](../references/webgl-r3f.md) and [`../references/webgl-scenes.md`](../references/webgl-scenes.md) for that.
18
+
19
+ Directed mode extends the main skill, it does not replace it:
20
+
21
+ | Concern | Where it is decided |
22
+ |---|---|
23
+ | Type system | [`../references/typography.md`](../references/typography.md) |
24
+ | Palette and mood | [`../references/vibe-presets.md`](../references/vibe-presets.md) |
25
+ | Single clock (Lenis driven by `gsap.ticker`, R3F driven from it) | [`../references/setup.md`](../references/setup.md) and [`../references/webgl-r3f.md`](../references/webgl-r3f.md) |
26
+ | Drei helpers, postprocessing, interactive scenes | [`../references/webgl-scenes.md`](../references/webgl-scenes.md) |
27
+ | What awards-level work looks like | [`../references/showcase.md`](../references/showcase.md) |
28
+ | What to avoid | [`../references/anti-patterns.md`](../references/anti-patterns.md) |
29
+
30
+ This folder adds what those files do not cover: experience state, property ownership, chapters, camera blocking, semantic timelines, handoff contracts, tuning and audit criteria.
31
+
32
+ **Order of work.** `/struq direct` first runs [`../references/direction.md`](../references/direction.md) phases 0 to 3 (Intake, Brand, Concept, System) into `STRUQ.md`, with `Mode: directed`. Only then do the phases below start, and their lean outputs are appended to the same `STRUQ.md` under a `## DIRECTION` section (see Project artifacts). The direction.md gate still applies: one "Veto anything?" message, after the DIRECTION section is written and before code.
33
+
34
+ ## Stack rules inherited from the main skill
35
+
36
+ Three rules from the main skill are binding in directed mode. Nothing in this folder overrides them.
37
+
38
+ 1. **One clock.** Lenis is created with `autoRaf: false` and advanced from `gsap.ticker`. ScrollTrigger reads from Lenis. The R3F canvas is mounted with `frameloop="never"` and advanced from the same ticker (a reactive-only scene with no ambient animation may use `frameloop="demand"` with `invalidate()`, never the default `always`). No other `requestAnimationFrame` loop runs. Scroll progress, elapsed time and pointer input are separate signals, not separate clocks.
39
+ 2. **GSAP owns scroll.** Every scroll-linked behavior (pinned stage, scrubbed chapter timelines, activation, velocity and direction signals) is GSAP and ScrollTrigger. Motion never reads scroll progress for the narrative, and `lenis.scrollTo()` is the only scroll command path. High-frequency pointer work on DOM elements runs on the same ticker through `gsap.quickTo`, not through a Motion spring loop. Lenis lerp and scrub smoothing are paired as in [`../references/feel-layer.md`](../references/feel-layer.md).
40
+ 3. **The GSAP vs Motion split is the one in [`../SKILL.md`](../SKILL.md) (GSAP vs Motion: the decision rule).** That table decides who animates menus, overlays, hover and press; this folder does not restate it. If a Motion component takes part in a GSAP sequence, one library owns the outer wrapper and the other owns an inner element. Never animate the same transform from both.
41
+
42
+ ## Principles
43
+
44
+ 1. **Continuity before spectacle.** The experience must feel like one evolving world. Do not reset the camera, lighting, background, subject or typography at every chapter unless the reset is an intentional narrative beat.
45
+ 2. **Pinning is a mechanism, not the concept.** Prefer a persistent viewport-locked stage spanning multiple chapters over a stack of independently pinned panels.
46
+ 3. **Every chapter is a state transformation.** Define its initial state, final state, progress windows, key poses, interaction envelope and handoff contract.
47
+ 4. **One writer per property.** Narrative, reactive, procedural and discrete systems must not compete for the same transform. Use nested rigs or separate state channels.
48
+ 5. **Separate signals, one clock.** Scroll progress owns narrative state, elapsed time owns ambient motion, pointer and velocity modulate the result, and clicks and routes own discrete transitions. All of them are read on the single `gsap.ticker` clock.
49
+ 6. **Handoffs are designed explicitly.** Every boundary specifies shared bridge elements, overlap, ownership transfer, occlusion, camera continuity, reverse behavior and a completion condition.
50
+ 7. **Choreograph beats, not arbitrary tweens.** Use semantic labels, key poses, holds, accents, anticipations, overlaps and resolutions.
51
+ 8. **Manual tuning is expected.** Expose important values through direction data and provide a tuning harness. Do not bury composition values inside components.
52
+ 9. **Responsive choreography is authored.** Mobile, reduced-motion and low-performance variants preserve intent but may use different shots and transition mechanics.
53
+ 10. **Do not code before direction is stable.** For substantial work, establish the chapter map, ownership model, handoff contracts and camera shots first.
54
+
55
+ ## Operating modes
56
+
57
+ Pick the mode from the request. Use a hybrid when the request spans several, state the active phase, and do not make the user restate what is already known.
58
+
59
+ - **Design** when there is a concept, references, copy, assets or a visual direction but no stable experience specification.
60
+ - **Implementation** when code is being built or changed and needs architecture, sequencing, integration, debugging or tuning guidance.
61
+ - **Audit** when there is a current page, codebase, timeline, video, screenshots or written plan to make more cinematic, coherent, performant or professional.
62
+
63
+ ## Initial discovery
64
+
65
+ Collect only details that materially change the architecture. Infer sensible defaults for the rest.
66
+
67
+ - The central subject, product, story or metaphor.
68
+ - The desired emotional progression.
69
+ - Required chapters or content.
70
+ - Available assets: models, image sequences, video, SVG, type, audio, data, shaders.
71
+ - Target devices and performance floor.
72
+ - Required interactions and route behavior.
73
+ - Whether scrolling is continuous, snap-assisted, hybrid or state-based.
74
+ - Whether DOM and WebGL must visually intersect.
75
+ - Which aspects must stay editable by a non-specialist.
76
+
77
+ Do not start with a library checklist. Start with the experience, then assign libraries once the state and motion responsibilities are clear.
78
+
79
+ ## Phased workflow
80
+
81
+ ### Phase 1: Frame the experience
82
+
83
+ Write a one-paragraph **experience thesis** containing what the viewer is doing, what the visual world is doing, how the emotional intensity changes, what makes the experience continuous, and what the final resolution should feel like.
84
+
85
+ Then define a compact **experience contract**: persistent stage strategy, chapter count and purpose, primary transition language, input ownership, camera character, typography behavior (decided with [`../references/typography.md`](../references/typography.md)), performance class, reduced-motion strategy and prohibited generic patterns.
86
+
87
+ ### Phase 2: Map chapters
88
+
89
+ For every chapter define the narrative purpose, incoming state, outgoing state, primary subject, dominant visual action, camera shot or movement, DOM and SVG role, lighting and atmosphere, local progress phases, interaction envelope and the bridge to the next chapter.
90
+
91
+ Use the default chapter grammar when there is no better structure:
92
+
93
+ `pre-roll → entrance → establish → development → transformation → handoff preparation → handoff → resolution → post-roll`
94
+
95
+ Not every chapter uses every phase. The grammar is a diagnostic tool, not a mandatory animation recipe.
96
+
97
+ ### Phase 3: Define state and ownership
98
+
99
+ Create an explicit state model with at least `routeState`, `chapterId`, `chapterProgress`, `globalProgress`, `transitionState`, `scrollVelocity`, `scrollDirection`, `pointerNormalized`, `pointerVelocity`, `elapsedTime`, `viewportClass`, `reducedMotion`, `performanceTier` and `interactionMode`.
100
+
101
+ Build a property ownership table. For each animated property, name the sole authoritative writer and any additive modulation channel. The layer model is below.
102
+
103
+ ### Phase 4: Design handoffs
104
+
105
+ Every adjacent chapter pair gets a handoff contract (see Handoffs below). Reject transitions that only fade one section out and the next one in, unless that simplicity is a deliberate contrast beat.
106
+
107
+ ### Phase 5: Direct camera and composition
108
+
109
+ Create named shot presets instead of scattering raw camera values. Each shot defines camera position, target position, field of view, roll, near and far planes when relevant, focus distance and aperture when depth of field is used, exposure, subject transform, composition notes, safe framing for typography, and desktop and mobile variants.
110
+
111
+ Use cinematography language: dolly, truck, pedestal, pan, tilt, roll, orbit, crane, push-in, pull-out, zoom, rack focus, parallax reveal, match cut, hero framing, insert, macro detail, establishing shot and resolution shot. Definitions are in [`references/02-vocabulary.md`](references/02-vocabulary.md).
112
+
113
+ ### Phase 6: Build the timeline hierarchy
114
+
115
+ See Timeline hierarchy below. Detail is in [`references/04-timeline-choreography.md`](references/04-timeline-choreography.md).
116
+
117
+ ### Phase 7: Assign stack responsibilities
118
+
119
+ See Stack responsibilities below. Plugin detail is in [`references/08-gsap-plugin-patterns.md`](references/08-gsap-plugin-patterns.md).
120
+
121
+ ### Phase 8: Implement in vertical slices
122
+
123
+ Build one complete chapter and one complete handoff before the whole experience. Recommended order:
124
+
125
+ 1. Persistent stage and layout scaffolding.
126
+ 2. Scroll and frame-loop integration (the single clock).
127
+ 3. Experience state and registry.
128
+ 4. First camera shot and subject rig.
129
+ 5. One chapter timeline.
130
+ 6. One handoff contract implemented end to end.
131
+ 7. Tuning controls and debug overlays.
132
+ 8. Remaining chapters.
133
+ 9. Responsive variants.
134
+ 10. Performance, accessibility and route lifecycle.
135
+ 11. Final rhythm and polish pass.
136
+
137
+ At each step keep a working experience. Do not create all scenes first and attempt orchestration at the end.
138
+
139
+ ### Phase 9: Tune
140
+
141
+ Treat tuning as direction work, not cleanup. Expose chapter scroll budgets, local phase boundaries, timeline overlaps, shot presets, path control points, subject transforms, pointer influence, damping constants, velocity mappings, shader values, lighting values, post-processing intensity, copy reveal timing and reduced-motion substitutions.
142
+
143
+ Provide or recommend a control surface with global progress, chapter progress, play and pause, reverse, slow motion, jump-to-label, camera readouts, current ownership, ScrollTrigger markers, performance metrics, post-processing toggles and preset capture. Full list and tuning order: [`references/09-tuning-harness.md`](references/09-tuning-harness.md).
144
+
145
+ ### Phase 10: Audit
146
+
147
+ Score the work against narrative clarity, continuity, chapter differentiation, handoff quality, camera direction, property ownership, timing and rhythm, input arbitration, typography choreography, DOM and WebGL integration, responsive adaptation, reduced motion, performance stability, tuning readiness, and route lifecycle and cleanup. The full rubric is [`references/12-audit-rubric.md`](references/12-audit-rubric.md).
148
+
149
+ For every problem identify the observed symptom, the architectural cause, the perceptual consequence, the exact corrective action and the validation method. Fix structure before decoration.
150
+
151
+ ## Ownership and layer model
152
+
153
+ Four layers cover every motion in the experience.
154
+
155
+ - **Narrative layer:** GSAP chapter and handoff timelines, scrubbed by ScrollTrigger.
156
+ - **Ambient layer:** R3F `useFrame`, shader time uniforms, model idles, particles. Runs when scroll stops.
157
+ - **Reactive layer:** damped pointer, hover, drag, scroll velocity, device orientation. Additive and limited.
158
+ - **Discrete layer:** route transitions, overlays, project opens, menu states, mode changes.
159
+
160
+ When layers must combine, use nested transform rigs, one parent per category of motion:
161
+
162
+ ```text
163
+ cameraPlacementRig route or viewport placement
164
+ └── cameraNarrativeRig chapter and handoff timelines
165
+ └── cameraReactionRig pointer and velocity modulation
166
+ └── cameraShakeRig procedural noise
167
+ └── camera
168
+ ```
169
+
170
+ For scalar values (shader distortion, bloom), use named channels and compose them centrally: `final = narrative + velocity + hover`, then clamp. Rig and channel patterns: [`references/06-three-rig-architecture.md`](references/06-three-rig-architecture.md).
171
+
172
+ ## Handoffs
173
+
174
+ A handoff is a designed state interval between two chapters, not a decorative effect. Every handoff contract specifies:
175
+
176
+ - outgoing owner and incoming owner,
177
+ - shared bridge element,
178
+ - matching end and start state (and the coordinate space it is measured in),
179
+ - overlap window,
180
+ - camera path continuity,
181
+ - occlusion or compositing method, with a measurable coverage condition,
182
+ - typography and lighting continuity,
183
+ - interaction gating,
184
+ - reverse-scroll behavior,
185
+ - asset readiness requirement,
186
+ - completion condition.
187
+
188
+ Bridge strategies (object, aperture or portal, occluder, typography, vector, light, render target, motion) and the contract schema are in [`references/05-handoff-contracts.md`](references/05-handoff-contracts.md). The blank form is [`templates/04-handoff-contract.md`](templates/04-handoff-contract.md).
189
+
190
+ ## Timeline hierarchy
191
+
192
+ ```text
193
+ Route lifecycle
194
+ ├── preload timeline
195
+ ├── intro timeline
196
+ ├── master narrative timeline
197
+ │ ├── chapter timeline
198
+ │ ├── handoff timeline
199
+ │ ├── chapter timeline
200
+ │ └── handoff timeline
201
+ ├── discrete interaction timelines
202
+ └── outro / route-leave timeline
203
+ ```
204
+
205
+ The master timeline coordinates child timelines and labels. It must not become a dumping ground for hundreds of unrelated selectors. Use semantic labels such as `chapter:enter`, `subject:established`, `copy:available`, `camera:commit`, `transformation:apex`, `handoff:armed`, `handoff:occluded` and `chapter:resolved`. Position tweens relative to labels, not with unexplained numeric offsets.
206
+
207
+ ## Stack responsibilities
208
+
209
+ Use these defaults unless the project requires another allocation.
210
+
211
+ | Tool | Responsibility |
212
+ |---|---|
213
+ | Next.js or Vite | Application shell, routing, data, assets, build system. |
214
+ | React | Composition and lifecycle. |
215
+ | Three.js and React Three Fiber | Persistent 3D stage, camera rigs, scene graph, shaders, post-processing, render targets. Rendered from the single ticker. |
216
+ | GSAP | Authored narrative timelines, SVG morphing and drawing, text choreography, route and discrete transition sequences. |
217
+ | ScrollTrigger | Scroll-to-progress mapping, pinned stage ranges, chapter activation, velocity and direction signals. |
218
+ | Lenis | Physical scroll smoothing and normalization, advanced from `gsap.ticker`. |
219
+ | Motion for React | React-lifecycle motion: presence, layout, UI micro-interactions, stateful overlays, controls outside the central timeline. |
220
+ | SplitText | Typography segmentation and re-split-aware text choreography. |
221
+ | DrawSVGPlugin, MorphSVGPlugin, MotionPathPlugin | Stroke reveals, path-to-path transitions, controlled travel along authored paths. |
222
+ | Flip | DOM layout-state transitions where source and destination layouts must visually connect. |
223
+ | Observer | Gesture normalization for wheel, touch, pointer and intent-driven state changes. |
224
+ | CustomEase, CustomWiggle, CustomBounce | Project-specific motion character where standard eases are not enough. |
225
+
226
+ Do not let GSAP and Motion control the same property on the same element at the same time. Drei helpers, postprocessing and interactive scene patterns are covered in [`../references/webgl-scenes.md`](../references/webgl-scenes.md). Integration detail is in [`references/07-stack-integration.md`](references/07-stack-integration.md).
227
+
228
+ ## Response behavior
229
+
230
+ When designing, produce direction before code. When implementing, provide the smallest coherent next slice and say where it belongs in the architecture. When auditing, separate architecture faults, choreography faults, implementation faults, performance faults and polish opportunities.
231
+
232
+ Use concrete statements. Replace "make it more dynamic" with measurable direction such as:
233
+
234
+ > During local progress 0.62 to 0.78, reduce the pointer influence from 0.08 to 0.015, dolly the narrative camera rig from shot `detailWide` to `apertureEntry`, rotate the bridge object 38 degrees around local Y, and begin the incoming environment lighting at 0.70 while the outgoing background remains visible until 0.82.
235
+
236
+ Distinguish architectural certainty (ownership, lifecycle, state boundaries, cleanup), direction hypotheses (camera path, timing, ease, phase range) and visual tuning values (exact position, FOV, light intensity). Give strong starting values, name the ones that need in-browser judgment, and never pretend an exact composition is final before seeing it run. More in [`references/11-agent-workflows.md`](references/11-agent-workflows.md).
237
+
238
+ ## Required outputs by mode
239
+
240
+ ### Design mode: lean direction (default)
241
+
242
+ For most directed builds, produce these six. They are the ones that decide whether the experience holds together.
243
+
244
+ 1. **Experience thesis** (one paragraph).
245
+ 2. **Chapter map table** (id, name, purpose, main transformation, scroll budget, bridge to next).
246
+ 3. **Ownership matrix** (every animated property, its narrative owner, reactive and ambient channels, transfer cue).
247
+ 4. **Shot presets** (named camera and subject poses with desktop and mobile variants).
248
+ 5. **Handoff contracts** for each chapter boundary.
249
+ 6. **Acceptance criteria** (observable outcomes).
250
+
251
+ Templates: [`templates/02-experience-contract.md`](templates/02-experience-contract.md) (thesis and chapter map), [`templates/05-ownership-matrix.md`](templates/05-ownership-matrix.md), [`templates/06-shot-presets.md`](templates/06-shot-presets.md), [`templates/04-handoff-contract.md`](templates/04-handoff-contract.md), [`templates/09-acceptance-tests.md`](templates/09-acceptance-tests.md). A worked example of the lean pieces is in [`examples/concise/`](examples/concise/01-chapter-spec-example.md).
252
+
253
+ Add the rest only when the problem needs it. Reduced-motion and mobile variants should still be stated in one line each, even in a lean direction.
254
+
255
+ ### Design mode: full direction (large builds)
256
+
257
+ For large builds, long-lived projects or teams, produce all fifteen:
258
+
259
+ 1. experience thesis,
260
+ 2. experience contract,
261
+ 3. narrative map,
262
+ 4. chapter specification table,
263
+ 5. state model,
264
+ 6. ownership matrix,
265
+ 7. scene and rig hierarchy,
266
+ 8. shot presets,
267
+ 9. timeline hierarchy,
268
+ 10. semantic cue map,
269
+ 11. handoff contracts,
270
+ 12. responsive and reduced-motion variants,
271
+ 13. implementation plan,
272
+ 14. tuning parameters,
273
+ 15. acceptance criteria.
274
+
275
+ A complete worked example is [`examples/verbose/01-full-experience-direction.md`](examples/verbose/01-full-experience-direction.md).
276
+
277
+ ### Implementation mode
278
+
279
+ 1. current-state summary,
280
+ 2. target slice,
281
+ 3. involved files and responsibilities,
282
+ 4. state and ownership implications,
283
+ 5. code or pseudocode,
284
+ 6. cleanup and lifecycle behavior,
285
+ 7. tuning values exposed,
286
+ 8. validation checklist,
287
+ 9. next vertical slice.
288
+
289
+ Template: [`templates/07-implementation-slice.md`](templates/07-implementation-slice.md). Reference code: [`examples/code/`](examples/code/shared/README.md).
290
+
291
+ ### Audit mode
292
+
293
+ 1. executive diagnosis,
294
+ 2. scorecard,
295
+ 3. continuity map,
296
+ 4. property-conflict map,
297
+ 5. timeline and handoff findings,
298
+ 6. camera and composition findings,
299
+ 7. performance and accessibility findings,
300
+ 8. prioritized remediation plan,
301
+ 9. before and after behavior specification,
302
+ 10. validation tests.
303
+
304
+ Worked example: [`examples/verbose/02-full-audit-example.md`](examples/verbose/02-full-audit-example.md). Short version: [`examples/concise/03-audit-finding-example.md`](examples/concise/03-audit-finding-example.md).
305
+
306
+ ## Prohibited patterns
307
+
308
+ Flag these unless intentionally justified:
309
+
310
+ - independent viewport-height sections with no shared state,
311
+ - repeated headline fade-up plus image scale pattern,
312
+ - full reset of camera and environment at every boundary,
313
+ - transition implemented only as an opacity crossfade,
314
+ - every element moving simultaneously,
315
+ - no hold or reading time,
316
+ - pointer parallax at equal strength throughout,
317
+ - scroll velocity mapped directly without clamping or smoothing,
318
+ - camera position animated without an authored target,
319
+ - one monolithic timeline with anonymous offsets,
320
+ - React state updates on every animation frame for mutable visual values,
321
+ - multiple libraries controlling the same transform,
322
+ - a second animation clock (R3F on its default loop, a stray `requestAnimationFrame`, Lenis with `autoRaf` on) next to `gsap.ticker`,
323
+ - hidden hardcoded tuning values across components,
324
+ - desktop choreography merely scaled down for mobile,
325
+ - no reverse-scroll design,
326
+ - no reduced-motion experience,
327
+ - expensive effects enabled uniformly on all devices,
328
+ - route changes that leave ScrollTriggers, timelines, ticker callbacks or WebGL resources alive.
329
+
330
+ ## Project artifacts
331
+
332
+ `STRUQ.md` stays the one contract. The lean direction (thesis, chapter map, ownership matrix, shot presets, handoff contracts, acceptance criteria) is appended to it as one section:
333
+
334
+ ```markdown
335
+ ## DIRECTION
336
+ Thesis: <one paragraph>
337
+ Chapters: <table: id, name, purpose, main transformation, scroll budget, bridge to next>
338
+ Ownership: <table: property, narrative owner, reactive and ambient channels, transfer cue>
339
+ Shots: <named camera and subject poses, desktop and mobile>
340
+ Handoffs: <one contract per chapter boundary>
341
+ Acceptance: <observable outcomes>
342
+ Mobile / reduced motion: <one line each>
343
+ ```
344
+
345
+ Option for large builds, long-lived projects or teams only: split the full direction into a folder next to `STRUQ.md`, and link it from the DIRECTION section so the contract still points at everything:
346
+
347
+ ```text
348
+ direction/
349
+ ├── experience-brief.md
350
+ ├── experience-contract.md
351
+ ├── chapter-map.md
352
+ ├── state-model.md
353
+ ├── ownership-matrix.md
354
+ ├── shot-presets.md
355
+ ├── handoff-contracts.md
356
+ ├── responsive-variants.md
357
+ ├── tuning-register.md
358
+ └── acceptance-tests.md
359
+ ```
360
+
361
+ A lean direction never needs the folder: the DIRECTION section above is the whole artifact.
362
+
363
+ ## Reference map
364
+
365
+ Read only what the current task needs.
366
+
367
+ References:
368
+
369
+ - Core mental model: [`references/01-core-mental-model.md`](references/01-core-mental-model.md)
370
+ - Vocabulary: [`references/02-vocabulary.md`](references/02-vocabulary.md)
371
+ - Experience architecture: [`references/03-experience-architecture.md`](references/03-experience-architecture.md)
372
+ - Timeline choreography: [`references/04-timeline-choreography.md`](references/04-timeline-choreography.md)
373
+ - Handoff contracts: [`references/05-handoff-contracts.md`](references/05-handoff-contracts.md)
374
+ - Three.js and R3F rig architecture: [`references/06-three-rig-architecture.md`](references/06-three-rig-architecture.md)
375
+ - Stack integration: [`references/07-stack-integration.md`](references/07-stack-integration.md)
376
+ - GSAP plugin patterns: [`references/08-gsap-plugin-patterns.md`](references/08-gsap-plugin-patterns.md)
377
+ - Tuning and debugging: [`references/09-tuning-harness.md`](references/09-tuning-harness.md)
378
+ - Responsive, performance and accessibility: [`references/10-quality-systems.md`](references/10-quality-systems.md)
379
+ - Agent workflows: [`references/11-agent-workflows.md`](references/11-agent-workflows.md)
380
+ - Audit rubric: [`references/12-audit-rubric.md`](references/12-audit-rubric.md)
381
+ - Official documentation index: [`references/13-official-docs.md`](references/13-official-docs.md)
382
+
383
+ Templates (blank production artifacts):
384
+
385
+ - [`templates/01-experience-brief.md`](templates/01-experience-brief.md)
386
+ - [`templates/02-experience-contract.md`](templates/02-experience-contract.md)
387
+ - [`templates/03-chapter-spec.md`](templates/03-chapter-spec.md)
388
+ - [`templates/04-handoff-contract.md`](templates/04-handoff-contract.md)
389
+ - [`templates/05-ownership-matrix.md`](templates/05-ownership-matrix.md)
390
+ - [`templates/06-shot-presets.md`](templates/06-shot-presets.md)
391
+ - [`templates/07-implementation-slice.md`](templates/07-implementation-slice.md)
392
+ - [`templates/08-tuning-register.md`](templates/08-tuning-register.md)
393
+ - [`templates/09-acceptance-tests.md`](templates/09-acceptance-tests.md)
394
+
395
+ Checklists:
396
+
397
+ - [`checklists/01-preproduction.md`](checklists/01-preproduction.md)
398
+ - [`checklists/02-implementation.md`](checklists/02-implementation.md)
399
+ - [`checklists/03-polish.md`](checklists/03-polish.md)
400
+
401
+ Examples:
402
+
403
+ - Concise (minimum useful specificity): [`examples/concise/01-chapter-spec-example.md`](examples/concise/01-chapter-spec-example.md), [`examples/concise/02-handoff-example.md`](examples/concise/02-handoff-example.md), [`examples/concise/03-audit-finding-example.md`](examples/concise/03-audit-finding-example.md)
404
+ - Verbose (complete packages): [`examples/verbose/01-full-experience-direction.md`](examples/verbose/01-full-experience-direction.md), [`examples/verbose/02-full-audit-example.md`](examples/verbose/02-full-audit-example.md)
405
+ - Code (architecture patterns, not a finished design): [`examples/code/shared/README.md`](examples/code/shared/README.md), [`examples/code/nextjs/README.md`](examples/code/nextjs/README.md), [`examples/code/vite/README.md`](examples/code/vite/README.md)
406
+
407
+ ## A note on pinning
408
+
409
+ A cinematic site does not require every content region to be individually pinned. The stronger pattern is usually one persistent stage whose state evolves across several scroll ranges. Pinning controls viewport behavior. It does not create continuity by itself.
@@ -0,0 +1,15 @@
1
+ # Preproduction Checklist
2
+
3
+ - [ ] The experience thesis is one coherent transformation.
4
+ - [ ] Required content is mapped to narrative actions, not only sections.
5
+ - [ ] The persistent-stage strategy is decided.
6
+ - [ ] Chapters have purposes, scroll budgets, and bridge ideas.
7
+ - [ ] Primary input ownership is explicit.
8
+ - [ ] Camera character and shot language are defined.
9
+ - [ ] Typography has a motion and layout system.
10
+ - [ ] Models contain or receive useful anchors.
11
+ - [ ] Every chapter boundary has a draft handoff contract.
12
+ - [ ] Desktop, mobile, and reduced-motion intent is documented.
13
+ - [ ] Asset readiness is mapped to chapter needs.
14
+ - [ ] Prohibited generic patterns are written down.
15
+ - [ ] One vertical slice is selected for the first implementation proof.
@@ -0,0 +1,17 @@
1
+ # Implementation Checklist
2
+
3
+ - [ ] GSAP plugins are registered once in the correct client context.
4
+ - [ ] Lenis and ScrollTrigger use one documented integration path.
5
+ - [ ] The persistent stage and semantic scroll regions are separated.
6
+ - [ ] Runtime state avoids per-frame React updates.
7
+ - [ ] Timeline targets use refs or a registry rather than global selectors.
8
+ - [ ] Camera, subject, and effects use explicit rigs or channels.
9
+ - [ ] One complete chapter and handoff work before expansion.
10
+ - [ ] Chapter timelines use semantic labels.
11
+ - [ ] Shared state matches at ownership transfer.
12
+ - [ ] Reverse scroll is tested continuously.
13
+ - [ ] Interaction is gated during critical intervals.
14
+ - [ ] Direction values are centralized.
15
+ - [ ] A debug HUD and scrubber exist.
16
+ - [ ] Resize and font/model readiness trigger controlled rebuilds.
17
+ - [ ] Route unmount kills timelines, triggers, callbacks, and listeners.
@@ -0,0 +1,17 @@
1
+ # Direction and Polish Checklist
2
+
3
+ - [ ] Each chapter has one dominant visual idea.
4
+ - [ ] Motion density varies across the experience.
5
+ - [ ] Every major movement has anticipation or consequence.
6
+ - [ ] Stable holds provide reading and comprehension time.
7
+ - [ ] Camera stops and copy land with intentional microtiming.
8
+ - [ ] The principal subject changes role across chapters.
9
+ - [ ] Bridge elements become visible before the boundary.
10
+ - [ ] Lighting begins preparing incoming states early.
11
+ - [ ] SVG and text motion share the visual axis.
12
+ - [ ] Pointer influence is not uniform across all chapters.
13
+ - [ ] Velocity effects have controlled attack and decay.
14
+ - [ ] Post-processing supports beats rather than masking weak composition.
15
+ - [ ] Mobile has authored shots and cover conditions.
16
+ - [ ] Reduced motion retains hierarchy and continuity.
17
+ - [ ] Slow-motion recordings reveal no jumps or accidental simultaneous landings.
@@ -0,0 +1,13 @@
1
+ # Next.js Adapter
2
+
3
+ ## Install
4
+
5
+ ```bash
6
+ npm install gsap @gsap/react lenis three @react-three/fiber @react-three/drei motion
7
+ ```
8
+
9
+ Copy `cinematic/examples/code/shared` to `src/experience`.
10
+
11
+ Then use the files in this folder as the App Router adapter. The main experience component is a client component because it uses browser APIs, animation lifecycles, and WebGL.
12
+
13
+ Verify GSAP plugin imports against your installed version. Keep semantic content available outside the canvas, and add a WebGL fallback appropriate to the actual project.
@@ -0,0 +1,13 @@
1
+ 'use client';
2
+
3
+ import type { JSX } from 'react';
4
+ import { ExperiencePage } from '@/experience/ExperiencePage';
5
+ import { LenisRoot } from './components/LenisRoot';
6
+
7
+ export function CinematicExperience(): JSX.Element {
8
+ return (
9
+ <LenisRoot>
10
+ <ExperiencePage />
11
+ </LenisRoot>
12
+ );
13
+ }
@@ -0,0 +1,42 @@
1
+ 'use client';
2
+
3
+ import { ReactLenis, useLenis, type LenisRef } from 'lenis/react';
4
+ import 'lenis/dist/lenis.css';
5
+ import { useEffect, useRef, type JSX, type ReactNode } from 'react';
6
+ import { gsap, ScrollTrigger, registerGsap } from '@/experience/gsap-client';
7
+
8
+ registerGsap();
9
+
10
+ type LenisRootProps = {
11
+ children: ReactNode;
12
+ };
13
+
14
+ export function LenisRoot({ children }: LenisRootProps): JSX.Element {
15
+ const lenisRef = useRef<LenisRef>(null);
16
+
17
+ // ScrollTrigger sync. useLenis subscribes as soon as the root instance exists,
18
+ // so it never races the ref the way a one-time lenis.on('scroll') capture does.
19
+ useLenis(() => ScrollTrigger.update());
20
+
21
+ useEffect(() => {
22
+ // Registered unconditionally; the instance is resolved through the ref on
23
+ // every frame. Never capture it once and early-return: that is the
24
+ // dead-scroll race (references/setup.md §2).
25
+ const update = (time: number) => {
26
+ lenisRef.current?.lenis?.raf(time * 1000);
27
+ };
28
+
29
+ gsap.ticker.add(update);
30
+ gsap.ticker.lagSmoothing(0);
31
+
32
+ return () => {
33
+ gsap.ticker.remove(update);
34
+ };
35
+ }, []);
36
+
37
+ return (
38
+ <ReactLenis root ref={lenisRef} options={{ lerp: 0.1, anchors: true, autoRaf: false }}>
39
+ {children}
40
+ </ReactLenis>
41
+ );
42
+ }
@@ -0,0 +1,6 @@
1
+ import type { JSX } from 'react';
2
+ import { CinematicExperience } from './cinematic-experience';
3
+
4
+ export default function Page(): JSX.Element {
5
+ return <CinematicExperience />;
6
+ }
@@ -0,0 +1,65 @@
1
+ import { PerspectiveCamera } from '@react-three/drei';
2
+ import { useFrame } from '@react-three/fiber';
3
+ import { useEffect, useRef, type JSX } from 'react';
4
+ import * as THREE from 'three';
5
+ import { experienceRegistry } from './registry';
6
+ import { runtime } from './runtime';
7
+ import { damp } from './math';
8
+
9
+ const targetWorld = new THREE.Vector3();
10
+
11
+ export function CameraRig(): JSX.Element {
12
+ const narrativeRig = useRef<THREE.Group>(null);
13
+ const reactionRig = useRef<THREE.Group>(null);
14
+ const targetNarrativeRig = useRef<THREE.Group>(null);
15
+ const camera = useRef<THREE.PerspectiveCamera>(null);
16
+
17
+ useEffect(() => {
18
+ if (!narrativeRig.current || !targetNarrativeRig.current || !camera.current) return;
19
+
20
+ const unregister = [
21
+ experienceRegistry.register('cameraNarrativeRig', narrativeRig.current),
22
+ experienceRegistry.register('cameraTargetNarrativeRig', targetNarrativeRig.current),
23
+ experienceRegistry.register('camera', camera.current),
24
+ ];
25
+
26
+ return () => unregister.forEach((dispose) => dispose());
27
+ }, []);
28
+
29
+ useFrame((state, delta) => {
30
+ if (!reactionRig.current || !targetNarrativeRig.current || !camera.current) return;
31
+
32
+ runtime.elapsedTime = state.clock.elapsedTime;
33
+ runtime.deltaTime = delta;
34
+
35
+ const multiplier = runtime.viewport === 'mobile' ? 0 : 1;
36
+ const strength = runtime.channels.pointerCameraStrength * multiplier;
37
+
38
+ reactionRig.current.rotation.y = damp(
39
+ reactionRig.current.rotation.y,
40
+ runtime.pointer.x * strength,
41
+ 8,
42
+ delta,
43
+ );
44
+ reactionRig.current.rotation.x = damp(
45
+ reactionRig.current.rotation.x,
46
+ -runtime.pointer.y * strength * 0.55,
47
+ 8,
48
+ delta,
49
+ );
50
+
51
+ targetNarrativeRig.current.getWorldPosition(targetWorld);
52
+ camera.current.lookAt(targetWorld);
53
+ });
54
+
55
+ return (
56
+ <>
57
+ <group ref={narrativeRig} position={[0, 0.25, 5.8]}>
58
+ <group ref={reactionRig}>
59
+ <PerspectiveCamera ref={camera} makeDefault position={[0, 0, 0]} fov={34} />
60
+ </group>
61
+ </group>
62
+ <group ref={targetNarrativeRig} position={[0, 0, 0]} />
63
+ </>
64
+ );
65
+ }
@@ -0,0 +1,20 @@
1
+ import type { JSX } from 'react';
2
+ import { Canvas } from '@react-three/fiber';
3
+ import { CameraRig } from './CameraRig';
4
+ import { GsapFrameLoop } from './GsapFrameLoop';
5
+ import { SubjectRig } from './SubjectRig';
6
+ import { InteriorRoot } from './InteriorRoot';
7
+
8
+ export function ExperienceCanvas(): JSX.Element {
9
+ return (
10
+ <Canvas dpr={[1, 1.5]} gl={{ antialias: true }} frameloop="never">
11
+ <GsapFrameLoop />
12
+ <color attach="background" args={['#080808']} />
13
+ <ambientLight intensity={0.35} />
14
+ <directionalLight position={[3, 4, 5]} intensity={3} />
15
+ <CameraRig />
16
+ <SubjectRig />
17
+ <InteriorRoot />
18
+ </Canvas>
19
+ );
20
+ }