@skyf0xx/hedgehog 2.0.3 → 2.0.5

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@skyf0xx/hedgehog",
3
- "version": "2.0.3",
3
+ "version": "2.0.5",
4
4
  "description": "Install the Hedgehog build discipline (agents + skills) into a repo.",
5
5
  "type": "module",
6
6
  "repository": {
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: landing-builder
3
- description: Use for the build phase of the Chain Method (landing-page core) — implementing the audited spec exactly in Astro, Tailwind, GSAP/ScrollTrigger/Lenis, SplitType, and Paper.js/SVG for the motif, placing landing-copywriter's final copy verbatim. Runs last, only after landing-critic returns a pass. Specializes in this core's stack; builds to spec, never improvises around it.
3
+ description: Use for the build phase of the Chain Method (landing-page core) — implementing the audited spec exactly in Astro, Tailwind, GSAP/ScrollTrigger/Lenis, SplitType, and the p5.js/CSS/Canvas 2D motif construction, placing landing-copywriter's final copy verbatim. Runs last, only after landing-critic returns a pass. Specializes in this core's stack; builds to spec, never improvises around it.
4
4
  model: sonnet
5
5
  color: green
6
6
  tools: Read, Glob, Grep, Edit, Write, Bash
@@ -28,18 +28,20 @@ never silently improvised around.
28
28
  gap in the token system, flagged back to `landing-systems`, not
29
29
  invented locally.
30
30
  - **GSAP + ScrollTrigger** — implement `landing-sequencer`'s pacing spec:
31
- section transitions, timing. Import `MorphSVGPlugin` from
32
- `gsap/MorphSVGPlugin` directly (it ships inside the `gsap` package
33
- no separate install).
31
+ section transitions, timing. Scoped to CSS/transform targets only, no
32
+ plugins a `border-radius` string tween replaces shape-morphing, for
33
+ example.
34
34
  - **Lenis** — wire smooth-scroll globally, matching the beat structure
35
35
  `landing-sequencer` specified.
36
36
  - **SplitType** — implement copy-reveal splitting exactly where
37
37
  `landing-sequencer`'s beat structure calls for it, not on every section
38
38
  by default.
39
- - **Paper.js / hand-authored SVG** — implement the motif from
40
- `src/motifs/` exactly as `landing-systems` specified (source,
41
- persistence, continuity, scale range, literalness) don't simplify or
42
- embellish it during implementation.
39
+ - **p5.js / CSS / Canvas 2D** — implement the motif from `src/motifs/`
40
+ exactly as `landing-systems` specified (source, persistence,
41
+ continuity, scale range, literalness), using whichever construction
42
+ technique the spec calls for (p5.js for organic/generative, CSS for
43
+ static geometric, Canvas 2D for measured/connective) — don't simplify
44
+ or embellish it during implementation.
43
45
  - **React Three Fiber** — only if the subject is genuinely spatial and
44
46
  `landing-systems`/`landing-sequencer` specified it; otherwise never
45
47
  reach for it.
@@ -21,14 +21,19 @@ values and the signature motif.
21
21
  block in `src/styles/global.css` (Tailwind v4, CSS-first — no
22
22
  `tailwind.config.js`). No component classes, no plugin beyond the
23
23
  base.
24
- - **SVG-first** for the motif hand-authored graphics, no icon library
25
- or generator look to fight against.
26
- - **Paper.js** canvas vector work, for a motif that needs to evolve
27
- (augmentation/inversion) rather than sit static.
28
- - Figma MCP / Stitch MCP, if the user provides a design reference, are
29
- input onlynever allowed to set spacing or style values directly.
30
- Anything handed off through them gets re-derived through your own
31
- token system before it touches Tailwind config.
24
+ - **Motif construction** is picked per motif type, never hand-typed
25
+ coordinates:
26
+ - **p5.js** for an organic/generative motif described as a rule
27
+ (noise, jitter, growth) rather than freehand path data.
28
+ - **CSS** (`clip-path` / gradients / `border-radius`) for a static
29
+ geometric motifspines, chevrons, blobs directly GSAP-animatable.
30
+ - **Canvas 2D with computed coordinates** for a measured/connective
31
+ motif threads/lines that align to real DOM positions, drawn from
32
+ measured values, not imagined ones.
33
+ - This core has no design-handoff tool. Every token, dial, and motif
34
+ choice is derived directly from `landing-strategist`'s emotional
35
+ target and your own reconciliation at step 5 — never imported from an
36
+ external design file.
32
37
 
33
38
  ## Core Responsibilities
34
39
 
@@ -153,9 +158,16 @@ Borrowed technique:
153
158
  retrograde) for exactly how the motif is allowed to evolve as it
154
159
  recurs, rather than repeating identically or mutating arbitrarily
155
160
 
156
- Author the motif as hand-built SVG, or as a Paper.js sketch if it needs
157
- to evolve programmatically across sectionsoutput either the SVG
158
- markup or the Paper.js setup into `src/motifs/`.
161
+ Pick the construction technique from what the motif actually is, not by
162
+ default: a p5.js sketch (driven by a formula noise, jitter, growth) for
163
+ an organic motif that needs to evolve programmatically across sections; a
164
+ CSS-only treatment (`clip-path`, gradients, `border-radius`) for a static
165
+ geometric shape; Canvas 2D driven by measured DOM coordinates for a motif
166
+ that threads/connects across real element positions. Output the result
167
+ into `src/motifs/`. Use the `motif-authoring` skill for the actual
168
+ construction: build from a formula, a measurement, or a small set of
169
+ deliberate CSS primitives — never a hand-typed freehand coordinate — that's
170
+ the difference between a sourced motif and generic clip-art geometry.
159
171
 
