diff --git a/.gitignore b/.gitignore
index 0ac0170..71788d6 100644
--- a/.gitignore
+++ b/.gitignore
@@ -6,3 +6,9 @@ dist/
# bad design-audit run artifacts (regenerable)
audit-results/
+
+# generated art: raw fal/FLUX output stays out of git (archive: company/gtm/execution-plans/assets/tangle-website-rebuild/raw-art)
+public/images/agents/**/*.png
+public/images/agents/bases/
+public/images/agents/forged/
+public/images/brand/backgrounds/*.png
diff --git a/package.json b/package.json
index 4ab01b2..e164fcd 100644
--- a/package.json
+++ b/package.json
@@ -37,6 +37,7 @@
"react": "^19.2.4",
"react-dom": "^19.2.4",
"tailwindcss": "^4.2.1",
+ "three": "^0.185.1",
"wrangler": "^4.74.0"
},
"devDependencies": {
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index ffc4c5f..1818ea3 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -56,6 +56,9 @@ importers:
tailwindcss:
specifier: ^4.2.1
version: 4.2.2
+ three:
+ specifier: ^0.185.1
+ version: 0.185.1
wrangler:
specifier: ^4.74.0
version: 4.76.0
@@ -2254,6 +2257,9 @@ packages:
resolution: {integrity: sha512-g9ljZiwki/LfxmQADO3dEY1CbpmXT5Hm2fJ+QaGKwSXUylMybePR7/67YW7jOrrvjEgL1Fmz5kzyAjWVWLlucg==}
engines: {node: '>=6'}
+ three@0.185.1:
+ resolution: {integrity: sha512-5aojFCXKwnjBRZvUnt3WFfEcvUJgkN5LlijRFN95hMy8WVkG4I0QNcJE+OuWvuJ0bOdStrbfXn0pkd6/QyiAlg==}
+
tiny-inflate@1.0.3:
resolution: {integrity: sha512-pkY1fj1cKHb2seWDy0B16HeWyczlJA9/WW3u3c4z/NiWDsO3DOU5D7nhTLE9CF0yXv/QZFY7sEJmj24dK+Rrqw==}
@@ -5100,6 +5106,8 @@ snapshots:
tapable@2.3.0: {}
+ three@0.185.1: {}
+
tiny-inflate@1.0.3: {}
tinyclip@0.1.12: {}
diff --git a/public/images/agents/common-01.webp b/public/images/agents/common-01.webp
new file mode 100644
index 0000000..0af4012
Binary files /dev/null and b/public/images/agents/common-01.webp differ
diff --git a/public/images/agents/common-02.webp b/public/images/agents/common-02.webp
new file mode 100644
index 0000000..f5b1985
Binary files /dev/null and b/public/images/agents/common-02.webp differ
diff --git a/public/images/agents/common-03.webp b/public/images/agents/common-03.webp
new file mode 100644
index 0000000..a143d7d
Binary files /dev/null and b/public/images/agents/common-03.webp differ
diff --git a/public/images/agents/crystal-bot-01.webp b/public/images/agents/crystal-bot-01.webp
new file mode 100644
index 0000000..490beff
Binary files /dev/null and b/public/images/agents/crystal-bot-01.webp differ
diff --git a/public/images/agents/crystal-bot-02.webp b/public/images/agents/crystal-bot-02.webp
new file mode 100644
index 0000000..0907777
Binary files /dev/null and b/public/images/agents/crystal-bot-02.webp differ
diff --git a/public/images/agents/crystal-bot-03.webp b/public/images/agents/crystal-bot-03.webp
new file mode 100644
index 0000000..22d0d72
Binary files /dev/null and b/public/images/agents/crystal-bot-03.webp differ
diff --git a/public/images/agents/crystal-v2-01.webp b/public/images/agents/crystal-v2-01.webp
new file mode 100644
index 0000000..6cc48d9
Binary files /dev/null and b/public/images/agents/crystal-v2-01.webp differ
diff --git a/public/images/agents/crystal-v2-02.webp b/public/images/agents/crystal-v2-02.webp
new file mode 100644
index 0000000..97db6bf
Binary files /dev/null and b/public/images/agents/crystal-v2-02.webp differ
diff --git a/public/images/agents/crystal-v2-03.webp b/public/images/agents/crystal-v2-03.webp
new file mode 100644
index 0000000..e721693
Binary files /dev/null and b/public/images/agents/crystal-v2-03.webp differ
diff --git a/public/images/agents/crystal-var-01.webp b/public/images/agents/crystal-var-01.webp
new file mode 100644
index 0000000..98bd479
Binary files /dev/null and b/public/images/agents/crystal-var-01.webp differ
diff --git a/public/images/agents/crystal-var-02.webp b/public/images/agents/crystal-var-02.webp
new file mode 100644
index 0000000..7336cf0
Binary files /dev/null and b/public/images/agents/crystal-var-02.webp differ
diff --git a/public/images/agents/crystal-var-03.webp b/public/images/agents/crystal-var-03.webp
new file mode 100644
index 0000000..d4de6e0
Binary files /dev/null and b/public/images/agents/crystal-var-03.webp differ
diff --git a/public/images/agents/epic-01.webp b/public/images/agents/epic-01.webp
new file mode 100644
index 0000000..02afbc5
Binary files /dev/null and b/public/images/agents/epic-01.webp differ
diff --git a/public/images/agents/epic-02.webp b/public/images/agents/epic-02.webp
new file mode 100644
index 0000000..6e1b1e0
Binary files /dev/null and b/public/images/agents/epic-02.webp differ
diff --git a/public/images/agents/epic-03.webp b/public/images/agents/epic-03.webp
new file mode 100644
index 0000000..fbbe918
Binary files /dev/null and b/public/images/agents/epic-03.webp differ
diff --git a/public/images/agents/evolve/matte-v2-01-s1.webp b/public/images/agents/evolve/matte-v2-01-s1.webp
new file mode 100644
index 0000000..1d9b122
Binary files /dev/null and b/public/images/agents/evolve/matte-v2-01-s1.webp differ
diff --git a/public/images/agents/evolve/matte-v2-01-s2.webp b/public/images/agents/evolve/matte-v2-01-s2.webp
new file mode 100644
index 0000000..d962e95
Binary files /dev/null and b/public/images/agents/evolve/matte-v2-01-s2.webp differ
diff --git a/public/images/agents/matte-bot-01.webp b/public/images/agents/matte-bot-01.webp
new file mode 100644
index 0000000..9d4c128
Binary files /dev/null and b/public/images/agents/matte-bot-01.webp differ
diff --git a/public/images/agents/matte-bot-02.webp b/public/images/agents/matte-bot-02.webp
new file mode 100644
index 0000000..1307516
Binary files /dev/null and b/public/images/agents/matte-bot-02.webp differ
diff --git a/public/images/agents/matte-bot-03.webp b/public/images/agents/matte-bot-03.webp
new file mode 100644
index 0000000..be0fd32
Binary files /dev/null and b/public/images/agents/matte-bot-03.webp differ
diff --git a/public/images/agents/matte-v2-01.webp b/public/images/agents/matte-v2-01.webp
new file mode 100644
index 0000000..074f218
Binary files /dev/null and b/public/images/agents/matte-v2-01.webp differ
diff --git a/public/images/agents/matte-v2-02.webp b/public/images/agents/matte-v2-02.webp
new file mode 100644
index 0000000..c1f75a2
Binary files /dev/null and b/public/images/agents/matte-v2-02.webp differ
diff --git a/public/images/agents/matte-v2-03.webp b/public/images/agents/matte-v2-03.webp
new file mode 100644
index 0000000..45f715b
Binary files /dev/null and b/public/images/agents/matte-v2-03.webp differ
diff --git a/public/images/agents/matte-var-01.webp b/public/images/agents/matte-var-01.webp
new file mode 100644
index 0000000..ae4cd32
Binary files /dev/null and b/public/images/agents/matte-var-01.webp differ
diff --git a/public/images/agents/matte-var-02.webp b/public/images/agents/matte-var-02.webp
new file mode 100644
index 0000000..30a882c
Binary files /dev/null and b/public/images/agents/matte-var-02.webp differ
diff --git a/public/images/agents/matte-var-03.webp b/public/images/agents/matte-var-03.webp
new file mode 100644
index 0000000..072134e
Binary files /dev/null and b/public/images/agents/matte-var-03.webp differ
diff --git a/public/images/agents/rare-01.webp b/public/images/agents/rare-01.webp
new file mode 100644
index 0000000..7a2f82b
Binary files /dev/null and b/public/images/agents/rare-01.webp differ
diff --git a/public/images/agents/rare-02.webp b/public/images/agents/rare-02.webp
new file mode 100644
index 0000000..973aba5
Binary files /dev/null and b/public/images/agents/rare-02.webp differ
diff --git a/public/images/agents/rare-03.webp b/public/images/agents/rare-03.webp
new file mode 100644
index 0000000..fb0443b
Binary files /dev/null and b/public/images/agents/rare-03.webp differ
diff --git a/public/images/agents/woven-bot-01.webp b/public/images/agents/woven-bot-01.webp
new file mode 100644
index 0000000..ddd3c13
Binary files /dev/null and b/public/images/agents/woven-bot-01.webp differ
diff --git a/public/images/agents/woven-bot-02.webp b/public/images/agents/woven-bot-02.webp
new file mode 100644
index 0000000..fc1c4cd
Binary files /dev/null and b/public/images/agents/woven-bot-02.webp differ
diff --git a/public/images/agents/woven-bot-03.webp b/public/images/agents/woven-bot-03.webp
new file mode 100644
index 0000000..8245169
Binary files /dev/null and b/public/images/agents/woven-bot-03.webp differ
diff --git a/public/images/art-review/01-hero-v2-01.webp b/public/images/art-review/01-hero-v2-01.webp
new file mode 100644
index 0000000..8f385aa
Binary files /dev/null and b/public/images/art-review/01-hero-v2-01.webp differ
diff --git a/public/images/art-review/02-hero-v2-02.webp b/public/images/art-review/02-hero-v2-02.webp
new file mode 100644
index 0000000..050a66e
Binary files /dev/null and b/public/images/art-review/02-hero-v2-02.webp differ
diff --git a/public/images/art-review/03-hero-v2-03.webp b/public/images/art-review/03-hero-v2-03.webp
new file mode 100644
index 0000000..80709f0
Binary files /dev/null and b/public/images/art-review/03-hero-v2-03.webp differ
diff --git a/public/images/art-review/04-hero-v2-flux-01.webp b/public/images/art-review/04-hero-v2-flux-01.webp
new file mode 100644
index 0000000..9cfaa5b
Binary files /dev/null and b/public/images/art-review/04-hero-v2-flux-01.webp differ
diff --git a/public/images/art-review/05-hero-v2-flux-02.webp b/public/images/art-review/05-hero-v2-flux-02.webp
new file mode 100644
index 0000000..5602be3
Binary files /dev/null and b/public/images/art-review/05-hero-v2-flux-02.webp differ
diff --git a/public/images/art-review/06-card-sandbox-01.webp b/public/images/art-review/06-card-sandbox-01.webp
new file mode 100644
index 0000000..5af1e8c
Binary files /dev/null and b/public/images/art-review/06-card-sandbox-01.webp differ
diff --git a/public/images/art-review/07-card-sandbox-02.webp b/public/images/art-review/07-card-sandbox-02.webp
new file mode 100644
index 0000000..0019dbc
Binary files /dev/null and b/public/images/art-review/07-card-sandbox-02.webp differ
diff --git a/public/images/art-review/08-card-sandbox-flux-01.webp b/public/images/art-review/08-card-sandbox-flux-01.webp
new file mode 100644
index 0000000..a3826f6
Binary files /dev/null and b/public/images/art-review/08-card-sandbox-flux-01.webp differ
diff --git a/public/images/art-review/09-card-intelligence-01.webp b/public/images/art-review/09-card-intelligence-01.webp
new file mode 100644
index 0000000..079ef46
Binary files /dev/null and b/public/images/art-review/09-card-intelligence-01.webp differ
diff --git a/public/images/art-review/10-card-intelligence-02.webp b/public/images/art-review/10-card-intelligence-02.webp
new file mode 100644
index 0000000..3a48742
Binary files /dev/null and b/public/images/art-review/10-card-intelligence-02.webp differ
diff --git a/public/images/art-review/11-card-intelligence-flux-01.webp b/public/images/art-review/11-card-intelligence-flux-01.webp
new file mode 100644
index 0000000..9b58fcd
Binary files /dev/null and b/public/images/art-review/11-card-intelligence-flux-01.webp differ
diff --git a/public/images/art-review/12-card-inference-01.webp b/public/images/art-review/12-card-inference-01.webp
new file mode 100644
index 0000000..74dc29d
Binary files /dev/null and b/public/images/art-review/12-card-inference-01.webp differ
diff --git a/public/images/art-review/13-card-inference-02.webp b/public/images/art-review/13-card-inference-02.webp
new file mode 100644
index 0000000..7200a0f
Binary files /dev/null and b/public/images/art-review/13-card-inference-02.webp differ
diff --git a/public/images/art-review/14-card-inference-flux-01.webp b/public/images/art-review/14-card-inference-flux-01.webp
new file mode 100644
index 0000000..3e9553c
Binary files /dev/null and b/public/images/art-review/14-card-inference-flux-01.webp differ
diff --git a/public/images/art-review/15-optimize-flow-g-01.webp b/public/images/art-review/15-optimize-flow-g-01.webp
new file mode 100644
index 0000000..f4b7554
Binary files /dev/null and b/public/images/art-review/15-optimize-flow-g-01.webp differ
diff --git a/public/images/art-review/16-optimize-flow-g-02.webp b/public/images/art-review/16-optimize-flow-g-02.webp
new file mode 100644
index 0000000..9950388
Binary files /dev/null and b/public/images/art-review/16-optimize-flow-g-02.webp differ
diff --git a/public/images/art-review/17-optimize-flow-f-01.webp b/public/images/art-review/17-optimize-flow-f-01.webp
new file mode 100644
index 0000000..1593793
Binary files /dev/null and b/public/images/art-review/17-optimize-flow-f-01.webp differ
diff --git a/public/images/art-review/18-model-field-g-01.webp b/public/images/art-review/18-model-field-g-01.webp
new file mode 100644
index 0000000..bb22231
Binary files /dev/null and b/public/images/art-review/18-model-field-g-01.webp differ
diff --git a/public/images/art-review/19-model-field-g-02.webp b/public/images/art-review/19-model-field-g-02.webp
new file mode 100644
index 0000000..1cd9915
Binary files /dev/null and b/public/images/art-review/19-model-field-g-02.webp differ
diff --git a/public/images/art-review/20-model-field-f-01.webp b/public/images/art-review/20-model-field-f-01.webp
new file mode 100644
index 0000000..3b8191c
Binary files /dev/null and b/public/images/art-review/20-model-field-f-01.webp differ
diff --git a/public/images/art-review/21-research-desk-g-01.webp b/public/images/art-review/21-research-desk-g-01.webp
new file mode 100644
index 0000000..e516480
Binary files /dev/null and b/public/images/art-review/21-research-desk-g-01.webp differ
diff --git a/public/images/art-review/22-research-desk-g-02.webp b/public/images/art-review/22-research-desk-g-02.webp
new file mode 100644
index 0000000..1408095
Binary files /dev/null and b/public/images/art-review/22-research-desk-g-02.webp differ
diff --git a/public/images/art-review/23-research-desk-f-01.webp b/public/images/art-review/23-research-desk-f-01.webp
new file mode 100644
index 0000000..65dab38
Binary files /dev/null and b/public/images/art-review/23-research-desk-f-01.webp differ
diff --git a/public/images/art-review/24-hero-v3-g-01.webp b/public/images/art-review/24-hero-v3-g-01.webp
new file mode 100644
index 0000000..9c10327
Binary files /dev/null and b/public/images/art-review/24-hero-v3-g-01.webp differ
diff --git a/public/images/art-review/25-hero-v3-g-02.webp b/public/images/art-review/25-hero-v3-g-02.webp
new file mode 100644
index 0000000..cda5905
Binary files /dev/null and b/public/images/art-review/25-hero-v3-g-02.webp differ
diff --git a/public/images/art-review/26-hero-v3-f-01.webp b/public/images/art-review/26-hero-v3-f-01.webp
new file mode 100644
index 0000000..09a192f
Binary files /dev/null and b/public/images/art-review/26-hero-v3-f-01.webp differ
diff --git a/public/images/art-review/27-footer-strip-g-01.webp b/public/images/art-review/27-footer-strip-g-01.webp
new file mode 100644
index 0000000..ff34158
Binary files /dev/null and b/public/images/art-review/27-footer-strip-g-01.webp differ
diff --git a/public/images/art-review/28-footer-strip-g-02.webp b/public/images/art-review/28-footer-strip-g-02.webp
new file mode 100644
index 0000000..29f513b
Binary files /dev/null and b/public/images/art-review/28-footer-strip-g-02.webp differ
diff --git a/public/images/art-review/29-footer-strip-f-01.webp b/public/images/art-review/29-footer-strip-f-01.webp
new file mode 100644
index 0000000..23b531b
Binary files /dev/null and b/public/images/art-review/29-footer-strip-f-01.webp differ
diff --git a/public/images/brand/atmospheres/tangle-atmosphere-dark-01.webp b/public/images/brand/atmospheres/tangle-atmosphere-dark-01.webp
new file mode 100644
index 0000000..c590478
Binary files /dev/null and b/public/images/brand/atmospheres/tangle-atmosphere-dark-01.webp differ
diff --git a/public/images/brand/atmospheres/tangle-atmosphere-indigo-01.webp b/public/images/brand/atmospheres/tangle-atmosphere-indigo-01.webp
new file mode 100644
index 0000000..c69845f
Binary files /dev/null and b/public/images/brand/atmospheres/tangle-atmosphere-indigo-01.webp differ
diff --git a/public/images/brand/atmospheres/tangle-atmosphere-light-01.webp b/public/images/brand/atmospheres/tangle-atmosphere-light-01.webp
new file mode 100644
index 0000000..9430142
Binary files /dev/null and b/public/images/brand/atmospheres/tangle-atmosphere-light-01.webp differ
diff --git a/public/images/brand/atmospheres/tangle-atmosphere-trace-01.webp b/public/images/brand/atmospheres/tangle-atmosphere-trace-01.webp
new file mode 100644
index 0000000..08b519f
Binary files /dev/null and b/public/images/brand/atmospheres/tangle-atmosphere-trace-01.webp differ
diff --git a/public/images/brand/atmospheres/tangle-atmosphere-warm-01.webp b/public/images/brand/atmospheres/tangle-atmosphere-warm-01.webp
new file mode 100644
index 0000000..e86c09a
Binary files /dev/null and b/public/images/brand/atmospheres/tangle-atmosphere-warm-01.webp differ
diff --git a/public/images/brand/atmospheres/tangle-filament-alt-01.webp b/public/images/brand/atmospheres/tangle-filament-alt-01.webp
new file mode 100644
index 0000000..fe39d43
Binary files /dev/null and b/public/images/brand/atmospheres/tangle-filament-alt-01.webp differ
diff --git a/public/images/brand/atmospheres/tangle-filament-hero-01.webp b/public/images/brand/atmospheres/tangle-filament-hero-01.webp
new file mode 100644
index 0000000..cbd3d27
Binary files /dev/null and b/public/images/brand/atmospheres/tangle-filament-hero-01.webp differ
diff --git a/public/images/brand/atmospheres/tangle-paper-indigo-01.webp b/public/images/brand/atmospheres/tangle-paper-indigo-01.webp
new file mode 100644
index 0000000..3bcfd4d
Binary files /dev/null and b/public/images/brand/atmospheres/tangle-paper-indigo-01.webp differ
diff --git a/public/images/brand/atmospheres/tangle-wave-dark-01.webp b/public/images/brand/atmospheres/tangle-wave-dark-01.webp
new file mode 100644
index 0000000..a17007c
Binary files /dev/null and b/public/images/brand/atmospheres/tangle-wave-dark-01.webp differ
diff --git a/public/images/brand/atmospheres/tangle-wave-light-01.webp b/public/images/brand/atmospheres/tangle-wave-light-01.webp
new file mode 100644
index 0000000..17cacd7
Binary files /dev/null and b/public/images/brand/atmospheres/tangle-wave-light-01.webp differ
diff --git a/public/images/brand/atmospheres/tangle-wave-minimal-01.webp b/public/images/brand/atmospheres/tangle-wave-minimal-01.webp
new file mode 100644
index 0000000..66293c4
Binary files /dev/null and b/public/images/brand/atmospheres/tangle-wave-minimal-01.webp differ
diff --git a/public/images/brand/atmospheres/tangle-wave-trace-01.webp b/public/images/brand/atmospheres/tangle-wave-trace-01.webp
new file mode 100644
index 0000000..f4a1a79
Binary files /dev/null and b/public/images/brand/atmospheres/tangle-wave-trace-01.webp differ
diff --git a/public/images/brand/atmospheres/tangle-wave-warm-01.webp b/public/images/brand/atmospheres/tangle-wave-warm-01.webp
new file mode 100644
index 0000000..b90232d
Binary files /dev/null and b/public/images/brand/atmospheres/tangle-wave-warm-01.webp differ
diff --git a/public/images/brand/backgrounds/cosmic-vista-01.webp b/public/images/brand/backgrounds/cosmic-vista-01.webp
new file mode 100644
index 0000000..e208c06
Binary files /dev/null and b/public/images/brand/backgrounds/cosmic-vista-01.webp differ
diff --git a/public/images/brand/cards/card-inference.webp b/public/images/brand/cards/card-inference.webp
new file mode 100644
index 0000000..de056e7
Binary files /dev/null and b/public/images/brand/cards/card-inference.webp differ
diff --git a/public/images/brand/cards/card-intelligence.webp b/public/images/brand/cards/card-intelligence.webp
new file mode 100644
index 0000000..53d3192
Binary files /dev/null and b/public/images/brand/cards/card-intelligence.webp differ
diff --git a/public/images/brand/cards/card-sandbox.webp b/public/images/brand/cards/card-sandbox.webp
new file mode 100644
index 0000000..74c6958
Binary files /dev/null and b/public/images/brand/cards/card-sandbox.webp differ
diff --git a/public/images/brand/knot-poster.webp b/public/images/brand/knot-poster.webp
new file mode 100644
index 0000000..a663ea9
Binary files /dev/null and b/public/images/brand/knot-poster.webp differ
diff --git a/public/images/brand/picks/cube-07.webp b/public/images/brand/picks/cube-07.webp
new file mode 100644
index 0000000..0019dbc
Binary files /dev/null and b/public/images/brand/picks/cube-07.webp differ
diff --git a/public/images/brand/picks/cube-08.webp b/public/images/brand/picks/cube-08.webp
new file mode 100644
index 0000000..a3826f6
Binary files /dev/null and b/public/images/brand/picks/cube-08.webp differ
diff --git a/public/images/brand/picks/field-01.webp b/public/images/brand/picks/field-01.webp
new file mode 100644
index 0000000..8f385aa
Binary files /dev/null and b/public/images/brand/picks/field-01.webp differ
diff --git a/public/images/brand/picks/field-03.webp b/public/images/brand/picks/field-03.webp
new file mode 100644
index 0000000..80709f0
Binary files /dev/null and b/public/images/brand/picks/field-03.webp differ
diff --git a/public/images/brand/picks/knot-24.webp b/public/images/brand/picks/knot-24.webp
new file mode 100644
index 0000000..9c10327
Binary files /dev/null and b/public/images/brand/picks/knot-24.webp differ
diff --git a/public/images/brand/picks/knot-25.webp b/public/images/brand/picks/knot-25.webp
new file mode 100644
index 0000000..cda5905
Binary files /dev/null and b/public/images/brand/picks/knot-25.webp differ
diff --git a/public/images/harness/claude-code.svg b/public/images/harness/claude-code.svg
new file mode 100644
index 0000000..24243dc
--- /dev/null
+++ b/public/images/harness/claude-code.svg
@@ -0,0 +1,4 @@
+
\ No newline at end of file
diff --git a/public/images/harness/codex.png b/public/images/harness/codex.png
new file mode 100644
index 0000000..63bf391
Binary files /dev/null and b/public/images/harness/codex.png differ
diff --git a/public/images/harness/hermes.png b/public/images/harness/hermes.png
new file mode 100644
index 0000000..2136748
Binary files /dev/null and b/public/images/harness/hermes.png differ
diff --git a/public/images/harness/kimi-code.png b/public/images/harness/kimi-code.png
new file mode 100644
index 0000000..c5b0875
Binary files /dev/null and b/public/images/harness/kimi-code.png differ
diff --git a/public/images/harness/nanoclaw.png b/public/images/harness/nanoclaw.png
new file mode 100644
index 0000000..aaeaec4
Binary files /dev/null and b/public/images/harness/nanoclaw.png differ
diff --git a/public/images/harness/openclaw.png b/public/images/harness/openclaw.png
new file mode 100644
index 0000000..bbe2afc
Binary files /dev/null and b/public/images/harness/openclaw.png differ
diff --git a/public/images/harness/opencode.svg b/public/images/harness/opencode.svg
new file mode 100644
index 0000000..157edc4
--- /dev/null
+++ b/public/images/harness/opencode.svg
@@ -0,0 +1,7 @@
+
\ No newline at end of file
diff --git a/public/images/harness/pi.svg b/public/images/harness/pi.svg
new file mode 100644
index 0000000..634eb6b
--- /dev/null
+++ b/public/images/harness/pi.svg
@@ -0,0 +1,5 @@
+
+
+
+ π
+
diff --git a/public/images/logos/github.svg b/public/images/logos/github.svg
new file mode 100644
index 0000000..5a0e3ce
--- /dev/null
+++ b/public/images/logos/github.svg
@@ -0,0 +1 @@
+GitHub
\ No newline at end of file
diff --git a/public/images/logos/linear.svg b/public/images/logos/linear.svg
new file mode 100644
index 0000000..ed15342
--- /dev/null
+++ b/public/images/logos/linear.svg
@@ -0,0 +1 @@
+Linear
\ No newline at end of file
diff --git a/public/images/logos/slack.svg b/public/images/logos/slack.svg
new file mode 100644
index 0000000..378c91a
--- /dev/null
+++ b/public/images/logos/slack.svg
@@ -0,0 +1 @@
+Slack
\ No newline at end of file
diff --git a/public/images/product/sandbox-full.webp b/public/images/product/sandbox-full.webp
new file mode 100644
index 0000000..c440c64
Binary files /dev/null and b/public/images/product/sandbox-full.webp differ
diff --git a/public/images/product/sandbox-workspace.webp b/public/images/product/sandbox-workspace.webp
new file mode 100644
index 0000000..1cb2a56
Binary files /dev/null and b/public/images/product/sandbox-workspace.webp differ
diff --git a/public/videos/hero-loop.mp4 b/public/videos/hero-loop.mp4
new file mode 100644
index 0000000..0ffb170
Binary files /dev/null and b/public/videos/hero-loop.mp4 differ
diff --git a/scripts/agent-forge.mjs b/scripts/agent-forge.mjs
new file mode 100644
index 0000000..debcef1
--- /dev/null
+++ b/scripts/agent-forge.mjs
@@ -0,0 +1,178 @@
+// Agent Forge — reproducible AgentProfile -> agent-portrait pipeline.
+//
+// Two-stage design:
+// Stage 1 (expensive, rare): base robot BODIES are generated with FLUX and
+// live in public/images/agents/. This script does NOT call any paid API.
+// Stage 2 (this script, cheap + deterministic): composite the REAL harness
+// logo, model, tools, and tier treatment onto a base body, driven by the
+// AgentProfile. Real SVG logos are pixel-accurate and free, so features are
+// reproducible from data (unlike hallucinated AI logos).
+//
+// Usage (working node on PATH; see repo notes for the nvm binary):
+// node scripts/agent-forge.mjs --count 8 --seed 1 --tier mixed
+// node scripts/agent-forge.mjs --profiles path/to/profiles.json
+//
+// Output: public/images/agents/forged/.png + forged/manifest.json
+// Batched (default 8) so a run is cheap and re-runnable; same seed => same set.
+
+import { chromium } from 'playwright';
+import { mkdirSync, writeFileSync, readFileSync, existsSync, readdirSync } from 'node:fs';
+import { fileURLToPath } from 'node:url';
+import { dirname, join, resolve, extname } from 'node:path';
+
+const ROOT = resolve(dirname(fileURLToPath(import.meta.url)), '..');
+const PUB = join(ROOT, 'public');
+
+// inline assets as data URIs so the render is self-contained (file:// and
+// localhost both fail or add a server dependency; base64 is reproducible).
+const MIME = { '.png': 'image/png', '.svg': 'image/svg+xml', '.jpg': 'image/jpeg', '.jpeg': 'image/jpeg' };
+const dataURICache = new Map();
+function dataURI(relPath) {
+ if (dataURICache.has(relPath)) return dataURICache.get(relPath);
+ const buf = readFileSync(join(PUB, relPath));
+ const uri = `data:${MIME[extname(relPath).toLowerCase()] || 'image/png'};base64,${buf.toString('base64')}`;
+ dataURICache.set(relPath, uri);
+ return uri;
+}
+const OUT = join(PUB, 'images/agents/forged');
+mkdirSync(OUT, { recursive: true });
+
+// ---- args ----
+const args = process.argv.slice(2);
+const arg = (k, d) => { const i = args.indexOf(`--${k}`); return i >= 0 ? args[i + 1] : d; };
+const COUNT = parseInt(arg('count', '8'), 10);
+const SEED = parseInt(arg('seed', '1'), 10);
+const TIERFILTER = arg('tier', 'mixed');
+const PROFILES_PATH = arg('profiles', null);
+
+// ---- config catalog (mirrors the AgentProfile shape) ----
+const HARNESSES = [
+ { id: 'claude', name: 'Claude Code', logo: 'images/harness/claude-code.svg' },
+ { id: 'codex', name: 'Codex', logo: 'images/harness/codex.png' },
+ { id: 'opencode', name: 'OpenCode', logo: 'images/harness/opencode.svg' },
+ { id: 'hermes', name: 'Hermes', logo: 'images/harness/hermes.png' },
+ { id: 'openclaw', name: 'OpenClaw', logo: 'images/harness/openclaw.png' },
+ { id: 'nanoclaw', name: 'NanoClaw', logo: 'images/harness/nanoclaw.png' },
+ { id: 'kimi', name: 'Kimi Code', logo: 'images/harness/kimi-code.png' },
+ { id: 'pi', name: 'Pi', logo: 'images/harness/pi.svg' },
+];
+const MODELS = ['claude-sonnet-5', 'claude-fable-5', 'gpt-5.5', 'gemini-3-pro', 'kimi-k2', 'llama-4-405b'];
+const TOOLS = ['shell', 'files', 'browser', 'python', 'git', 'sql', 'web', 'http'];
+const TIERS = ['Common', 'Uncommon', 'Rare', 'Epic'];
+
+// base bodies grouped by tier (from the fal-generated pool). Auto-discovers any
+// bases/ renders; falls back to the flat pool so the script runs today.
+function discoverBases() {
+ const flat = readdirSync(join(PUB, 'images/agents')).filter((f) => f.endsWith('.png'));
+ const basesDir = join(PUB, 'images/agents/bases');
+ const bases = existsSync(basesDir) ? readdirSync(basesDir).filter((f) => f.endsWith('.png')) : [];
+ const pick = (re, dir, arr) => arr.filter((f) => re.test(f)).map((f) => `images/agents/${dir}${f}`);
+ const byTier = {
+ Epic: [...pick(/^body-rare/, 'bases/', bases), ...pick(/^(epic|woven)/, '', flat)],
+ Rare: [...pick(/^body-rare/, 'bases/', bases), ...pick(/^(rare|crystal)/, '', flat)],
+ Uncommon: [...pick(/^body-common/, 'bases/', bases), ...pick(/^(matte)/, '', flat)],
+ Common: [...pick(/^body-common/, 'bases/', bases), ...pick(/^(common|matte)/, '', flat)],
+ };
+ for (const t of TIERS) if (!byTier[t].length) byTier[t] = pick(/./, '', flat);
+ return byTier;
+}
+
+// deterministic PRNG so a seed reproduces the exact roster
+function mulberry32(a) {
+ return () => { a |= 0; a = (a + 0x6D2B79F5) | 0; let t = Math.imul(a ^ (a >>> 15), 1 | a);
+ t = (t + Math.imul(t ^ (t >>> 7), 61 | t)) ^ t; return ((t ^ (t >>> 14)) >>> 0) / 4294967296; };
+}
+
+function buildProfiles() {
+ if (PROFILES_PATH) return JSON.parse(readFileSync(PROFILES_PATH, 'utf8'));
+ const byTier = discoverBases();
+ const out = [];
+ for (let i = 0; i < COUNT; i++) {
+ const r = mulberry32(SEED * 1000 + i * 97);
+ const tier = TIERFILTER !== 'mixed' && TIERS.includes(TIERFILTER)
+ ? TIERFILTER
+ : TIERS[Math.floor(r() * r() * TIERS.length)]; // skew toward common
+ const bases = byTier[tier];
+ const harness = HARNESSES[Math.floor(r() * HARNESSES.length)];
+ const nTools = 2 + Math.floor(r() * 4);
+ const tools = [...TOOLS].sort(() => r() - 0.5).slice(0, nTools);
+ out.push({
+ id: `AGENT-${String(1000 + SEED * 100 + i).padStart(4, '0')}`,
+ base: bases[Math.floor(r() * bases.length)],
+ tier, harness, model: MODELS[Math.floor(r() * MODELS.length)],
+ tools, level: 1 + TIERS.indexOf(tier) * 2 + Math.floor(r() * 3),
+ });
+ }
+ return out;
+}
+
+// the composited card template (features baked onto the base body)
+function cardHTML(p) {
+ const tierGlow = { Common: '0', Uncommon: '0.15', Rare: '0.4', Epic: '0.75' }[p.tier];
+ const toolPips = p.tools.map((t) => `${t}`).join('');
+ return `
+
+
+
+
+
+ ${p.tier}
+ LV ${p.level}
+
+ ${p.id}
+ `;
+}
+
+// ---- run ----
+const profiles = buildProfiles();
+const browser = await chromium.launch();
+const page = await browser.newPage({ viewport: { width: 640, height: 640 }, deviceScaleFactor: 2 });
+const manifest = [];
+for (const p of profiles) {
+ await page.setContent(cardHTML(p), { waitUntil: 'load' });
+ await page.waitForTimeout(120);
+ const file = join(OUT, `${p.id}.png`);
+ await page.screenshot({ path: file });
+ manifest.push({ ...p, file: `images/agents/forged/${p.id}.png` });
+ console.log(`forged ${p.id} ${p.tier.padEnd(9)} ${p.harness.name} / ${p.model}`);
+}
+writeFileSync(join(OUT, 'manifest.json'), JSON.stringify(manifest, null, 2));
+await browser.close();
+console.log(`\ndone: ${profiles.length} agents -> ${OUT}`);
+console.log(`re-run reproducibly: node scripts/agent-forge.mjs --count ${COUNT} --seed ${SEED}`);
diff --git a/src/components/Footer.astro b/src/components/Footer.astro
index 3fe7a81..1619709 100644
--- a/src/components/Footer.astro
+++ b/src/components/Footer.astro
@@ -1,42 +1,212 @@
---
-const footerLinks = [
- { label: 'Blog', href: '/blog', external: false },
- { label: 'Research', href: '/research', external: false },
- { label: 'Docs', href: 'https://docs.tangle.tools/', external: true },
- { label: 'Launch Agent', href: 'https://ai.tangle.tools', external: true },
- { label: 'Follow', href: 'https://twitter.com/intent/follow?screen_name=tangle_network', external: true },
+// Dispersion-hairline sitemap footer. The hairline is the one place on the
+// page where all three product hues sit on one continuous line.
+const products = [
+ { label: 'Sandbox', href: 'https://sandbox.tangle.tools', domain: 'sandbox.tangle.tools', hue: '#818CF8' },
+ { label: 'Intelligence', href: 'https://intelligence.tangle.tools', domain: 'intelligence.tangle.tools', hue: '#818CF8' },
+ { label: 'Inference', href: 'https://router.tangle.tools', domain: 'router.tangle.tools', hue: '#818CF8' },
+];
+const resources = [
+ { label: 'Docs', href: 'https://docs.tangle.tools', domain: 'docs.tangle.tools' },
+ { label: 'Console', href: 'https://ai.tangle.tools', domain: 'ai.tangle.tools' },
+ { label: 'GitHub', href: 'https://github.com/tangle-network', domain: 'github.com/tangle-network' },
+];
+const company = [
+ { label: 'Blog', href: '/blog' },
+ { label: 'Brand kit', href: '/brand-kit' },
];
---
-