From 68dc324941b0dd2ce35392b79c4fd44a60c93ce9 Mon Sep 17 00:00:00 2001
From: Jeff Emmett
Date: Wed, 25 Feb 2026 19:08:54 -0800
Subject: [PATCH] Restructure MycoStack roots, add interactive effects & data
flows
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
- Make Commons Stack the primary root of the MycoStack
- Reframe P2P Foundation as both foundation and forward-looking knowledge engine
producing convivial knowledge packets → open source protocol toolkits for P4P
- Add Data Flows section (trust, resources, favors, capital) with rStack/rSpace links
- Move Flow Funding to Tools in Active Research with TBFF from rFunds.online
- Lighten starting background and reduce chroma for gentler rainbow fade
- Add mouse-interactive mycelial canvas (cursor attraction, spore particles,
hypha connection lines, ambient glow)
- Add rFunds and rStack to network map and footer
Co-Authored-By: Claude Opus 4.6
---
app/globals.css | 6 +-
components/footer.tsx | 4 +-
components/hero-section.tsx | 4 +-
components/legacy-section.tsx | 258 ++++++++++++++++++++++-------
components/mycelial-canvas.tsx | 183 ++++++++++++++++++--
components/network-map-section.tsx | 45 +++--
components/scroll-provider.tsx | 17 +-
7 files changed, 412 insertions(+), 105 deletions(-)
diff --git a/app/globals.css b/app/globals.css
index 6d8ea45..597d2c7 100644
--- a/app/globals.css
+++ b/app/globals.css
@@ -5,9 +5,9 @@
:root {
/* Scroll-driven dynamic colors (set by JS) */
- --scroll-bg: oklch(0.08 0.02 30);
- --scroll-fg: oklch(0.85 0.03 80);
- --scroll-accent: oklch(0.45 0.12 60);
+ --scroll-bg: oklch(0.18 0.015 30);
+ --scroll-fg: oklch(0.88 0.02 80);
+ --scroll-accent: oklch(0.50 0.10 60);
--scroll-depth: 0;
/* Static palette tokens */
diff --git a/components/footer.tsx b/components/footer.tsx
index de7c3d6..c5c18cb 100644
--- a/components/footer.tsx
+++ b/components/footer.tsx
@@ -5,11 +5,13 @@ const LINKS = [
{ name: "P2P Foundation", url: "https://wiki.p2pfoundation.net/" },
{ name: "MycoFi", url: "https://mycofi.earth" },
{ name: "Mycopunk", url: "https://mycopunk.xyz" },
+ { name: "rFunds", url: "https://rfunds.online" },
+ { name: "rStack", url: "https://rstack.org" },
+ { name: "(You)rSpace", url: "https://yourspace.online" },
{ name: "Undernet", url: "https://undernet.earth" },
{ name: "Psilo-Cyber", url: "https://psilo-cyber.net" },
{ name: "Compost Capitalism", url: "https://compostcapitalism.xyz" },
{ name: "Post-Appitalism", url: "https://post-appitalist.app" },
- { name: "(You)rSpace", url: "https://yourspace.online" },
{ name: "Trippin Balls", url: "https://trippinballs.lol" },
]
diff --git a/components/hero-section.tsx b/components/hero-section.tsx
index 998c83d..aa92f9d 100644
--- a/components/hero-section.tsx
+++ b/components/hero-section.tsx
@@ -42,8 +42,8 @@ export function HeroSection() {
className="emerge-letter text-sm sm:text-base opacity-40 max-w-xl mx-auto"
style={{ animationDelay: "1.5s" }}
>
- Born from the P2P Foundation and the Commons Stack.
- Inoculating the age of the P4P (peer-for-peer) movement.
+ Rooted in the Commons Stack. Nourished by the P2P Foundation.
+ Propagating the P4P (peer-for-peer) movement.
{/* Terminal tagline */}
diff --git a/components/legacy-section.tsx b/components/legacy-section.tsx
index 0e8d34f..1c6956b 100644
--- a/components/legacy-section.tsx
+++ b/components/legacy-section.tsx
@@ -16,42 +16,42 @@ export function LegacySection() {
The Roots
- Every network grows from somewhere. Ours grows from the Commons
- Stack, the P2P Foundation, and the broader commons movement.
+ The MycoStack grows from the Commons Stack — its primary root
+ system — nourished by the knowledge commons of the P2P
+ Foundation and the broader commons movement.
- {/* P2P Foundation */}
+ {/* Commons Stack - Primary Root */}
- The P2P Foundation
+ The Commons Stack
The{" "}
- P2P Foundation Wiki
-
- , started by Michel Bauwens and shaped by
- hundreds of contributors, documents the emerging landscape of
- peer-to-peer collaboration and commons-based alternatives. Over
- 25,000 pages of case studies, theoretical frameworks, policy
- proposals, and practical guides — an open knowledge base
- that continues to inform projects worldwide.
+ Commons Stack
+ {" "}
+ is the primary root of the MycoStack. Its mission:{" "}
+ fund and govern the commons. Through pioneering work in
+ token engineering, augmented bonding curves, and conviction
+ voting, the Commons Stack and its{" "}
+ Trusted Seed community developed regenerative
+ funding mechanisms for commons infrastructure.
- Out of this work came key frameworks:{" "}
- commons-based peer production, the{" "}
- partner state, and{" "}
- cosmo-localism (“design global, manufacture
- local”). These ideas didn’t belong to any one person
- — they emerged from a network of researchers, practitioners,
- and communities building alternatives in the open.
+ But tools alone aren’t enough. The Commons Stack taught us
+ that technology must be wrapped in culture — in shared
+ values, governance practices, and communities of care. The
+ Trusted Seed wasn’t just a token-holder registry; it was an
+ experiment in building trust at the speed of consensus. From this
+ root system, the MycoStack grows outward.
@@ -94,81 +94,133 @@ export function LegacySection() {
- {/* Commons Stack history */}
+ {/* P2P Foundation - Foundation AND Forward */}
- The Commons Stack
+ The P2P Foundation
The{" "}
- Commons Stack
- {" "}
- was born from this intellectual tradition. Its mission:{" "}
- fund and govern the commons. Through pioneering work in
- token engineering, augmented bonding curves, and conviction
- voting, the Commons Stack and its{" "}
- Trusted Seed community developed regenerative
- funding mechanisms for commons infrastructure.
+ P2P Foundation Wiki
+
+ , started by Michel Bauwens and shaped by
+ hundreds of contributors, is both the bedrock beneath the
+ MycoStack and the frontier ahead of it. Over 25,000 pages of
+ case studies, theoretical frameworks, policy proposals, and
+ practical guides — an open knowledge base that continues
+ to inform projects worldwide.
- But tools alone aren’t enough. The Commons Stack taught us
- that technology must be wrapped in culture — in shared
- values, governance practices, and communities of care. The
- Trusted Seed wasn’t just a token-holder registry; it was an
- experiment in building trust at the speed of consensus.
+ Out of this work came key frameworks:{" "}
+ commons-based peer production, the{" "}
+ partner state, and{" "}
+ cosmo-localism (“design global, manufacture
+ local”). But the P2P Foundation doesn’t just preserve
+ knowledge — it transforms it. Each iteration of commons
+ practice feeds back into the knowledge base, refining theories
+ into{" "}
+ convivial knowledge packets: living documents
+ that distill decades of research and practice into actionable
+ frameworks communities can actually use.
+
+
+ These knowledge packets become the seeds of{" "}
+ open source protocol toolkits — practical
+ governance, funding, and coordination tools that any community
+ can adopt, adapt, and contribute back to. The P2P Foundation as
+ both root system and fruiting body: absorbing nutrients from the
+ ground, pushing spores into the future.
- {/* Flow Funding */}
+ {/* Data Flows - New Section */}
- Flow Funding
+ Data Flows of the Commons
- The Commons Stack pioneered the Augmented Bonding Curve — a
- breakthrough in sustainable funding for the commons. Flow Funding
- is its natural evolution: less mechanism, more ecology. Where the
- ABC created a single reservoir, Flow Funding cultivates{" "}
- enmeshed ecologies of inter- and intra-organizational
- flow — resources circulating continuously between nested
- communities the way nutrients cycle through a forest floor.
+ The MycoStack recognizes that the dissemination of{" "}
+ trust, resources,{" "}
+ favors, and capital are all
+ data flows — streams that can be made visible, governed
+ collectively, and managed by communities on self-provisioned
+ infrastructure.
- At the heart of Flow Funding is a threshold-based model rooted in
- the concept of “enoughness” —
- enabling an economics of sufficiency rather than accumulation. When
- a node in the network has enough, surplus flows onward to where
- it’s needed. No hoarding, no artificial scarcity. Just the
- continuous circulation that living systems have practiced for
- billions of years.
+ When communities own their own coordination tools, these flows
+ stop being opaque transactions mediated by extractive platforms
+ and become transparent, reciprocal exchanges governed by the
+ people who participate in them. Trust becomes legible. Resources
+ find their way to where they’re needed. Favors compound
+ into mutual aid networks. Capital circulates instead of
+ accumulating.
-
- This is economics as ecology: not designing incentives from above,
- but cultivating the conditions for resources to find their own
- path — rooted, reciprocal, and regenerative by nature.
+
+
+
+
+ Community-Owned Infrastructure for Coordination
+
+
+
+
+
+ Open source infrastructure stack for community coordination
+ — self-hostable, sovereign, interoperable
+
+
+
+
+
+ Community-owned digital spaces — where coordination
+ happens on infrastructure you control
+
+
+
+
+ When communities own their stack, every data flow becomes a
+ commons resource rather than a corporate asset.
- {/* P4P framework */}
+ {/* P4P Movement */}
The Inoculation of the
@@ -186,9 +238,12 @@ export function LegacySection() {
practice.
- Where the original Commons Stack built tools, MycoStack grows
- ecosystems. Where P2P described a relational dynamic, P4P demands
- a commitment. The mycelium doesn’t just connect — it
+ The P2P Foundation’s convivial knowledge packets become
+ the P4P movement’s open source protocol toolkits —
+ governance patterns, funding mechanisms, and coordination
+ primitives packaged as commons resources that any community can
+ deploy. Where P2P described a relational dynamic, P4P demands a
+ commitment. The mycelium doesn’t just connect — it
nourishes.
@@ -239,6 +294,81 @@ export function LegacySection() {
+ {/* Tools in Active Research */}
+
+
+ Tools in Active Research
+
+
+
+ Flow Funding — the natural evolution of
+ the Commons Stack’s Augmented Bonding Curve. Less
+ mechanism, more ecology. Where the ABC created a single
+ reservoir, Flow Funding cultivates{" "}
+ enmeshed ecologies of inter- and intra-organizational
+ flow — resources circulating continuously between nested
+ communities the way nutrients cycle through a forest floor.
+
+
+ The latest research takes the form of{" "}
+ Threshold-Based Flow Funding (TBFF), being
+ developed at{" "}
+
+ rFunds.online
+
+ . TBFF models funding pools as dynamic funnels operating across
+ three zones: an overflow zone where excess funds
+ automatically redistribute to connected pools, a{" "}
+ healthy zone of full flow and balanced
+ operations, and a critical zone where outflow
+ restricts to conservation mode. Funnels connect via overflow and
+ spending edges, creating living networks of resource circulation
+ governed by thresholds of{" "}
+ “enoughness” rather than
+ accumulation.
+
+
+ This is economics as ecology: not designing incentives from above,
+ but cultivating the conditions for resources to find their own
+ path — rooted, reciprocal, and regenerative by nature.
+
+
+
+
+
+ TBFF Zones
+
+
+
+
overflow
+
+ Above MAX — surplus redistributes to connected funnels
+
+
+
+
healthy
+
+ Normal ops — full flow rate, balanced funding
+
+
+
+
critical
+
+ Below MIN — outflow restricted, conservation mode
+
+
+
+
+
+
{/* Pillars */}
(null)
const hyphaeRef = useRef([])
+ const sporesRef = useRef([])
const frameRef = useRef(0)
const trailCanvasRef = useRef(null)
+ const mouseRef = useRef<{ x: number; y: number; active: boolean }>({
+ x: 0,
+ y: 0,
+ active: false,
+ })
useEffect(() => {
const canvas = canvasRef.current
@@ -50,8 +66,28 @@ export function MycelialCanvas() {
resize()
window.addEventListener("resize", resize)
- const w = () => canvas.width / (Math.min(window.devicePixelRatio || 1, 2))
- const h = () => canvas.height / (Math.min(window.devicePixelRatio || 1, 2))
+ // Mouse/touch tracking for interactive effects
+ const onMouseMove = (e: MouseEvent) => {
+ mouseRef.current.x = e.clientX
+ mouseRef.current.y = e.clientY
+ mouseRef.current.active = true
+ }
+ const onTouchMove = (e: TouchEvent) => {
+ if (e.touches.length > 0) {
+ mouseRef.current.x = e.touches[0].clientX
+ mouseRef.current.y = e.touches[0].clientY
+ mouseRef.current.active = true
+ }
+ }
+ const onMouseLeave = () => {
+ mouseRef.current.active = false
+ }
+ window.addEventListener("mousemove", onMouseMove)
+ window.addEventListener("touchmove", onTouchMove, { passive: true })
+ window.addEventListener("mouseleave", onMouseLeave)
+
+ const w = () => canvas.width / Math.min(window.devicePixelRatio || 1, 2)
+ const h = () => canvas.height / Math.min(window.devicePixelRatio || 1, 2)
const createHypha = (
x: number,
@@ -62,17 +98,27 @@ export function MycelialCanvas() {
x,
y,
angle,
- speed: 1.2 + Math.random() * 0.8 - depth * 0.15,
+ speed: 1.0 + Math.random() * 0.6 - depth * 0.1,
age: 0,
- maxAge: 200 + Math.random() * 150 - depth * 20,
+ maxAge: 250 + Math.random() * 200 - depth * 15,
parentX: x,
parentY: y,
depth,
branchCount: 0,
})
- // Seed initial hyphae from bottom
- const seedCount = Math.max(3, Math.floor(w() / 250))
+ const createSpore = (x: number, y: number): Spore => ({
+ x,
+ y,
+ vx: (Math.random() - 0.5) * 1.5,
+ vy: (Math.random() - 0.5) * 1.5 - 0.3,
+ life: 0,
+ maxLife: 60 + Math.random() * 80,
+ radius: 1 + Math.random() * 2,
+ })
+
+ // Seed initial hyphae from bottom and sides
+ const seedCount = Math.max(4, Math.floor(w() / 200))
for (let i = 0; i < seedCount; i++) {
const x =
(w() / (seedCount + 1)) * (i + 1) + (Math.random() - 0.5) * 80
@@ -85,16 +131,29 @@ export function MycelialCanvas() {
)
)
}
+ // Seed a couple from sides
+ for (let i = 0; i < 2; i++) {
+ const fromLeft = Math.random() > 0.5
+ hyphaeRef.current.push(
+ createHypha(
+ fromLeft ? -10 : w() + 10,
+ h() * (0.4 + Math.random() * 0.4),
+ fromLeft ? -0.2 + Math.random() * 0.4 : Math.PI - 0.2 + Math.random() * 0.4,
+ 0
+ )
+ )
+ }
const getAccentColor = () => {
return (
getComputedStyle(document.documentElement)
.getPropertyValue("--scroll-accent")
- .trim() || "oklch(0.55 0.18 155)"
+ .trim() || "oklch(0.55 0.13 155)"
)
}
let lastSeed = 0
+ let lastSporeEmit = 0
const animate = () => {
const width = w()
@@ -104,10 +163,11 @@ export function MycelialCanvas() {
ctx.clearRect(0, 0, width, height)
// Fade the trail canvas slowly
- trailCtx.fillStyle = "rgba(10, 8, 5, 0.008)"
+ trailCtx.fillStyle = "rgba(10, 8, 5, 0.006)"
trailCtx.fillRect(0, 0, width, height)
const accent = getAccentColor()
+ const mouse = mouseRef.current
const alive: Hypha[] = []
for (const hypha of hyphaeRef.current) {
@@ -122,6 +182,21 @@ export function MycelialCanvas() {
hypha.angle += (Math.random() - 0.5) * 0.12
// Gentle gravitropism (slightly toward vertical)
hypha.angle += (-Math.PI / 2 - hypha.angle) * 0.003
+
+ // Mouse attraction: hyphae gently curve toward cursor
+ if (mouse.active) {
+ const dx = mouse.x - hypha.x
+ const dy = mouse.y - hypha.y
+ const dist = Math.sqrt(dx * dx + dy * dy)
+ if (dist < 300 && dist > 20) {
+ const targetAngle = Math.atan2(dy, dx)
+ let angleDiff = targetAngle - hypha.angle
+ if (angleDiff > Math.PI) angleDiff -= Math.PI * 2
+ if (angleDiff < -Math.PI) angleDiff += Math.PI * 2
+ hypha.angle += angleDiff * 0.015 * (1 - dist / 300)
+ }
+ }
+
hypha.x += Math.cos(hypha.angle) * hypha.speed
hypha.y += Math.sin(hypha.angle) * hypha.speed
@@ -133,9 +208,9 @@ export function MycelialCanvas() {
const ageRatio = hypha.age / hypha.maxAge
const opacity = Math.max(
0.05,
- (1 - ageRatio * 0.9) * (0.6 - hypha.depth * 0.08)
+ (1 - ageRatio * 0.9) * (0.6 - hypha.depth * 0.06)
)
- const lineWidth = Math.max(0.3, 2.5 - hypha.depth * 0.4 - ageRatio)
+ const lineWidth = Math.max(0.3, 2.5 - hypha.depth * 0.35 - ageRatio)
// Draw on trail canvas for persistence
trailCtx.strokeStyle = accent.replace(")", ` / ${opacity * 0.5})`)
@@ -154,6 +229,25 @@ export function MycelialCanvas() {
ctx.fill()
}
+ // Draw faint connections between nearby hyphae tips
+ if (ageRatio < 0.5 && hypha.depth < 3) {
+ for (const other of alive) {
+ if (other === hypha) continue
+ const ox = other.x - hypha.x
+ const oy = other.y - hypha.y
+ const od = Math.sqrt(ox * ox + oy * oy)
+ if (od < 80 && od > 10) {
+ const connOpacity = 0.06 * (1 - od / 80)
+ ctx.strokeStyle = accent.replace(")", ` / ${connOpacity})`)
+ ctx.lineWidth = 0.5
+ ctx.beginPath()
+ ctx.moveTo(hypha.x, hypha.y)
+ ctx.lineTo(other.x, other.y)
+ ctx.stroke()
+ }
+ }
+ }
+
// Branching
if (
hypha.age > 25 &&
@@ -171,6 +265,65 @@ export function MycelialCanvas() {
alive.push(hypha)
}
+ // Spore particles
+ const now = Date.now()
+ // Emit spores near mouse
+ if (mouse.active && now - lastSporeEmit > 150) {
+ lastSporeEmit = now
+ sporesRef.current.push(
+ createSpore(
+ mouse.x + (Math.random() - 0.5) * 40,
+ mouse.y + (Math.random() - 0.5) * 40
+ )
+ )
+ }
+
+ // Emit ambient spores occasionally
+ if (now - lastSporeEmit > 800 && sporesRef.current.length < 30) {
+ lastSporeEmit = now
+ sporesRef.current.push(
+ createSpore(Math.random() * width, Math.random() * height)
+ )
+ }
+
+ // Update and draw spores
+ const aliveSpores: Spore[] = []
+ for (const spore of sporesRef.current) {
+ spore.life++
+ if (spore.life >= spore.maxLife) continue
+
+ spore.x += spore.vx
+ spore.y += spore.vy
+ spore.vx *= 0.98
+ spore.vy *= 0.98
+
+ const lifeRatio = spore.life / spore.maxLife
+ const sporeOpacity = Math.sin(lifeRatio * Math.PI) * 0.3
+ const sporeRadius = spore.radius * (1 - lifeRatio * 0.5)
+
+ ctx.fillStyle = accent.replace(")", ` / ${sporeOpacity})`)
+ ctx.beginPath()
+ ctx.arc(spore.x, spore.y, sporeRadius, 0, Math.PI * 2)
+ ctx.fill()
+
+ aliveSpores.push(spore)
+ }
+ sporesRef.current = aliveSpores
+
+ // Mouse glow effect
+ if (mouse.active) {
+ const gradient = ctx.createRadialGradient(
+ mouse.x, mouse.y, 0,
+ mouse.x, mouse.y, 120
+ )
+ gradient.addColorStop(0, accent.replace(")", " / 0.06)"))
+ gradient.addColorStop(1, accent.replace(")", " / 0)"))
+ ctx.fillStyle = gradient
+ ctx.beginPath()
+ ctx.arc(mouse.x, mouse.y, 120, 0, Math.PI * 2)
+ ctx.fill()
+ }
+
// Draw trail canvas behind
ctx.drawImage(trailCanvas, 0, 0, width, height)
@@ -178,8 +331,7 @@ export function MycelialCanvas() {
hyphaeRef.current = alive.length > 500 ? alive.slice(-400) : alive
// Periodically seed new roots
- const now = Date.now()
- if (now - lastSeed > 3000 && alive.length < 350) {
+ if (now - lastSeed > 2500 && alive.length < 400) {
lastSeed = now
const x = Math.random() * width
hyphaeRef.current.push(
@@ -194,6 +346,9 @@ export function MycelialCanvas() {
return () => {
window.removeEventListener("resize", resize)
+ window.removeEventListener("mousemove", onMouseMove)
+ window.removeEventListener("touchmove", onTouchMove)
+ window.removeEventListener("mouseleave", onMouseLeave)
cancelAnimationFrame(frameRef.current)
}
}, [])
@@ -201,8 +356,8 @@ export function MycelialCanvas() {
return (
)
}
diff --git a/components/network-map-section.tsx b/components/network-map-section.tsx
index 55875d1..9840e3d 100644
--- a/components/network-map-section.tsx
+++ b/components/network-map-section.tsx
@@ -25,7 +25,7 @@ const NODES: NetworkNode[] = [
{
name: "Commons Stack",
domain: "commonsstack.org",
- description: "Fund and govern the commons",
+ description: "Fund and govern the commons — primary root",
x: 50,
y: 10,
},
@@ -40,57 +40,71 @@ const NODES: NetworkNode[] = [
name: "MycoFi",
domain: "mycofi.earth",
description: "Mycoeconomics & regenerative currencies",
- x: 25,
+ x: 22,
y: 20,
},
{
name: "Mycopunk",
domain: "mycopunk.xyz",
description: "Building from beneath the surface",
- x: 75,
+ x: 78,
y: 15,
},
+ {
+ name: "rFunds",
+ domain: "rfunds.online",
+ description: "Threshold-Based Flow Funding research",
+ x: 32,
+ y: 30,
+ },
+ {
+ name: "rStack",
+ domain: "rstack.org",
+ description: "Open source community coordination infrastructure",
+ x: 75,
+ y: 58,
+ },
{
name: "Compost Capitalism",
domain: "compostcapitalism.xyz",
description: "Decomposing extractive systems",
- x: 12,
+ x: 10,
y: 50,
},
{
name: "The Undernet",
domain: "undernet.earth",
description: "Community-owned infrastructure",
- x: 88,
- y: 45,
+ x: 90,
+ y: 40,
},
{
name: "Post-Appitalism",
domain: "post-appitalist.app",
description: "Tools beyond extractive platforms",
- x: 22,
+ x: 18,
y: 78,
},
{
name: "(You)rSpace",
domain: "yourspace.online",
- description: "Spaces that belong to communities",
- x: 60,
- y: 80,
+ description: "Community-owned digital spaces",
+ x: 62,
+ y: 78,
},
{
name: "Psilo-Cyber",
domain: "psilo-cyber.net",
description: "Encrypted mesh networks",
- x: 82,
+ x: 85,
y: 72,
},
{
name: "Trippin Balls",
domain: "trippinballs.lol",
description: "Expand your perspective",
- x: 42,
- y: 88,
+ x: 40,
+ y: 90,
},
]
@@ -101,9 +115,14 @@ const CONNECTIONS: [string, string][] = [
["mycostack.xyz", "undernet.earth"],
["mycostack.xyz", "compostcapitalism.xyz"],
["mycostack.xyz", "yourspace.online"],
+ ["mycostack.xyz", "rstack.org"],
["commonsstack.org", "wiki.p2pfoundation.net"],
["commonsstack.org", "mycofi.earth"],
["commonsstack.org", "mycopunk.xyz"],
+ ["commonsstack.org", "rfunds.online"],
+ ["rfunds.online", "mycofi.earth"],
+ ["rstack.org", "yourspace.online"],
+ ["rstack.org", "undernet.earth"],
["wiki.p2pfoundation.net", "post-appitalist.app"],
["mycofi.earth", "mycopunk.xyz"],
["undernet.earth", "psilo-cyber.net"],
diff --git a/components/scroll-provider.tsx b/components/scroll-provider.tsx
index 097c0af..f68a97f 100644
--- a/components/scroll-provider.tsx
+++ b/components/scroll-provider.tsx
@@ -5,15 +5,16 @@ import { useEffect } from "react"
// Color stops: [scrollPos, bg-L, bg-C, bg-H, fg-L, fg-C, fg-H, accent-L, accent-C, accent-H]
// 8 sections: Hero → Legacy → Compost → Mycelium → Undernet → Anastomosis → Emergence → Network Map
+// Gentler rainbow fade with lighter start, lower chroma for subtlety
const COLOR_STOPS: number[][] = [
- [0.0, 0.08, 0.02, 10, 0.85, 0.02, 10, 0.45, 0.08, 10 ], // Hero: warm red-brown
- [0.10, 0.10, 0.03, 40, 0.84, 0.02, 40, 0.50, 0.10, 40 ], // Legacy: faded orange
- [0.20, 0.12, 0.03, 70, 0.82, 0.03, 70, 0.55, 0.10, 65 ], // Compost: faded amber
- [0.35, 0.16, 0.04, 145, 0.88, 0.03, 145, 0.55, 0.12, 150], // Mycelium: faded green
- [0.48, 0.26, 0.03, 230, 0.92, 0.02, 230, 0.55, 0.10, 225], // Undernet: faded blue
- [0.60, 0.45, 0.04, 290, 0.15, 0.02, 290, 0.55, 0.10, 285], // Anastomosis: faded violet
- [0.78, 0.85, 0.03, 345, 0.15, 0.02, 345, 0.60, 0.10, 340], // Emergence: faded rose
- [0.92, 0.94, 0.02, 30, 0.12, 0.02, 30, 0.55, 0.08, 25 ], // Network Map: back to warm
+ [0.0, 0.18, 0.015, 10, 0.88, 0.02, 10, 0.50, 0.08, 10 ], // Hero: warm twilight
+ [0.10, 0.16, 0.018, 40, 0.86, 0.02, 40, 0.52, 0.10, 40 ], // Legacy: faded orange
+ [0.20, 0.15, 0.025, 70, 0.84, 0.03, 70, 0.55, 0.10, 65 ], // Compost: faded amber
+ [0.35, 0.18, 0.03, 145, 0.88, 0.03, 145, 0.55, 0.12, 150], // Mycelium: faded green
+ [0.48, 0.24, 0.025, 230, 0.90, 0.02, 230, 0.52, 0.10, 225], // Undernet: faded blue
+ [0.60, 0.45, 0.03, 290, 0.15, 0.02, 290, 0.58, 0.10, 285], // Anastomosis: faded violet
+ [0.78, 0.82, 0.025, 345, 0.15, 0.02, 345, 0.58, 0.10, 340], // Emergence: faded rose
+ [0.92, 0.92, 0.015, 30, 0.12, 0.02, 30, 0.55, 0.08, 25 ], // Network Map: back to warm
]
function lerp(a: number, b: number, t: number) {