160
172
  ## Workflow
161
173
 
@@ -196,8 +208,6 @@ markup or the Paper.js setup into `src/motifs/`.
196
208
  decorative asset to fill a gap — that gap is a signal to go back to the
197
209
  Ingredient Vocabulary and derive the right choice, not to default to
198
210
  something off-the-shelf.
199
- - Figma/Stitch MCP output, if used, is never copied through as final
200
- token values — always re-derived through step 5's reconciliation.
201
211
  - Don't write section layout, pacing, or transitions — that's
202
212
  `landing-sequencer`'s step 7, working from your token system.
203
213
  - Don't touch `src/pages/`, `src/sections/` beyond what's needed to
@@ -21,7 +21,8 @@
21
21
  "astro": "^7.1.3",
22
22
  "gsap": "^3.15.0",
23
23
  "lenis": "^1.3.25",
24
- "paper": "^0.12.18",
24
+ "ogl": "^1.0.11",
25
+ "p5": "^2.3.1",
25
26
  "split-type": "^0.3.4",
26
27
  "tailwindcss": "^4.3.3"
27
28
  },
@@ -20,9 +20,12 @@ importers:
20
20
  lenis:
21
21
  specifier: ^1.3.25
22
22
  version: 1.3.25
23
- paper:
24
- specifier: ^0.12.18
25
- version: 0.12.18
23
+ ogl:
24
+ specifier: ^1.0.11
25
+ version: 1.0.11
26
+ p5:
27
+ specifier: ^2.3.1
28
+ version: 2.3.1
26
29
  split-type:
27
30
  specifier: ^0.3.4
28
31
  version: 0.3.4
@@ -175,6 +178,10 @@ packages:
175
178
  engines: {node: '>=6.0.0'}
176
179
  hasBin: true
177
180
 
181
+ '@babel/runtime@7.29.7':
182
+ resolution: {integrity: sha512-Nq8OhGWiZIZGV6hLHoyAKLLcJihP/xFeBMGJoUrxTX2psI8dCifzLhZISFb+VWS3wFMRDmCGw5R+dOySCqPLhw==}
183
+ engines: {node: '>=6.9.0'}
184
+
178
185
  '@babel/types@7.29.7':
179
186
  resolution: {integrity: sha512-4zBIxpPzowiZpusoFkyGVwakdRJUyuH5PxQ/PrqghfdFWWasvnCdPfQXHrenDai+gyLARulZjZowCOj6fjT4pA==}
180
187
  engines: {node: '>=6.9.0'}
@@ -236,6 +243,9 @@ packages:
236
243
  resolution: {integrity: sha512-y7/yvZ2TPAnR9+jnc00klvNNLkJiXFFrQA/hlLCcxA9a2A4zQIOimyFQ9XfwYKiGD1fb5GY8vbKIIgO8d5Tb2A==}
237
244
  engines: {node: '>= 20.12.0'}
238
245
 
246
+ '@davepagurek/bezier-path@0.0.7':
247
+ resolution: {integrity: sha512-CVlnCOrV1iy4Z12T756i9l4G6kF7r8uhlnb+xqDemAMmWQB+8Q0b+8VEqIiUfywgZDSiDr18Rm7pZlnA69rE8Q==}
248
+
239
249
  '@emmetio/abbreviation@2.3.3':
240
250
  resolution: {integrity: sha512-mgv58UrU3rh4YgbE/TzgLQwJ3pFsHHhCLqY20aJq+9comytTXUDNGG/SMtSeMJdkpxgXSXunBGLD8Boka3JyVA==}
241
251
 
@@ -621,6 +631,9 @@ packages:
621
631
  cpu: [x64]
622
632
  os: [win32]
623
633
 
634
+ '@japont/unicode-range@1.0.0':
635
+ resolution: {integrity: sha512-BckHvA2XdjRBVAWe2uceNuRf78lBeI28kyWEbfr/Q2pE17POkwuZ6WWY/UMv8FL9iBxhW4xfDoNLM9UVZaTeUQ==}
636
+
624
637
  '@jridgewell/gen-mapping@0.3.13':
625
638
  resolution: {integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==}
626
639
 
@@ -991,6 +1004,10 @@ packages:
991
1004
  peerDependencies:
992
1005
  acorn: ^6.0.0 || ^7.0.0 || ^8.0.0
993
1006
 
1007
+ acorn-walk@8.3.5:
1008
+ resolution: {integrity: sha512-HEHNfbars9v4pgpW6SO1KSPkfoS0xVOM/9UzkJltjlsHZmJasxg8aXkuZa7SMf8vKGIBhpUsPluQSqhJFCqebw==}
1009
+ engines: {node: '>=0.4.0'}
1010
+
994
1011
  acorn@8.17.0:
995
1012
  resolution: {integrity: sha512-xRQbDb9BnwDafYNn6Vwl839DYVjqXYb1XVGtWAZ1kcDc6iwAL4hg3B1dZlRiuENFeO2H53gFG3in621AdERVAg==}
996
1013
  engines: {node: '>=0.4.0'}
@@ -1106,6 +1123,9 @@ packages:
1106
1123
  color-name@1.1.4:
