Restructure MycoStack roots, add interactive effects & data flows
- 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 <noreply@anthropic.com>
This commit is contained in:
parent
465320623e
commit
e0af4e23ae
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -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" },
|
||||
]
|
||||
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
</p>
|
||||
|
||||
{/* Terminal tagline */}
|
||||
|
|
|
|||
|
|
@ -16,42 +16,42 @@ export function LegacySection() {
|
|||
The Roots
|
||||
</h2>
|
||||
<p className="text-lg sm:text-xl opacity-70 max-w-2xl mx-auto">
|
||||
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.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{/* P2P Foundation */}
|
||||
{/* Commons Stack - Primary Root */}
|
||||
<div className="section-reveal max-w-3xl mx-auto space-y-6">
|
||||
<h3 className="font-serif text-2xl sm:text-3xl font-semibold">
|
||||
The P2P Foundation
|
||||
The Commons Stack
|
||||
</h3>
|
||||
<div className="space-y-4 text-base leading-relaxed opacity-80">
|
||||
<p>
|
||||
The{" "}
|
||||
<a
|
||||
href="https://wiki.p2pfoundation.net/"
|
||||
href="https://commonsstack.org"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="domain-link"
|
||||
>
|
||||
P2P Foundation Wiki
|
||||
</a>
|
||||
, 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
|
||||
</a>{" "}
|
||||
is the primary root of the MycoStack. Its mission:{" "}
|
||||
<em>fund and govern the commons</em>. Through pioneering work in
|
||||
token engineering, augmented bonding curves, and conviction
|
||||
voting, the Commons Stack and its{" "}
|
||||
<strong>Trusted Seed</strong> community developed regenerative
|
||||
funding mechanisms for commons infrastructure.
|
||||
</p>
|
||||
<p>
|
||||
Out of this work came key frameworks:{" "}
|
||||
<strong>commons-based peer production</strong>, the{" "}
|
||||
<strong>partner state</strong>, and{" "}
|
||||
<strong>cosmo-localism</strong> (“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.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -94,81 +94,133 @@ export function LegacySection() {
|
|||
</p>
|
||||
</div>
|
||||
|
||||
{/* Commons Stack history */}
|
||||
{/* P2P Foundation - Foundation AND Forward */}
|
||||
<div
|
||||
className="section-reveal max-w-3xl mx-auto space-y-6"
|
||||
style={{ transitionDelay: "0.15s" }}
|
||||
style={{ transitionDelay: "0.12s" }}
|
||||
>
|
||||
<h3 className="font-serif text-2xl sm:text-3xl font-semibold">
|
||||
The Commons Stack
|
||||
The P2P Foundation
|
||||
</h3>
|
||||
<div className="space-y-4 text-base leading-relaxed opacity-80">
|
||||
<p>
|
||||
The{" "}
|
||||
<a
|
||||
href="https://commonsstack.org"
|
||||
href="https://wiki.p2pfoundation.net/"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="domain-link"
|
||||
>
|
||||
Commons Stack
|
||||
</a>{" "}
|
||||
was born from this intellectual tradition. Its mission:{" "}
|
||||
<em>fund and govern the commons</em>. Through pioneering work in
|
||||
token engineering, augmented bonding curves, and conviction
|
||||
voting, the Commons Stack and its{" "}
|
||||
<strong>Trusted Seed</strong> community developed regenerative
|
||||
funding mechanisms for commons infrastructure.
|
||||
P2P Foundation Wiki
|
||||
</a>
|
||||
, 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.
|
||||
</p>
|
||||
<p>
|
||||
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:{" "}
|
||||
<strong>commons-based peer production</strong>, the{" "}
|
||||
<strong>partner state</strong>, and{" "}
|
||||
<strong>cosmo-localism</strong> (“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{" "}
|
||||
<strong>convivial knowledge packets</strong>: living documents
|
||||
that distill decades of research and practice into actionable
|
||||
frameworks communities can actually use.
|
||||
</p>
|
||||
<p>
|
||||
These knowledge packets become the seeds of{" "}
|
||||
<strong>open source protocol toolkits</strong> — 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.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Flow Funding */}
|
||||
{/* Data Flows - New Section */}
|
||||
<div
|
||||
className="section-reveal max-w-3xl mx-auto space-y-6"
|
||||
style={{ transitionDelay: "0.18s" }}
|
||||
style={{ transitionDelay: "0.15s" }}
|
||||
>
|
||||
<h3 className="font-serif text-2xl sm:text-3xl font-semibold">
|
||||
Flow Funding
|
||||
Data Flows of the Commons
|
||||
</h3>
|
||||
<div className="space-y-4 text-base leading-relaxed opacity-80">
|
||||
<p>
|
||||
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{" "}
|
||||
<em>enmeshed ecologies</em> 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{" "}
|
||||
<strong>trust</strong>, <strong>resources</strong>,{" "}
|
||||
<strong>favors</strong>, and <strong>capital</strong> are all
|
||||
data flows — streams that can be made visible, governed
|
||||
collectively, and managed by communities on self-provisioned
|
||||
infrastructure.
|
||||
</p>
|
||||
<p>
|
||||
At the heart of Flow Funding is a threshold-based model rooted in
|
||||
the concept of <strong>“enoughness”</strong> —
|
||||
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.
|
||||
</p>
|
||||
<p>
|
||||
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.
|
||||
</div>
|
||||
|
||||
<div className="glass-card p-6 sm:p-8 space-y-4">
|
||||
<h4 className="font-serif text-lg font-semibold opacity-70">
|
||||
Community-Owned Infrastructure for Coordination
|
||||
</h4>
|
||||
<div className="grid gap-4 sm:grid-cols-2 font-mono text-sm">
|
||||
<div className="space-y-1">
|
||||
<div className="font-serif text-base font-semibold not-italic">
|
||||
<a
|
||||
href="https://rstack.org"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="domain-link"
|
||||
>
|
||||
rStack
|
||||
</a>
|
||||
</div>
|
||||
<div className="opacity-60">
|
||||
Open source infrastructure stack for community coordination
|
||||
— self-hostable, sovereign, interoperable
|
||||
</div>
|
||||
</div>
|
||||
<div className="space-y-1">
|
||||
<div className="font-serif text-base font-semibold not-italic">
|
||||
<a
|
||||
href="https://yourspace.online"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="domain-link"
|
||||
>
|
||||
(You)rSpace
|
||||
</a>
|
||||
</div>
|
||||
<div className="opacity-60">
|
||||
Community-owned digital spaces — where coordination
|
||||
happens on infrastructure you control
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<p className="text-sm opacity-50 pt-2">
|
||||
When communities own their stack, every data flow becomes a
|
||||
commons resource rather than a corporate asset.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* P4P framework */}
|
||||
{/* P4P Movement */}
|
||||
<div
|
||||
className="section-reveal max-w-3xl mx-auto space-y-6"
|
||||
style={{ transitionDelay: "0.24s" }}
|
||||
style={{ transitionDelay: "0.20s" }}
|
||||
>
|
||||
<h3 className="font-serif text-3xl sm:text-4xl md:text-5xl font-bold text-center">
|
||||
The Birth of the
|
||||
|
|
@ -186,9 +238,12 @@ export function LegacySection() {
|
|||
practice.
|
||||
</p>
|
||||
<p>
|
||||
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.
|
||||
</p>
|
||||
</div>
|
||||
|
|
@ -239,6 +294,81 @@ export function LegacySection() {
|
|||
</div>
|
||||
</div>
|
||||
|
||||
{/* Tools in Active Research */}
|
||||
<div
|
||||
className="section-reveal max-w-3xl mx-auto space-y-6"
|
||||
style={{ transitionDelay: "0.22s" }}
|
||||
>
|
||||
<h3 className="font-serif text-2xl sm:text-3xl font-semibold">
|
||||
Tools in Active Research
|
||||
</h3>
|
||||
<div className="space-y-4 text-base leading-relaxed opacity-80">
|
||||
<p>
|
||||
<strong>Flow Funding</strong> — 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{" "}
|
||||
<em>enmeshed ecologies</em> of inter- and intra-organizational
|
||||
flow — resources circulating continuously between nested
|
||||
communities the way nutrients cycle through a forest floor.
|
||||
</p>
|
||||
<p>
|
||||
The latest research takes the form of{" "}
|
||||
<strong>Threshold-Based Flow Funding (TBFF)</strong>, being
|
||||
developed at{" "}
|
||||
<a
|
||||
href="https://rfunds.online"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="domain-link"
|
||||
>
|
||||
rFunds.online
|
||||
</a>
|
||||
. TBFF models funding pools as dynamic funnels operating across
|
||||
three zones: an <strong>overflow zone</strong> where excess funds
|
||||
automatically redistribute to connected pools, a{" "}
|
||||
<strong>healthy zone</strong> of full flow and balanced
|
||||
operations, and a <strong>critical zone</strong> where outflow
|
||||
restricts to conservation mode. Funnels connect via overflow and
|
||||
spending edges, creating living networks of resource circulation
|
||||
governed by thresholds of{" "}
|
||||
<strong>“enoughness”</strong> rather than
|
||||
accumulation.
|
||||
</p>
|
||||
<p>
|
||||
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.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="glass-card p-6 space-y-3 font-mono text-sm">
|
||||
<div className="font-serif text-base font-semibold not-italic opacity-70">
|
||||
TBFF Zones
|
||||
</div>
|
||||
<div className="grid gap-2 sm:grid-cols-3">
|
||||
<div className="space-y-1">
|
||||
<div className="opacity-50">overflow</div>
|
||||
<div className="opacity-70 text-xs">
|
||||
Above MAX — surplus redistributes to connected funnels
|
||||
</div>
|
||||
</div>
|
||||
<div className="space-y-1">
|
||||
<div style={{ color: "var(--mycelium-green)" }}>healthy</div>
|
||||
<div className="opacity-70 text-xs">
|
||||
Normal ops — full flow rate, balanced funding
|
||||
</div>
|
||||
</div>
|
||||
<div className="space-y-1">
|
||||
<div style={{ color: "var(--compost-amber)" }}>critical</div>
|
||||
<div className="opacity-70 text-xs">
|
||||
Below MIN — outflow restricted, conservation mode
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Pillars */}
|
||||
<div
|
||||
className="section-reveal grid gap-6 sm:grid-cols-2 max-w-3xl mx-auto"
|
||||
|
|
@ -255,7 +385,7 @@ export function LegacySection() {
|
|||
},
|
||||
{
|
||||
title: "Evolve",
|
||||
text: "Update the theoretical frameworks for current conditions. Bridge Web3 and traditional commons movements. Experiment with emerging technologies in service of collective flourishing.",
|
||||
text: "Update the theoretical frameworks for current conditions. Distill research into convivial knowledge packets. Transform insights into open source protocol toolkits that communities can deploy.",
|
||||
},
|
||||
{
|
||||
title: "Propagate",
|
||||
|
|
|
|||
|
|
@ -15,11 +15,27 @@ interface Hypha {
|
|||
branchCount: number
|
||||
}
|
||||
|
||||
interface Spore {
|
||||
x: number
|
||||
y: number
|
||||
vx: number
|
||||
vy: number
|
||||
life: number
|
||||
maxLife: number
|
||||
radius: number
|
||||
}
|
||||
|
||||
export function MycelialCanvas() {
|
||||
const canvasRef = useRef<HTMLCanvasElement>(null)
|
||||
const hyphaeRef = useRef<Hypha[]>([])
|
||||
const sporesRef = useRef<Spore[]>([])
|
||||
const frameRef = useRef<number>(0)
|
||||
const trailCanvasRef = useRef<HTMLCanvasElement | null>(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 (
|
||||
<canvas
|
||||
ref={canvasRef}
|
||||
className="fixed inset-0 pointer-events-none"
|
||||
style={{ zIndex: 0, opacity: 0.55 }}
|
||||
className="fixed inset-0"
|
||||
style={{ zIndex: 0, opacity: 0.6, pointerEvents: "none" }}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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"],
|
||||
|
|
|
|||
|
|
@ -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, 30, 0.85, 0.03, 80, 0.45, 0.12, 60 ], // Hero: deep soil
|
||||
[0.10, 0.10, 0.03, 35, 0.84, 0.03, 80, 0.50, 0.13, 50 ], // Legacy: dark warm earth
|
||||
[0.20, 0.12, 0.04, 40, 0.82, 0.04, 80, 0.55, 0.15, 45 ], // Compost: earth brown
|
||||
[0.35, 0.16, 0.05, 150, 0.88, 0.05, 145, 0.55, 0.18, 155], // Mycelium: forest green
|
||||
[0.48, 0.22, 0.04, 200, 0.90, 0.03, 200, 0.50, 0.14, 220], // Undernet: deep blue
|
||||
[0.60, 0.45, 0.06, 140, 0.15, 0.03, 150, 0.65, 0.18, 145], // Anastomosis: transition
|
||||
[0.78, 0.85, 0.04, 110, 0.15, 0.04, 100, 0.60, 0.16, 90 ], // Emergence: golden light
|
||||
[0.92, 0.94, 0.02, 110, 0.12, 0.03, 100, 0.55, 0.18, 155], // Network Map: canopy
|
||||
[0.0, 0.18, 0.015, 30, 0.88, 0.02, 80, 0.50, 0.10, 60 ], // Hero: warm twilight (lighter)
|
||||
[0.10, 0.16, 0.018, 40, 0.86, 0.02, 80, 0.52, 0.10, 50 ], // Legacy: warm earth
|
||||
[0.20, 0.15, 0.025, 50, 0.84, 0.03, 75, 0.55, 0.11, 45 ], // Compost: amber earth
|
||||
[0.35, 0.18, 0.03, 150, 0.88, 0.03, 145, 0.55, 0.13, 155], // Mycelium: forest green
|
||||
[0.48, 0.22, 0.025, 210, 0.90, 0.02, 200, 0.52, 0.10, 220], // Undernet: deep teal
|
||||
[0.60, 0.45, 0.03, 160, 0.15, 0.02, 150, 0.60, 0.12, 145], // Anastomosis: transition
|
||||
[0.78, 0.82, 0.025, 110, 0.15, 0.03, 100, 0.58, 0.12, 90 ], // Emergence: golden light
|
||||
[0.92, 0.92, 0.015, 120, 0.12, 0.02, 100, 0.55, 0.13, 155], // Network Map: canopy
|
||||
]
|
||||
|
||||
function lerp(a: number, b: number, t: number) {
|
||||
|
|
|
|||
Loading…
Reference in New Issue