sheleg-design-skill 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/package.json +1 -1
- package/skill/SHELEG_DESIGN.md +19 -19
- package/skill/SKILL.md +55 -66
package/README.md
CHANGED
|
@@ -64,7 +64,7 @@ npx sheleg-design-skill --help
|
|
|
64
64
|
|
|
65
65
|
| File | Purpose |
|
|
66
66
|
|---|---|
|
|
67
|
-
| `SKILL.md` | Agent-facing skill: discovery trigger
|
|
67
|
+
| `SKILL.md` | Agent-facing skill: discovery trigger, the principles, how to apply them, quick-reference rules, common mistakes |
|
|
68
68
|
| `SHELEG_DESIGN.md` | The full reference: architecture, layer-by-layer mechanics with code, the exact morph math, the DOM↔WebGL projection bridge, a build-from-scratch recipe, and the "why it works" |
|
|
69
69
|
|
|
70
70
|
After installing, a Cursor or Claude agent in that project can discover the
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "sheleg-design-skill",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "SHELEG Design — an agent skill for building cinematic, scroll-driven, particle-backed landing pages. Installs a SKILL.md + reference doc into your project so Cursor/Claude agents can build sites with a single-clock motion system, a scene-formation particle engine, and degrade-to-calm fallbacks.",
|
|
5
5
|
"bin": {
|
|
6
6
|
"sheleg-design-skill": "bin/cli.js"
|
package/skill/SHELEG_DESIGN.md
CHANGED
|
@@ -158,7 +158,7 @@ to you" signal.
|
|
|
158
158
|
|
|
159
159
|
## 3. Layer 2 — Smooth scroll (one position per frame)
|
|
160
160
|
|
|
161
|
-
**File:** `src/components/
|
|
161
|
+
**File:** `src/components/motion/SmoothScroll.tsx`
|
|
162
162
|
|
|
163
163
|
Lenis provides inertial scrolling, but the important move is **driving Lenis
|
|
164
164
|
from the GSAP ticker** rather than its own rAF:
|
|
@@ -183,7 +183,7 @@ and keep native scroll. The store still runs, so the rail and nav stay in sync.
|
|
|
183
183
|
|
|
184
184
|
## 4. Layer 3 — The particle field (the scene-formation engine)
|
|
185
185
|
|
|
186
|
-
**File:** `src/components/
|
|
186
|
+
**File:** `src/components/webgl/SignalField.tsx`
|
|
187
187
|
|
|
188
188
|
This is the showpiece: ~936 points (`24 × 13 × 3`) that narrate the page section
|
|
189
189
|
by section. It is a single `THREE.Points` cloud whose target positions change
|
|
@@ -326,7 +326,7 @@ scrubbed scalar, scrolling back up rewinds the whole explosion frame-for-frame.
|
|
|
326
326
|
|
|
327
327
|
## 5. Layer 4 — The 2D fallback (SignalMesh)
|
|
328
328
|
|
|
329
|
-
**File:** `src/components/
|
|
329
|
+
**File:** `src/components/atmosphere/SignalMesh.tsx`
|
|
330
330
|
|
|
331
331
|
Touch and no-WebGL clients get a canvas mesh: two depth layers of grid nodes
|
|
332
332
|
with hairline links and traveling pulses, plus **stroke overlays** that fade in
|
|
@@ -399,18 +399,18 @@ particle "head" runs exactly where the line tip is being drawn.
|
|
|
399
399
|
|
|
400
400
|
Three small components, one mechanism each, all reading the same clock.
|
|
401
401
|
|
|
402
|
-
### FocalSpotlight — `src/components/
|
|
402
|
+
### FocalSpotlight — `src/components/motion/FocalSpotlight.tsx`
|
|
403
403
|
An `IntersectionObserver` with a generous center band (`rootMargin: -22% 0 -22% 0`)
|
|
404
404
|
toggles a `data-dim` attribute on sections outside the band. CSS dims them to
|
|
405
405
|
62% opacity. The reader's eye is always pulled to the active section. The finale
|
|
406
406
|
section is excluded (`:not(#finale)`) because it runs its own fade.
|
|
407
407
|
|
|
408
|
-
### ParallaxDrift — `src/components/
|
|
408
|
+
### ParallaxDrift — `src/components/motion/ParallaxDrift.tsx`
|
|
409
409
|
Wraps **at most one figure per viewport** in a GSAP `yPercent` scrub for a few
|
|
410
410
|
percent of depth drift. Restraint is the rule: parallax on everything is nausea;
|
|
411
411
|
parallax on the one hero figure is depth.
|
|
412
412
|
|
|
413
|
-
### ScrollRail — `src/components/
|
|
413
|
+
### ScrollRail — `src/components/atmosphere/ScrollRail.tsx`
|
|
414
414
|
A right-edge hairline whose fill is scaled imperatively (`scaleY(global)`) and
|
|
415
415
|
brightened by `velocity` — a live mission timeline, updated per frame with zero
|
|
416
416
|
React renders. Act markers deep-link to their anchor sections and use the coarse
|
|
@@ -420,7 +420,7 @@ React renders. Act markers deep-link to their anchor sections and use the coarse
|
|
|
420
420
|
|
|
421
421
|
## 8. Layer 7 — Reveal primitives (act-themed entrances)
|
|
422
422
|
|
|
423
|
-
**File:** `src/components/
|
|
423
|
+
**File:** `src/components/design/Reveal.tsx`
|
|
424
424
|
|
|
425
425
|
Entrances are not generic. Each narrative act has a reveal whose *physics* match
|
|
426
426
|
its meaning — this is Disney's "staging" applied to a scroll page:
|
|
@@ -487,7 +487,7 @@ The non-negotiables (each learned from a real bug here):
|
|
|
487
487
|
No component invents its own curve. Everything uses:
|
|
488
488
|
|
|
489
489
|
- **`EASE = cubic-bezier(0.16, 1, 0.3, 1)`** (an easeOutExpo-like signature),
|
|
490
|
-
mirrored in CSS as `--
|
|
490
|
+
mirrored in CSS as `--motion-ease`.
|
|
491
491
|
- **`DUR`** — `fast 0.18` / `base 0.32` / `slow 0.55` / `epic 0.8` seconds.
|
|
492
492
|
- **`STAGGER = 0.07`** — the standard interval between sibling reveals.
|
|
493
493
|
|
|
@@ -622,18 +622,18 @@ A pragmatic order that front-loads the parts everything else depends on.
|
|
|
622
622
|
| Lazy GSAP + reduced-motion gate | `src/lib/motion/gsap-client.ts` |
|
|
623
623
|
| DOM↔WebGL bridge | `src/lib/motion/field-sync.ts` |
|
|
624
624
|
| Interactive field gestures | `src/lib/motion/use-section-field.ts` |
|
|
625
|
-
| WebGL particle field | `src/components/
|
|
626
|
-
| 2D fallback field | `src/components/
|
|
627
|
-
| Field/fallback mode switch | `src/components/
|
|
628
|
-
| Constellation SVG overlay | `src/components/
|
|
629
|
-
| Progress rail | `src/components/
|
|
630
|
-
| Smooth scroll | `src/components/
|
|
631
|
-
| Attention dimming | `src/components/
|
|
632
|
-
| Figure parallax | `src/components/
|
|
633
|
-
| Reveal primitives | `src/components/
|
|
634
|
-
| Epilogue runway | `src/components/
|
|
625
|
+
| WebGL particle field | `src/components/webgl/SignalField.tsx` |
|
|
626
|
+
| 2D fallback field | `src/components/atmosphere/SignalMesh.tsx` |
|
|
627
|
+
| Field/fallback mode switch | `src/components/atmosphere/AtmosphereField.tsx` |
|
|
628
|
+
| Constellation SVG overlay | `src/components/atmosphere/ConstellationOverlay.tsx` |
|
|
629
|
+
| Progress rail | `src/components/atmosphere/ScrollRail.tsx` |
|
|
630
|
+
| Smooth scroll | `src/components/motion/SmoothScroll.tsx` |
|
|
631
|
+
| Attention dimming | `src/components/motion/FocalSpotlight.tsx` |
|
|
632
|
+
| Figure parallax | `src/components/motion/ParallaxDrift.tsx` |
|
|
633
|
+
| Reveal primitives | `src/components/design/Reveal.tsx` |
|
|
634
|
+
| Epilogue runway | `src/components/sections/FinaleSection.tsx` |
|
|
635
635
|
| Scrubbed instruments (examples) | `WhyNowChart.tsx`, `EcosystemDiagram.tsx`, `PinnedSteps.tsx` |
|
|
636
|
-
| CSS tokens +
|
|
636
|
+
| CSS tokens + motion styles | `src/app/motion.css` |
|
|
637
637
|
|
|
638
638
|
---
|
|
639
639
|
|
package/skill/SKILL.md
CHANGED
|
@@ -1,85 +1,74 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: sheleg-design
|
|
3
|
-
description: Use when building or upgrading a cinematic
|
|
3
|
+
description: Use when building or upgrading a cinematic scroll-driven landing page, marketing site, or hero experience — a particle/WebGL background, scroll-linked animation, parallax, pinned or scrubbed sections, formation-morphing scenes — or when such a page feels busy or janky, or its motion layers drift out of sync with each other. Read before designing the motion architecture; pairs with an existing visual system, does not replace one.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# SHELEG Design
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
reference (architecture, code-level mechanics, build-from-scratch recipe, file
|
|
10
|
-
map, and the deeper "why") lives in [`SHELEG_DESIGN.md`](./SHELEG_DESIGN.md) next
|
|
11
|
-
to this file — read it before implementing.
|
|
12
|
-
|
|
13
|
-
## The thesis
|
|
8
|
+
## Overview
|
|
14
9
|
|
|
15
10
|
A page feels cinematic not from many animations, but from a **single source of
|
|
16
|
-
truth** (scroll position) driving **many cheap, layered
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
state.
|
|
11
|
+
truth** (measured scroll position) driving **many cheap, layered,
|
|
12
|
+
independently-degradable responses**. Centralize scroll into one store; layers
|
|
13
|
+
read it per frame and react in their own language. Nothing crossfades — things
|
|
14
|
+
*redeploy*. Every layer degrades to a calm static state.
|
|
21
15
|
|
|
22
|
-
|
|
16
|
+
**REQUIRED REFERENCE:** read [`SHELEG_DESIGN.md`](./SHELEG_DESIGN.md) (same
|
|
17
|
+
directory) before implementing — it holds the architecture, exact morph math,
|
|
18
|
+
the DOM↔WebGL bridge, the build recipe (§11), and the file map.
|
|
23
19
|
|
|
24
|
-
|
|
25
|
-
measure scroll independently, so they can never drift out of phase.
|
|
26
|
-
2. **Read per frame, notify rarely.** Hot consumers (WebGL/canvas/rail) read the
|
|
27
|
-
store imperatively each frame and cause zero React renders. Only coarse,
|
|
28
|
-
human-visible changes (the current "act"/section) notify the framework.
|
|
29
|
-
3. **Hold, then redeploy.** Hold a formation steady for ~80% of a section, then
|
|
30
|
-
morph in a short, phase-staggered, arc-curved wave. Ban crossfades.
|
|
31
|
-
4. **Earned motion.** Scrub belongs to instruments that narrate state over time
|
|
32
|
-
(charts, step flows). Hover/entrance motion stays sub-500ms and never gates
|
|
33
|
-
content visibility.
|
|
34
|
-
5. **Degrade to calm.** `prefers-reduced-motion` / coarse pointer / no-WebGL all
|
|
35
|
-
collapse to a static, fully-legible page. The effect is a bonus, never a
|
|
36
|
-
dependency.
|
|
20
|
+
## When to Use
|
|
37
21
|
|
|
38
|
-
|
|
22
|
+
- Landing/marketing/hero pages where motion is a stated goal
|
|
23
|
+
- Particle or WebGL backgrounds tied to scroll; scenes that morph per section
|
|
24
|
+
- Scroll-linked charts, step flows, progress rails, parallax
|
|
25
|
+
- Existing scroll site that feels nervous, janky, or out of phase
|
|
39
26
|
|
|
40
|
-
|
|
27
|
+
**Not for:** docs, dashboards, static content sites — or any page whose visual
|
|
28
|
+
system or copy isn't finished yet. Fix those first; motion amplifies weakness.
|
|
41
29
|
|
|
42
|
-
|
|
43
|
-
top of a weak visual system amplifies the weakness. SHELEG Design is the
|
|
44
|
-
motion layer — it assumes a visual foundation exists.
|
|
45
|
-
2. **Build bottom-up following the layer order** in `SHELEG_DESIGN.md` §11:
|
|
46
|
-
the scroll clock → smooth scroll → particle field → 2D fallback → DOM
|
|
47
|
-
choreography → reveal primitives → scrubbed instruments → (optional) DOM↔WebGL
|
|
48
|
-
bridge. Each layer is a small, single-responsibility file reading the one clock.
|
|
49
|
-
3. **Storyboard in data.** Express the narrative as a `SCENES` registry (one
|
|
50
|
-
`{ anchor, formation, focusX, energy }` per section). Iterate on the data
|
|
51
|
-
before touching render loops.
|
|
52
|
-
4. **Pay the fallback + a11y tax in the same commit** as each layer, never at the
|
|
53
|
-
end. Every animated component ships its reduced-motion branch immediately.
|
|
54
|
-
5. **Verify** with typecheck/lint/build, screenshots of each scene mid-hold and
|
|
55
|
-
mid-morph, a reduced-motion pass, and a narrow-viewport pass.
|
|
30
|
+
## Core Pattern — five principles, in order
|
|
56
31
|
|
|
57
|
-
|
|
32
|
+
1. **One clock.** All motion derives from one measured scroll state; no layer
|
|
33
|
+
measures scroll itself, so layers can never drift out of phase.
|
|
34
|
+
2. **Read per frame, notify rarely.** Hot consumers (WebGL/canvas/rail) read
|
|
35
|
+
the store imperatively, zero framework renders; only coarse act/section
|
|
36
|
+
changes notify the framework.
|
|
37
|
+
3. **Hold, then redeploy.** Hold a formation ~80% of a section, then morph in a
|
|
38
|
+
short, phase-staggered, arc-curved wave. Crossfades are banned.
|
|
39
|
+
4. **Earned motion.** Scrub only for instruments that narrate state over time;
|
|
40
|
+
hover/entrance motion stays sub-500ms and never gates content.
|
|
41
|
+
5. **Degrade to calm.** Reduced-motion / coarse pointer / no-WebGL collapse to
|
|
42
|
+
a static, fully-legible page. The effect is a bonus, never a dependency.
|
|
58
43
|
|
|
59
|
-
|
|
60
|
-
per-frame readers and a coarse subscription for framework-rendered UI.
|
|
61
|
-
- Hold-then-morph (long hold, short smoothstepped tail) — constant morphing
|
|
62
|
-
reads as nervous; this is the single biggest "calm" lever.
|
|
63
|
-
- Redeploy with a per-point phase-staggered, perpendicular-arc migration — this
|
|
64
|
-
is what makes a particle field read as premium rather than a screensaver.
|
|
65
|
-
- Drive smooth scroll (e.g. Lenis) from the animation library's ticker so
|
|
66
|
-
scrubbed instruments and the particle field share one inertia.
|
|
67
|
-
- Lazy-load heavy libs (GSAP/WebGL) out of the initial bundle; WebGL mounts one
|
|
68
|
-
frame after hydration paints.
|
|
69
|
-
- One ease + a tiny duration/stagger token set for the whole site; no component
|
|
70
|
-
invents its own curve.
|
|
71
|
-
- For scrubbed SVG: `ease: 'none'`, `pathLength={1}` to normalize paths, and
|
|
72
|
-
always kill timelines + triggers on cleanup.
|
|
73
|
-
- Animate only `transform` and `opacity`; reserve scrub for genuine instruments.
|
|
44
|
+
## How to Apply
|
|
74
45
|
|
|
75
|
-
|
|
46
|
+
1. Visual system first (color, type, spacing, components).
|
|
47
|
+
2. Build bottom-up in the §11 layer order: scroll clock → smooth scroll →
|
|
48
|
+
particle field → 2D fallback → DOM choreography → reveals → scrubbed
|
|
49
|
+
instruments → optional DOM↔WebGL bridge. One small file per layer.
|
|
50
|
+
3. Storyboard in data: a `SCENES` registry (`{ anchor, formation, focusX,
|
|
51
|
+
energy }` per section); iterate on the data before touching render loops.
|
|
52
|
+
4. Ship each layer's reduced-motion/fallback branch in the same commit.
|
|
53
|
+
5. Verify: typecheck/lint/build; screenshot each scene mid-hold and mid-morph;
|
|
54
|
+
reduced-motion pass; narrow-viewport pass.
|
|
76
55
|
|
|
77
|
-
|
|
78
|
-
a goal. Do not bolt the particle field onto a page whose visual system or copy
|
|
79
|
-
isn't finished — fix those first.
|
|
56
|
+
## Quick Reference
|
|
80
57
|
|
|
81
|
-
|
|
58
|
+
| Rule | Prevents |
|
|
59
|
+
|---|---|
|
|
60
|
+
| One scroll store, two read paths (live getter + coarse subscription) | layers drifting out of phase; render storms |
|
|
61
|
+
| Long hold, short smoothstepped morph tail | nervous, constantly-moving page |
|
|
62
|
+
| Per-point phase-staggered, perpendicular-arc migration | "screensaver" particle look |
|
|
63
|
+
| Smooth scroll driven from the animation library's ticker | scrub and field on different inertia |
|
|
64
|
+
| Lazy-load GSAP/WebGL; mount WebGL one frame after hydration | heavy initial bundle, hydration jank |
|
|
65
|
+
| One ease + tiny duration/stagger token set site-wide | motion reading as many systems, not one |
|
|
66
|
+
| Scrubbed SVG: `ease: 'none'`, `pathLength={1}`, kill timelines on cleanup | easing fighting scrub; leaked triggers |
|
|
67
|
+
| Animate only `transform`/`opacity` | layout thrash |
|
|
68
|
+
|
|
69
|
+
## Common Mistakes
|
|
82
70
|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
71
|
+
- Paying the fallback/a11y tax "at the end" → it never ships. Same commit.
|
|
72
|
+
- Parallax on everything → nausea. At most one drifting figure per viewport.
|
|
73
|
+
- Scrub on hero/entrances → motion feels unearned; reserve scrub for
|
|
74
|
+
instruments.
|