1107
1124
  resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==}
1108
1125
 
1126
+ colorjs.io@0.6.1:
1127
+ resolution: {integrity: sha512-8lyR2wHzuIykCpqHKgluGsqQi5iDm3/a2IgP2GBZrasn2sBRkE4NOGsglZxWLs/jZQoNkmA/KM/8NV16rLUdBg==}
1128
+
1109
1129
  comma-separated-tokens@2.0.3:
1110
1130
  resolution: {integrity: sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==}
1111
1131
 
@@ -1242,6 +1262,11 @@ packages:
1242
1262
  resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==}
1243
1263
  engines: {node: '>=10'}
1244
1264
 
1265
+ escodegen@2.1.0:
1266
+ resolution: {integrity: sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==}
1267
+ engines: {node: '>=6.0'}
1268
+ hasBin: true
1269
+
1245
1270
  eslint-plugin-astro@3.0.1:
1246
1271
  resolution: {integrity: sha512-skys0KV/5m/rQ6a4BDAGOGtrGoBlWNYiWtoDjx25bghDwTiKXng63s4Yv823iX3ht/tH/kHtoUM2poxESGsv3w==}
1247
1272
  engines: {node: ^22.22.3 || ^24.16.0 || >=26.3.0}
@@ -1281,6 +1306,11 @@ packages:
1281
1306
  resolution: {integrity: sha512-7p3DrVEIopW1B1avAGLuCSh1jubc01H2JHc8B4qqGblmg5gI9yumBgACjWo4JlIc04ufug4xJ3SQI8HkS/Rgzw==}
1282
1307
  engines: {node: ^20.19.0 || ^22.13.0 || >=24}
1283
1308
 
1309
+ esprima@4.0.1:
1310
+ resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==}
1311
+ engines: {node: '>=4'}
1312
+ hasBin: true
1313
+
1284
1314
  esquery@1.7.0:
1285
1315
  resolution: {integrity: sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g==}
1286
1316
  engines: {node: '>=0.10'}
@@ -1375,6 +1405,9 @@ packages:
1375
1405
  resolution: {integrity: sha512-7nF7C9fIPFEMHgEMEfgIlO9wDdZ8CyHw27rWciFZfHvHDReIiPhsYuzPRXsfvBCqFy1l8RRyyWV7QLM+ZhUJsQ==}
1376
1406
  engines: {node: '>=20.20.0'}
1377
1407
 
1408
+ gifenc@1.0.3:
1409
+ resolution: {integrity: sha512-xdr6AdrfGBcfzncONUOlXMBuc5wJDtOueE3c5rdG0oNgtINLD+f2iFZltrBRZYzACRbKr+mSVU/x98zv2u3jmw==}
1410
+
1378
1411
  github-slugger@2.0.0:
1379
1412
  resolution: {integrity: sha512-IaOQ9puYtjrkq7Y0Ygl9KDZnrf/aiUJYUpVf89y8kyaxbRG7Y1SrX/jaumrv81vc61+kiMempujsM3Yw7w5qcw==}
1380
1413
 
@@ -1422,6 +1455,12 @@ packages:
1422
1455
  http-cache-semantics@4.2.0:
1423
1456
  resolution: {integrity: sha512-dTxcvPXqPvXBQpq5dUr6mEMJX4oIEFv6bwom3FDwKRDsuIjjJGANqhBuoAn9c1RQJIdAKav33ED65E2ys+87QQ==}
1424
1457
 
1458
+ i18next-browser-languagedetector@4.3.1:
1459
+ resolution: {integrity: sha512-KIToAzf8zwWvacgnRwJp63ase26o24AuNUlfNVJ5YZAFmdGhsJpmFClxXPuk9rv1FMI4lnc8zLSqgZPEZMrW4g==}
1460
+
1461
+ i18next@19.9.2:
1462
+ resolution: {integrity: sha512-0i6cuo6ER6usEOtKajUUDj92zlG+KArFia0857xxiEHAQcUwh/RtOQocui1LPJwunSYT574Pk64aNva1kwtxZg==}
1463
+
1425
1464
  ignore@5.3.2:
1426
1465
  resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==}
1427
1466
  engines: {node: '>= 4'}
@@ -1512,6 +1551,9 @@ packages:
1512
1551
  resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==}
1513
1552
  engines: {node: '>= 0.8.0'}
1514
1553
 
1554
+ libtess@1.2.2:
1555
+ resolution: {integrity: sha512-Nps8HPeVVcsmJxUvFLKVJcCgcz+1ajPTXDVAVPs6+giOQP4AHV31uZFFkh+CKow/bkB7GbZWKmwmit7myaqDSw==}
1556
+
1515
1557
  lightningcss-android-arm64@1.32.0:
1516
1558
  resolution: {integrity: sha512-YK7/ClTt4kAK0vo6w3X+Pnm0D2cf2vPHbhOXdoNti1Ga0al1P4TBZhwjATvjNwLEBCnKvjJc2jQgHXH0NEwlAg==}
1517
1559
  engines: {node: '>= 12.0.0'}
@@ -1739,9 +1781,15 @@ packages:
1739
1781
  ofetch@1.5.1:
1740
1782
  resolution: {integrity: sha512-2W4oUZlVaqAPAil6FUg/difl6YhqhUR7x2eZY4bQCko22UXg3hptq9KLQdqFClV+Wu85UX7hNtdGTngi/1BxcA==}
1741
1783
 
1784
+ ogl@1.0.11:
1785
+ resolution: {integrity: sha512-kUpC154AFfxi16pmZUK4jk3J+8zxwTWGPo03EoYA8QPbzikHoaC82n6pNTbd+oEaJonaE8aPWBlX7ad9zrqLsA==}
1786
+
1742
1787
  ohash@2.0.11:
1743
1788
  resolution: {integrity: sha512-RdR9FQrFwNBNXAr4GixM8YaRZRJ5PUWbKYbE5eOsrwAjJW0q2REGcf79oYPsLyskQCZG1PLN+S/K1V00joZAoQ==}
1744
1789
 
1790
+ omggif@1.0.10:
1791
+ resolution: {integrity: sha512-LMJTtvgc/nugXj0Vcrrs68Mn2D1r0zf630VNtqtpI1FEO7e+O9FP4gqs9AcnBaSEeoHIPm28u6qgPR0oyEpGSw==}
1792
+
1745
1793
  oniguruma-parser@0.12.2:
1746
1794
  resolution: {integrity: sha512-6HVa5oIrgMC6aA6WF6XyyqbhRPJrKR02L20+2+zpDtO5QAzGHAUGw5TKQvwi5vctNnRHkJYmjAhRVQF2EKdTQw==}
1747
1795
 
@@ -1772,12 +1820,14 @@ packages:
1772
1820
  resolution: {integrity: sha512-AxTM2wDGORHGEkPCt8yqxOTMgpfbEHqF51f/5fJCmwFC3C/zNcGT63SymH2ttOAaiIws2zVg4+izQCjrakcwHg==}
1773
1821
  engines: {node: '>=20'}
1774
1822
 
1823
+ p5@2.3.1:
1824
+ resolution: {integrity: sha512-YOzt3oP+xagNKtCiOfXK6EaEi4i7F4+5MNGFPUu6/yEJ1QhIsZQl1Tp/uYFNldi3Y0Uwmre997Ke0vDoFwBFBw==}
1825
+
1775
1826
  package-manager-detector@1.8.0:
1776
1827
  resolution: {integrity: sha512-yQA4H19AmPEoMUeavPMDIe1higySl/gH/yaQrkT/s07Qp+7pp2hYz30N3z2l5BkjVkF9Ow6o0wjJamm2y7Sn0A==}
1777
1828
 
1778
- paper@0.12.18:
1779
- resolution: {integrity: sha512-ZSLIEejQTJZuYHhSSqAf4jXOnii0kPhCJGAnYAANtdS72aNwXJ9cP95tZHgq1tnNpvEwgQhggy+4OarviqTCGw==}
1780
- engines: {node: '>=8.0.0'}
1829
+ pako@2.2.0:
1830
+ resolution: {integrity: sha512-zJq6RP/5q+TO2OpFV3FHzlPnFjmkb7Nc99a5SNjJE+uu/PkpChs+NIZSSzbBoD+6kjiISXjfYdwj1ZRQ81dz/w==}
1781
1831
 
1782
1832
  parse5@7.3.0:
1783
1833
  resolution: {integrity: sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==}
@@ -1993,6 +2043,10 @@ packages:
1993
2043
  resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==}
1994
2044
  engines: {node: '>=0.10.0'}
1995
2045
 
2046
+ source-map@0.6.1:
2047
+ resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==}
2048
+ engines: {node: '>=0.10.0'}
2049
+
1996
2050
  space-separated-tokens@2.0.2:
1997
2051
  resolution: {integrity: sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==}
1998
2052
 
@@ -2530,6 +2584,8 @@ snapshots:
2530
2584
  dependencies:
2531
2585
  '@babel/types': 7.29.7
2532
2586
 
2587
+ '@babel/runtime@7.29.7': {}
2588
+
2533
2589
  '@babel/types@7.29.7':
2534
2590
  dependencies:
2535
2591
  '@babel/helper-string-parser': 7.29.7
@@ -2582,6 +2638,8 @@ snapshots:
2582
2638
  fast-wrap-ansi: 0.2.2
2583
2639
  sisteransi: 1.0.5
2584
2640
 
2641
+ '@davepagurek/bezier-path@0.0.7': {}
2642
+
2585
2643
  '@emmetio/abbreviation@2.3.3':
2586
2644
  dependencies:
2587
2645
  '@emmetio/scanner': 1.0.4
@@ -2857,6 +2915,8 @@ snapshots:
2857
2915
  '@img/sharp-win32-x64@0.35.3':
2858
2916
  optional: true
2859
2917
 
2918
+ '@japont/unicode-range@1.0.0': {}
2919
+
2860
2920
  '@jridgewell/gen-mapping@0.3.13':
2861
2921
  dependencies:
2862
2922
  '@jridgewell/sourcemap-codec': 1.5.5
@@ -3228,6 +3288,10 @@ snapshots:
3228
3288
  dependencies:
3229
3289
  acorn: 8.17.0
3230
3290
 
3291
+ acorn-walk@8.3.5:
3292
+ dependencies:
3293
+ acorn: 8.17.0
3294
+
3231
3295
  acorn@8.17.0: {}
3232
3296
 
3233
3297
  ajv-draft-04@1.0.0(ajv@8.20.0):
@@ -3421,6 +3485,8 @@ snapshots:
3421
3485
 
3422
3486
  color-name@1.1.4: {}
3423
3487
 
3488
+ colorjs.io@0.6.1: {}
3489
+
3424
3490
  comma-separated-tokens@2.0.3: {}
3425
3491
 
3426
3492
  commander@11.1.0: {}
@@ -3560,6 +3626,14 @@ snapshots:
3560
3626
 
3561
3627
  escape-string-regexp@4.0.0: {}
3562
3628
 
3629
+ escodegen@2.1.0:
3630
+ dependencies:
3631
+ esprima: 4.0.1
3632
+ estraverse: 5.3.0
3633
+ esutils: 2.0.3
3634
+ optionalDependencies:
3635
+ source-map: 0.6.1
3636
+
3563
3637
  eslint-plugin-astro@3.0.1(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.1)(@typescript-eslint/parser@8.65.0(eslint@10.8.0(jiti@2.7.0))(typescript@5.9.3))(eslint@10.8.0(jiti@2.7.0)):
3564
3638
  dependencies:
3565
3639
  '@eslint-community/eslint-utils': 4.10.1(eslint@10.8.0(jiti@2.7.0))
@@ -3632,6 +3706,8 @@ snapshots:
3632
3706
  acorn-jsx: 5.3.2(acorn@8.17.0)
3633
3707
  eslint-visitor-keys: 5.0.1
3634
3708
 
3709
+ esprima@4.0.1: {}
3710
+
3635
3711
  esquery@1.7.0:
3636
3712
  dependencies:
3637
3713
  estraverse: 5.3.0
@@ -3707,6 +3783,8 @@ snapshots:
3707
3783
  dependencies:
3708
3784
  resolve-pkg-maps: 1.0.0
3709
3785
 
3786
+ gifenc@1.0.3: {}
3787
+
3710
3788
  github-slugger@2.0.0: {}
3711
3789
 
3712
3790
  glob-parent@6.0.2:
@@ -3787,6 +3865,14 @@ snapshots:
3787
3865
 
3788
3866
  http-cache-semantics@4.2.0: {}
3789
3867
 
3868
+ i18next-browser-languagedetector@4.3.1:
3869
+ dependencies:
3870
+ '@babel/runtime': 7.29.7
3871
+
3872
+ i18next@19.9.2:
3873
+ dependencies:
3874
+ '@babel/runtime': 7.29.7
3875
+
3790
3876
  ignore@5.3.2: {}
3791
3877
 
3792
3878
  ignore@7.0.6: {}
@@ -3840,6 +3926,8 @@ snapshots:
3840
3926
  prelude-ls: 1.2.1
3841
3927
  type-check: 0.4.0
3842
3928
 
3929
+ libtess@1.2.2: {}
3930
+
3843
3931
  lightningcss-android-arm64@1.32.0:
3844
3932
  optional: true
3845
3933
 
@@ -4025,8 +4113,12 @@ snapshots:
4025
4113
  node-fetch-native: 1.6.7
4026
4114
  ufo: 1.6.4
4027
4115
 
4116
+ ogl@1.0.11: {}
4117
+
4028
4118
  ohash@2.0.11: {}
4029
4119
 
4120
+ omggif@1.0.10: {}
4121
+
4030
4122
  oniguruma-parser@0.12.2: {}
4031
4123
 
4032
4124
  oniguruma-to-es@4.3.6:
@@ -4063,9 +4155,25 @@ snapshots:
4063
4155
 
4064
4156
  p-timeout@7.0.1: {}
4065
4157
 
4158
+ p5@2.3.1:
4159
+ dependencies:
4160
+ '@davepagurek/bezier-path': 0.0.7
4161
+ '@japont/unicode-range': 1.0.0
4162
+ acorn: 8.17.0
4163
+ acorn-walk: 8.3.5
4164
+ colorjs.io: 0.6.1
4165
+ escodegen: 2.1.0
4166
+ gifenc: 1.0.3
4167
+ i18next: 19.9.2
4168
+ i18next-browser-languagedetector: 4.3.1
4169
+ libtess: 1.2.2
4170
+ omggif: 1.0.10
4171
+ pako: 2.2.0
4172
+ zod: 4.4.3
4173
+
4066
4174
  package-manager-detector@1.8.0: {}
4067
4175
 
4068
- paper@0.12.18: {}
4176
+ pako@2.2.0: {}
4069
4177
 
4070
4178
  parse5@7.3.0:
4071
4179
  dependencies:
@@ -4256,6 +4364,9 @@ snapshots:
4256
4364
 
4257
4365
  source-map-js@1.2.1: {}
4258
4366
 
4367
+ source-map@0.6.1:
4368
+ optional: true
4369
+
4259
4370
  space-separated-tokens@2.0.2: {}
4260
4371
 
4261
4372
  split-type@0.3.4: {}
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: hedgehog-bootstrap-landing-page-core
3
- description: Use once, at the start of a new Hedgehog project on the landing-page core, to land the pre-verified Astro + Tailwind workspace and verify it's green. Runs as the only move of the `bootstrap` agent on this core — there are no add-on steps, unlike full-stack-app. Invoked automatically by `planner` after Confirm & Lock.
3
+ description: Use once, at the start of a new Hedgehog project on the landing-page core, to land the pre-verified Astro + Tailwind v4 workspace and verify it's green. Runs as the only move of the `bootstrap` agent on this core — there are no add-on steps, unlike full-stack-app. Invoked automatically by `planner` after Confirm & Lock.
4
4
  ---
5
5
 
6
6
  # Hedgehog Bootstrap — landing-page Core
@@ -9,8 +9,9 @@ Lands the whole of a `landing-page` project's workspace — there's no
9
9
  add-on layer to run after it, unlike `full-stack-app`'s
10
10
  `hedgehog-bootstrap` — by copying a pre-built, pre-verified workspace
11
11
  (`src/golden-cores/landing-page/` in the Hedgehog package) rather than
12
- generating it live: Astro workspace, Tailwind token-layer config, the
13
- library set this core is built on (GSAP, Lenis, SplitType, Paper.js).
12
+ generating it live: Astro workspace, Tailwind v4 CSS-first token-layer
13
+ config, the library set this core is built on (GSAP, Lenis, SplitType,
14
+ p5.js, ogl).
14
15
  This piece is deterministic — the same commands produce the same output
15
16
  on every project — so the output is committed once, upstream, and copied
16
17
  here instead of re-derived by an agent on every run.
@@ -27,17 +28,15 @@ Hedgehog package, copied to the repo root:
27
28
  - Root: `astro.config.mjs`, `package.json` (with the `dev` script —
28
29
  `astro dev` — and every library in the stack pinned), `tsconfig.json`,
29
30
  `eslint.config.mjs`, `.prettierrc.js`, `.gitignore`, `pnpm-lock.yaml`.
30
- - `tailwind.config.ts` — the token layer only: no component classes, no
31
- plugin beyond the base. Ships with placeholder tokens (a neutral
32
- starting palette, a system type stack, a 4px spacing unit) that
33
- `landing-systems` overwrites at its own phase — this file existing and
34
- being wired into the build is what core guarantees, not any specific
35
- token values.
36
31
  - `src/pages/index.astro` — a minimal placeholder page (proves the build
37
32
  pipeline works end to end), replaced by `landing-builder`'s own output
38
33
  at the build phase.
39
- - `src/styles/global.css` — the Tailwind import and CSS custom-property
40
- scaffold `landing-systems`'s token system writes into.
34
+ - `src/styles/global.css` — the Tailwind v4 CSS-first import and the
35
+ `@theme` token block: no component classes, no plugin beyond the base.
36
+ Ships with placeholder tokens (a neutral starting palette, a system
37
+ type stack, a 4px spacing unit) that `landing-systems` overwrites
38
+ entirely at its own phase — this block existing and being wired into
39
+ the build is what core guarantees, not any specific token values.
41
40
  - `src/sections/`, `src/motifs/` — empty, with a `.gitkeep`; real content
42
41
  starts at the systems and build phases.
43
42
 
@@ -125,13 +124,6 @@ like an unnecessary pin.
125
124
  root. All four are stripped before syncing — they'd otherwise collide
126
125
  with (or silently shadow) the project's real root `CLAUDE.md` and
127
126
  Hedgehog's own workspace conventions.
128
- - **MorphSVGPlugin ships inside the `gsap` package itself** — no
129
- separate install, no Club GreenSock membership, no private registry.
130
- GreenSock made every plugin free when GSAP joined Webflow in 2024.
131
- Import it as `import { MorphSVGPlugin } from 'gsap/MorphSVGPlugin'`
132
- directly from the `gsap` dependency already in `package.json`. Don't
133
- reintroduce a separate paid-plugin workaround if this comes up again —
134
- verify current licensing against gsap.com before assuming otherwise.
135
127
 
136
128
  ## If verification fails
137
129
 
@@ -182,9 +182,6 @@ Lock has held and its commit has landed. If not, stop and ask.
182
182
  - **The Critic's veto is real.** `landing-critic` can send any phase back
183
183
  to its owning agent, citing which audit failed; it cannot rewrite the
184
184
  artifact itself.
185
- - **Figma/Stitch MCP output is input only.** Anything handed off from
186
- those tools is re-derived through the token system (phase 6) before it
187
- touches Tailwind config — never copied through as final values.
188
185
 
189
186
  ## Core Reference Points
190
187
 
@@ -0,0 +1,127 @@
1
+ ---
2
+ name: motif-authoring
3
+ description: Use whenever `landing-systems` authors the signature motif (Chain Method step 6, `hedgehog-landing-loop`) or `landing-builder` implements one from `src/motifs/`. Trigger on "draw the motif", "author the motif", "write src/motifs/". Picks the right construction technique — p5.js, CSS, or Canvas 2D — per motif type, and gives the technique for producing each without hand-typed coordinate guessing.
4
+ ---
5
+
6
+ # Motif Authoring
7
+
8
+ A motif is constructed from a formula or a measurement, never a
9
+ hand-typed coordinate. Freehand numeric coordinates — a bezier control
10
+ point, a magic pixel offset — are unreadable as numbers: there's no way
11
+ to tell what a shape looks like from its raw values while writing them,
12
+ so hand-typed geometry drifts into lumpy, asymmetric, or misaligned
13
+ results that read as generic rather than the sourced, deliberate motif
14
+ step 6 specifies.
15
+
16
+ ## Pick the technique from the motif type
17
+
18
+ `landing-systems` step 6 names the motif's source, persistence,
19
+ continuity, scale range, and literalness. That spec determines which of
20
+ three techniques applies — pick one, don't mix by default:
21
+
22
+ 1. **Organic / generative** (a material's grain, a growth pattern, a
23
+ natural form that evolves) → **p5.js**. Write the motif as a rule —
24
+ noise, jitter, growth, a formula-driven point set — not a curve typed
25
+ out point by point. The generator is legible and adjustable; a
26
+ hand-typed curve is neither.
27
+ 2. **Static geometric** (a spine, a chevron, a blob, a simple silhouette
28
+ that doesn't need to evolve) → **CSS** (`clip-path`, gradients,
29
+ `border-radius`). Build the shape from `clip-path` polygon/shape
30
+ functions, layered gradients, or `border-radius` percentage strings —
31
+ values you can reason about exactly, animatable directly by GSAP
32
+ (e.g. tweening a `border-radius` string in place of shape morphing).
33
+ 3. **Measured / connective** (a thread, a line, a connector that must
34
+ align to real element positions across the page) → **Canvas 2D with
35
+ computed coordinates**. Measure the actual DOM positions
36
+ (`getBoundingClientRect` or equivalent) at draw time and derive the
37
+ path from those measured values — never an eyeballed or imagined
38
+ coordinate.
39
+
40
+ ## The rule within each technique
41
+
42
+ **Never hand-write multi-point geometry as raw guessed numbers**, in any
43
+ of the three:
44
+
45
+ - **p5.js** — construct from a formula (sine-based waveform, noise
46
+ function, L-system, Voronoi cell, particle rule) with named parameters,
47
+ not a manually plotted point list. Express motif variation
48
+ (augmentation/inversion/retrograde, per `landing-systems` step 6's
49
+ music-theory vocabulary) as parameter changes on the same generator,
50
+ not a hand-edited copy.
51
+ - Use **instance mode** (`new p5(sketch, container)`), not global mode
52
+ — a global-mode sketch leaks `setup`/`draw`/every p5 function onto
53
+ `window`, which collides with Astro's own module scope and with
54
+ GSAP/ScrollTrigger's own render loop running on the same page.
55
+ - Seed every source of randomness explicitly —
56
+ `p.randomSeed(seed); p.noiseSeed(seed);` — with a fixed, committed
57
+ seed value. This is what makes "derive from a formula" mean anything
58
+ in practice: the same seed must always reproduce the exact same
59
+ motif, so a reviewer (or `landing-critic`) can re-run it and get the
60
+ committed result, not a fresh roll.
61
+ - Collect the formula's inputs (particle count, noise scale, growth
62
+ rate, angle — whatever the generator exposes) into one named
63
+ `params` object at the top of the sketch, not scattered magic
64
+ numbers through `draw()`. This is the same object the "state the
65
+ parameters and what each one is for" verification step below reads
66
+ from — an ungrouped generator is harder to audit, not just harder to
67
+ read.
68
+ - Mount inside a `client:*` island only where the sequencer's beat
69
+ structure actually calls for the motif to animate; a motif that's
70
+ static per section doesn't need a live p5 instance at all — render
71
+ once and let CSS/GSAP handle any transform-level movement instead.
72
+ - **CSS** — build from `clip-path`'s named shape functions
73
+ (`polygon()`, `circle()`, `ellipse()`, `inset()` with rounded corners)
74
+ or `border-radius`'s percentage syntax, composed via layering and
75
+ transforms (rotate, scale, translate) rather than freehand
76
+ percentages guessed to "look right."
77
+ - **Canvas 2D** — derive every coordinate from a measurement (a DOM
78
+ element's rect, a computed grid position, a formula applied to those
79
+ measurements) — never a literal pixel value typed from eyeballing the
80
+ page.
81
+
82
+ ## Verifying a motif before committing it
83
+
84
+ A motif is not correct because it compiles. Before writing it into
85
+ `src/motifs/` and handing off:
86
+
87
+ - **Render it and look.** Use the Bash tool to run the dev server or a
88
+ standalone preview and view the actual output — don't judge geometry
89
+ or a Canvas draw call from the source alone.
90
+ - **State the construction's parameters and what each one is for** — a
91
+ p5.js formula's inputs, a `clip-path` shape's control values, a Canvas
92
+ draw's measured inputs — before accepting it. If you can't say why a
93
+ value is what it is, it was guessed, not authored — redo it via the
94
+ technique's proper primitives.
95
+ - **For p5.js, confirm the seed is fixed and committed**, not left to
96
+ default/time-based randomness — re-running the sketch must reproduce
97
+ the exact motif that was reviewed, not a new variation each load.
98
+ - **Check symmetry/proportion deliberately** where the source motif
99
+ implies it (step 6's "literalness" and "scale range" fields).
100
+ - **Prefer fewer parameters.** A motif with 4 deliberate formula inputs
101
+ or shape values reads as designed; one with 20 guessed numbers reads as
102
+ noise, regardless of what it depicts.
103
+
104
+ ## Constraints
105
+
106
+ - This skill governs *how* the motif is constructed, not *what* it is —
107
+ the source, persistence, continuity, scale range, and literalness are
108
+ `landing-systems` step 6's decisions (see `landing-systems.md`); this
109
+ skill only prevents the geometry itself from being guessed.
110
+ - Don't reach for an icon library or stock asset as a shortcut around
111
+ hard geometry — `landing-systems`'s existing constraint against generic
112
+ decoration still applies. A hard-to-construct motif is a signal to
113
+ simplify the formula or measurement, not to substitute a decorative
114
+ asset.
115
+ - **Never hand-write an SVG `<path d="...">` with freehand bezier
116
+ coordinates**, even as a fallback when none of the three techniques
117
+ above feels like a clean fit. Bezier control points typed as raw
118
+ numbers are unreadable — there's no way to tell what a curve looks
119
+ like from its `d` string while writing it, so hand-typed paths drift
120
+ into lumpy, asymmetric, or self-intersecting geometry regardless of
121
+ how carefully they're written. If a motif genuinely doesn't fit p5.js,
122
+ CSS, or Canvas 2D, that's a signal to reconsider the motif's source or
123
+ literalness with `landing-systems` — not a reason to fall back to
124
+ hand-authored SVG.
125
+ - `landing-builder` implements the motif exactly as authored here — a
126
+ motif that's hard to render cleanly should be fixed at this step, not
127
+ smoothed over during build.
@@ -65,23 +65,29 @@ edited after a phase closes.
65
65
  ### Stack (locked, every project — no add-ons on this core)
66
66
 
67
67
  **Astro** (zero-JS-by-default shell, islands only where interaction is
68
- genuinely needed) · **Tailwind** (config as token layer only — no
69
- component library on top) · **GSAP + ScrollTrigger** (primary animation
70
- engine; owns Sequencer pacing and top/heart/base fade timing) ·
71
- **Lenis** (smooth-scroll feel) · **SVG-first** (hand-authored graphics
72
- for the motif no icon library or generator look) · **SplitType**
73
- (line/word/char copy-reveal splitting) · **Paper.js** (canvas vector
74
- work for a motif that evolves across sections) · **MorphSVGPlugin**
75
- (GSAP for a motif that physically transforms across sections) ·
76
- **custom SVG noise/grain filter** (cheap materiality/texture layer) ·
77
- **React Three Fiber** (rare only when the subject is genuinely
78
- spatial; default is to skip it).
68
+ genuinely needed) · **Tailwind v4, CSS-first** (config as token layer
69
+ only — no component library on top) · **GSAP + ScrollTrigger**, scoped to
70
+ CSS/transform targets only, no plugins (primary animation engine; owns
71
+ Sequencer pacing and top/heart/base fade timing) · **Lenis** (smooth-
72
+ scroll feel, the "weight and suspension" dial) · **SplitType**
73
+ (line/word/char copy-reveal splitting) · **p5.js** (organic/generative
74
+ motifs described as a rule: noise, jitter, growth not hand-typed path
75
+ data) · **CSS `clip-path` / gradients / `border-radius`** (static
76
+ geometric motifs spines, chevrons, blobs GSAP-animatable directly,
77
+ zero coordinate-guessing risk) · **Canvas 2D with computed coordinates**
78
+ (measured/connective motifs threads/lines that align to real DOM
79
+ positions, drawn from measured values) · **`ogl`** (lightweight WebGL) or
80
+ a raw shader (a continuous background field spanning the full page
81
+ height, so sections read as windows onto one surface) · **CSS
82
+ `clip-path` irregular edges + `mix-blend-mode` overlap + negative-margin
83
+ overlap** (section boundary treatment — breaks the hard horizontal seam
84
+ between sections without a new dependency) · **CSS `mask-image` + noise
85
+ pattern** (texture/grain layer) · **React Three Fiber** (rare — only when
86
+ the subject is genuinely spatial; default is to skip it).
79
87
 
80
- Figma MCP / Stitch MCP are handoff/input tools only, used at the
81
- Strategist/Builder boundaries never allowed to set spacing or style
82
- defaults directly. Anything they hand off is re-derived through the
83
- Systems Designer's token system (step 5) before it touches Tailwind
84
- config.
88
+ This core has no design-handoff tool. All visual decisions are derived
89
+ directly through the Systems Designer's token system (step 5) and the
90
+ motif techniques above never imported from an external design file.
85
91
 
86
92
  Don't substitute libraries. If a package name changed upstream, verify
87
93
  against current docs before running — don't swap in a different one, and
@@ -90,16 +96,22 @@ above doesn't cover; that gap is a signal to go back to the Ingredient
90
96
  Vocabulary and derive the right choice, not to default to something
91
97
  off-the-shelf.
92
98
 
99
+ Motifs are always constructed from a formula or a measurement, never
100
+ hand-typed coordinates: an organic motif is a p5.js rule (noise, jitter,
101
+ growth), a static geometric motif is CSS (`clip-path`, gradients,
102
+ `border-radius`), and a measured/connective motif is Canvas 2D drawn from
103
+ real DOM positions. See the `motif-authoring` skill for the technique
104
+ per motif type.
105
+
93
106
  ### Layout
94
107
 
95
108
  ```
96
109
  astro.config.mjs Astro workspace root
97
- tailwind.config.ts token layer only — hex values, type roles, spacing unit, easing family from Step 5
98
110
  src/
99
111
  pages/ one file per page (usually just index.astro)
100
112
  sections/ one component per page section, in Sequencer order
101
- motifs/ the signature SVG/Paper.js motif + its variation rules
102
- styles/ global.css — Tailwind import + CSS variable theme
113
+ motifs/ the signature motif (p5.js / CSS / Canvas 2D) + its variation rules
114
+ styles/ global.css — Tailwind v4 CSS-first import + the `@theme` token layer (hex values, type roles, spacing unit, easing family from Step 5)
103
115
  .hedgehog/
104
116
  BMAD/ vendored BMAD-METHOD shelf's raw output (brief, PR-FAQ, PRD, UX spec, research) —
105
117
  write-once, from planner