Remove bright gradient bands, fix Sankey data, add newsletter CTA
- Replace bright gradient section backgrounds with flat bg-deep - Remove wave distortion (showDistortion=false) from all diagrams - Fix circular link errors in naturalFlows by breaking feedback cycles - Add multi-dimensional flow colors (energy, resource, signal, commons) - Update CTA: "Dive into the Current" with newsletter subscription - Newsletter posts to listmonk via newsletter-api (FlowFi list #26) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
35ada4127d
commit
a08a6bdb69
|
|
@ -1,8 +1,37 @@
|
|||
'use client'
|
||||
|
||||
import { useState, FormEvent } from 'react'
|
||||
import ScrollReveal from '@/components/ui/ScrollReveal'
|
||||
|
||||
const FLOWFI_LIST_UUID = 'fefebe2c-0966-4df5-81ec-1eae9b9dce3f'
|
||||
const SUBSCRIBE_URL = 'https://newsletter.jeffemmett.com/subscribe'
|
||||
|
||||
export default function CTASection() {
|
||||
const [email, setEmail] = useState('')
|
||||
const [status, setStatus] = useState<'idle' | 'loading' | 'success' | 'error'>('idle')
|
||||
|
||||
async function handleSubmit(e: FormEvent) {
|
||||
e.preventDefault()
|
||||
if (!email) return
|
||||
|
||||
setStatus('loading')
|
||||
try {
|
||||
const res = await fetch(SUBSCRIBE_URL, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ email, list_uuid: FLOWFI_LIST_UUID }),
|
||||
})
|
||||
if (res.ok) {
|
||||
setStatus('success')
|
||||
setEmail('')
|
||||
} else {
|
||||
setStatus('error')
|
||||
}
|
||||
} catch {
|
||||
setStatus('error')
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<section className="min-h-[60vh] flex flex-col items-center justify-center relative px-4 py-24">
|
||||
<div className="absolute inset-0 bg-gradient-to-b from-deep to-ocean" />
|
||||
|
|
@ -21,18 +50,49 @@ export default function CTASection() {
|
|||
</ScrollReveal>
|
||||
|
||||
<ScrollReveal delay={0.2}>
|
||||
<p className="font-caveat text-2xl text-foam/35 mb-14">
|
||||
You already are.
|
||||
<p className="font-caveat text-2xl text-foam/35 mb-10">
|
||||
Dive into the current.
|
||||
</p>
|
||||
</ScrollReveal>
|
||||
|
||||
<ScrollReveal delay={0.3}>
|
||||
{status === 'success' ? (
|
||||
<p className="text-flow/70 text-sm font-light mb-10">
|
||||
You're in the current now. Welcome.
|
||||
</p>
|
||||
) : (
|
||||
<form onSubmit={handleSubmit} className="flex flex-col sm:flex-row gap-3 justify-center items-center mb-10 max-w-md mx-auto">
|
||||
<input
|
||||
type="email"
|
||||
value={email}
|
||||
onChange={e => setEmail(e.target.value)}
|
||||
placeholder="your@email.com"
|
||||
required
|
||||
className="w-full sm:flex-1 bg-ocean/40 border border-flow/15 rounded-full px-6 py-3 text-foam/70 placeholder:text-mist/25 text-sm font-light focus:outline-none focus:border-flow/40 focus:bg-ocean/60 transition-all duration-500"
|
||||
/>
|
||||
<button
|
||||
type="submit"
|
||||
disabled={status === 'loading'}
|
||||
className="border border-flow/25 px-8 py-3 text-foam/50 hover:text-flow/80 hover:border-flow/50 hover:bg-flow/5 transition-all duration-500 text-sm rounded-full font-light disabled:opacity-40 whitespace-nowrap"
|
||||
>
|
||||
{status === 'loading' ? 'Diving in...' : 'Subscribe'}
|
||||
</button>
|
||||
</form>
|
||||
)}
|
||||
{status === 'error' && (
|
||||
<p className="text-anti-green/50 text-xs font-light mb-6">
|
||||
Something went wrong. Try again?
|
||||
</p>
|
||||
)}
|
||||
</ScrollReveal>
|
||||
|
||||
<ScrollReveal delay={0.4}>
|
||||
<p className="text-mist/25 text-sm mb-10 tracking-wide font-light">
|
||||
NoFi → FlowFi → ???
|
||||
</p>
|
||||
</ScrollReveal>
|
||||
|
||||
<ScrollReveal delay={0.4}>
|
||||
<ScrollReveal delay={0.5}>
|
||||
<a
|
||||
href="https://nofi.lol"
|
||||
className="inline-block border border-flow/15 px-10 py-4 text-foam/30 hover:text-flow/60 hover:border-flow/40 hover:bg-flow/5 transition-all duration-700 text-sm rounded-full font-light"
|
||||
|
|
|
|||
|
|
@ -8,16 +8,13 @@ import { extractiveFlows } from '@/lib/sankey-data'
|
|||
export default function ExtractivePipeSection() {
|
||||
return (
|
||||
<section className="min-h-screen flex flex-col items-center justify-center relative px-4 py-24">
|
||||
<div className="absolute inset-0 bg-gradient-to-b from-deep via-current to-deep" />
|
||||
|
||||
{/* Red pollution tint — subtle, unsettling */}
|
||||
<div className="absolute inset-0" style={{ background: 'radial-gradient(ellipse at 50% 40%, rgba(233, 69, 96, 0.06) 0%, transparent 60%)' }} />
|
||||
<div className="absolute inset-0 bg-deep" />
|
||||
|
||||
<div className="relative z-10 max-w-5xl w-full text-center">
|
||||
<SectionHeader className="text-anti-green/80">The Extractive Pattern</SectionHeader>
|
||||
|
||||
<ScrollReveal delay={0.2}>
|
||||
<div className="my-14 rounded-2xl overflow-hidden p-4 bg-current/30 border border-anti-green/10">
|
||||
<div className="my-14 rounded-2xl overflow-hidden p-4 bg-ocean/20 border border-anti-green/8">
|
||||
<SankeyDiagram
|
||||
data={extractiveFlows}
|
||||
showLabels={true}
|
||||
|
|
|
|||
|
|
@ -8,25 +8,28 @@ import { naturalFlows } from '@/lib/sankey-data'
|
|||
export default function NatureFlowsSection() {
|
||||
return (
|
||||
<section className="min-h-screen flex flex-col items-center justify-center relative px-4 py-24">
|
||||
<div className="absolute inset-0 bg-gradient-to-b from-deep via-ocean to-deep" />
|
||||
|
||||
{/* Subtle teal ambient light */}
|
||||
<div
|
||||
className="absolute top-1/3 left-1/4 w-[500px] h-[500px] rounded-full opacity-30"
|
||||
style={{ background: 'radial-gradient(circle, rgba(45, 212, 191, 0.06) 0%, transparent 70%)' }}
|
||||
/>
|
||||
<div className="absolute inset-0 bg-deep" />
|
||||
|
||||
<div className="relative z-10 max-w-5xl w-full text-center">
|
||||
<SectionHeader>Natural Flows</SectionHeader>
|
||||
|
||||
<ScrollReveal delay={0.1}>
|
||||
<div className="flex justify-center gap-6 mb-6 text-xs font-light">
|
||||
<span className="flex items-center gap-1.5"><span className="w-3 h-0.5 rounded bg-[#fbbf24]/60 inline-block" /> Energy</span>
|
||||
<span className="flex items-center gap-1.5"><span className="w-3 h-0.5 rounded bg-flow/60 inline-block" /> Resources</span>
|
||||
<span className="flex items-center gap-1.5"><span className="w-3 h-0.5 rounded bg-[#f472b6]/60 inline-block" /> Signals</span>
|
||||
<span className="flex items-center gap-1.5"><span className="w-3 h-0.5 rounded bg-mist/60 inline-block" /> Commons</span>
|
||||
</div>
|
||||
</ScrollReveal>
|
||||
|
||||
<ScrollReveal delay={0.2}>
|
||||
<div className="my-14 rounded-2xl overflow-hidden p-4 bg-ocean/30">
|
||||
<div className="my-8 rounded-2xl overflow-hidden p-4 bg-ocean/20">
|
||||
<SankeyDiagram
|
||||
data={naturalFlows}
|
||||
showLabels={false}
|
||||
showLabels={true}
|
||||
speed="slow"
|
||||
showParticles={true}
|
||||
showDistortion={true}
|
||||
showDistortion={false}
|
||||
maxParticles={8}
|
||||
/>
|
||||
</div>
|
||||
|
|
@ -34,7 +37,7 @@ export default function NatureFlowsSection() {
|
|||
|
||||
<ScrollReveal delay={0.4}>
|
||||
<p className="font-caveat text-xl md:text-2xl text-foam/45 max-w-2xl mx-auto leading-relaxed">
|
||||
In living systems, value doesn't accumulate. It <span className="text-flow/70">circulates</span>.
|
||||
In living systems, value doesn't accumulate. It <span className="text-flow/70">circulates</span> — across dimensions.
|
||||
</p>
|
||||
</ScrollReveal>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -8,25 +8,27 @@ import { regenerativeFlows } from '@/lib/sankey-data'
|
|||
export default function RegenerativeSection() {
|
||||
return (
|
||||
<section className="min-h-screen flex flex-col items-center justify-center relative px-4 py-24">
|
||||
<div className="absolute inset-0 bg-gradient-to-b from-deep via-ocean to-deep" />
|
||||
|
||||
{/* Green life glow */}
|
||||
<div
|
||||
className="absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 w-[700px] h-[500px] rounded-full"
|
||||
style={{ background: 'radial-gradient(ellipse, rgba(45, 212, 191, 0.06) 0%, transparent 60%)' }}
|
||||
/>
|
||||
<div className="absolute inset-0 bg-deep" />
|
||||
|
||||
<div className="relative z-10 max-w-5xl w-full text-center">
|
||||
<SectionHeader>The Regenerative Alternative</SectionHeader>
|
||||
|
||||
<ScrollReveal delay={0.1}>
|
||||
<div className="flex justify-center gap-6 mb-6 text-xs font-light">
|
||||
<span className="flex items-center gap-1.5"><span className="w-3 h-0.5 rounded bg-flow/60 inline-block" /> Economic</span>
|
||||
<span className="flex items-center gap-1.5"><span className="w-3 h-0.5 rounded bg-[#a78bfa]/60 inline-block" /> Governance</span>
|
||||
<span className="flex items-center gap-1.5"><span className="w-3 h-0.5 rounded bg-[#60a5fa]/60 inline-block" /> Data</span>
|
||||
</div>
|
||||
</ScrollReveal>
|
||||
|
||||
<ScrollReveal delay={0.2}>
|
||||
<div className="my-14 rounded-2xl overflow-hidden p-4 bg-ocean/30 border border-flow/10">
|
||||
<div className="my-8 rounded-2xl overflow-hidden p-4 bg-ocean/20 border border-flow/8">
|
||||
<SankeyDiagram
|
||||
data={regenerativeFlows}
|
||||
showLabels={true}
|
||||
speed="normal"
|
||||
showParticles={true}
|
||||
showDistortion={true}
|
||||
showDistortion={false}
|
||||
maxParticles={8}
|
||||
/>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ const lines = [
|
|||
export default function TransitionSection() {
|
||||
return (
|
||||
<section className="min-h-screen flex flex-col items-center justify-center relative px-4 py-24">
|
||||
<div className="absolute inset-0 bg-gradient-to-b from-deep via-current to-deep" />
|
||||
<div className="absolute inset-0 bg-deep" />
|
||||
|
||||
{/* Flowing light streak */}
|
||||
<div
|
||||
|
|
|
|||
|
|
@ -155,10 +155,11 @@ export default function SankeyDiagram({
|
|||
y={((node.y0 ?? 0) + (node.y1 ?? 0)) / 2}
|
||||
textAnchor={(node.x0 ?? 0) < width / 2 ? 'start' : 'end'}
|
||||
dominantBaseline="middle"
|
||||
fill="#f5f5dc"
|
||||
fontSize={12}
|
||||
fontFamily="'Courier New', monospace"
|
||||
opacity={0.7}
|
||||
fill="#e0f2f1"
|
||||
fontSize={11}
|
||||
fontFamily="'Outfit', system-ui, sans-serif"
|
||||
fontWeight={300}
|
||||
opacity={0.65}
|
||||
>
|
||||
{node.label}
|
||||
</text>
|
||||
|
|
|
|||
|
|
@ -1,47 +1,53 @@
|
|||
import { FlowData } from './types'
|
||||
|
||||
// S2: Natural flows — abstract organic Sankey (unlabeled, acyclic)
|
||||
// Represents sunlight/rain → photosynthesis/absorption → distribution → endpoints
|
||||
// Flow dimension colors:
|
||||
// Economic = teal (#2dd4bf)
|
||||
// Governance/Delegation = purple (#a78bfa)
|
||||
// Data/Knowledge = blue (#60a5fa)
|
||||
// Energy/Resources = amber (#fbbf24)
|
||||
|
||||
// S2: Multi-dimensional flows in a living system
|
||||
// Same nodes participate in multiple flow types
|
||||
// Note: d3-sankey requires acyclic graphs, so feedback loops are
|
||||
// represented with separate source/sink nodes (e.g. soil-in → soil-out)
|
||||
export const naturalFlows: FlowData = {
|
||||
nodes: [
|
||||
{ id: 'sun', color: '#fbbf24' },
|
||||
{ id: 'rain', color: '#60a5fa' },
|
||||
{ id: 'photo', color: '#34d399' },
|
||||
{ id: 'soil', color: '#c3b091' },
|
||||
{ id: 'canopy', color: '#34d399' },
|
||||
{ id: 'roots', color: '#a78bfa' },
|
||||
{ id: 'stream', color: '#60a5fa' },
|
||||
{ id: 'mycelium', color: '#a78bfa' },
|
||||
{ id: 'fauna', color: '#f59e0b' },
|
||||
{ id: 'atmosphere', color: '#94a3b8' },
|
||||
{ id: 'humus', color: '#92704f' },
|
||||
{ id: 'sun', label: 'Energy', color: '#fbbf24' },
|
||||
{ id: 'water', label: 'Water', color: '#38bdf8' },
|
||||
{ id: 'soil', label: 'Substrate', color: '#c3b091' },
|
||||
{ id: 'producers', label: 'Producers', color: '#34d399' },
|
||||
{ id: 'consumers', label: 'Consumers', color: '#60a5fa' },
|
||||
{ id: 'decomposers', label: 'Decomposers', color: '#a78bfa' },
|
||||
{ id: 'signals', label: 'Signals', color: '#f472b6' },
|
||||
{ id: 'nutrients', label: 'Nutrients', color: '#c3b091' },
|
||||
{ id: 'commons', label: 'Commons', color: '#94a3b8' },
|
||||
],
|
||||
links: [
|
||||
{ source: 'sun', target: 'photo', value: 8, color: '#fbbf2480' },
|
||||
{ source: 'sun', target: 'canopy', value: 4, color: '#fbbf2440' },
|
||||
{ source: 'rain', target: 'stream', value: 5, color: '#60a5fa80' },
|
||||
{ source: 'rain', target: 'soil', value: 6, color: '#60a5fa60' },
|
||||
{ source: 'photo', target: 'canopy', value: 5, color: '#34d39980' },
|
||||
{ source: 'photo', target: 'roots', value: 3, color: '#34d39960' },
|
||||
{ source: 'soil', target: 'roots', value: 4, color: '#c3b09180' },
|
||||
{ source: 'soil', target: 'mycelium', value: 3, color: '#c3b09160' },
|
||||
{ source: 'roots', target: 'mycelium', value: 3, color: '#a78bfa80' },
|
||||
{ source: 'canopy', target: 'atmosphere', value: 4, color: '#34d39960' },
|
||||
{ source: 'canopy', target: 'fauna', value: 3, color: '#34d39940' },
|
||||
{ source: 'mycelium', target: 'humus', value: 4, color: '#a78bfa60' },
|
||||
{ source: 'stream', target: 'atmosphere', value: 3, color: '#60a5fa60' },
|
||||
{ source: 'fauna', target: 'humus', value: 2, color: '#f59e0b60' },
|
||||
{ source: 'roots', target: 'humus', value: 2, color: '#a78bfa40' },
|
||||
// Energy flows (amber)
|
||||
{ source: 'sun', target: 'producers', value: 10, color: '#fbbf2460' },
|
||||
{ source: 'producers', target: 'consumers', value: 6, color: '#fbbf2440' },
|
||||
{ source: 'consumers', target: 'decomposers', value: 4, color: '#fbbf2430' },
|
||||
// Resource flows (teal)
|
||||
{ source: 'soil', target: 'producers', value: 6, color: '#2dd4bf50' },
|
||||
{ source: 'water', target: 'producers', value: 5, color: '#38bdf850' },
|
||||
{ source: 'decomposers', target: 'nutrients', value: 5, color: '#2dd4bf40' },
|
||||
// Information/signal flows (pink)
|
||||
{ source: 'producers', target: 'signals', value: 3, color: '#f472b640' },
|
||||
{ source: 'signals', target: 'consumers', value: 3, color: '#f472b640' },
|
||||
{ source: 'signals', target: 'decomposers', value: 2, color: '#f472b630' },
|
||||
// Commons flows (grey-blue)
|
||||
{ source: 'consumers', target: 'commons', value: 3, color: '#94a3b840' },
|
||||
{ source: 'producers', target: 'commons', value: 4, color: '#94a3b830' },
|
||||
],
|
||||
}
|
||||
|
||||
// S3: Extractive pattern — finance funnel (labeled, acyclic)
|
||||
// S3: Extractive pattern — all dimensions funnel through one bottleneck
|
||||
export const extractiveFlows: FlowData = {
|
||||
nodes: [
|
||||
{ id: 'labor', label: 'Labor', color: '#e9456060' },
|
||||
{ id: 'creativity', label: 'Creativity', color: '#e9456060' },
|
||||
{ id: 'nature', label: 'Nature', color: '#e9456060' },
|
||||
{ id: 'communities', label: 'Communities', color: '#e9456060' },
|
||||
{ id: 'labor', label: 'Labor', color: '#e9456050' },
|
||||
{ id: 'data', label: 'Data', color: '#e9456050' },
|
||||
{ id: 'nature', label: 'Nature', color: '#e9456050' },
|
||||
{ id: 'governance', label: 'Governance', color: '#e9456050' },
|
||||
{ id: 'finance', label: 'Finance', color: '#e94560' },
|
||||
{ id: 'shareholders', label: 'Shareholders', color: '#e94560cc' },
|
||||
{ id: 'executives', label: 'Executives', color: '#e94560cc' },
|
||||
|
|
@ -49,46 +55,53 @@ export const extractiveFlows: FlowData = {
|
|||
{ id: 'public-good', label: 'Public Good', color: '#e9456030' },
|
||||
],
|
||||
links: [
|
||||
{ source: 'labor', target: 'finance', value: 10, color: '#e9456040' },
|
||||
{ source: 'creativity', target: 'finance', value: 8, color: '#e9456040' },
|
||||
{ source: 'nature', target: 'finance', value: 12, color: '#e9456040' },
|
||||
{ source: 'communities', target: 'finance', value: 6, color: '#e9456040' },
|
||||
{ source: 'finance', target: 'shareholders', value: 15, color: '#e9456080' },
|
||||
{ source: 'finance', target: 'executives', value: 12, color: '#e9456080' },
|
||||
{ source: 'finance', target: 'tax-havens', value: 7, color: '#e9456060' },
|
||||
{ source: 'finance', target: 'public-good', value: 2, color: '#e9456020' },
|
||||
// Economic flows in (muted red)
|
||||
{ source: 'labor', target: 'finance', value: 10, color: '#e9456035' },
|
||||
{ source: 'nature', target: 'finance', value: 12, color: '#e9456035' },
|
||||
// Data flows in (muted red-blue)
|
||||
{ source: 'data', target: 'finance', value: 8, color: '#e9456030' },
|
||||
// Delegation captured (muted red-purple)
|
||||
{ source: 'governance', target: 'finance', value: 6, color: '#e9456028' },
|
||||
// All flows out through narrow channels
|
||||
{ source: 'finance', target: 'shareholders', value: 16, color: '#e9456070' },
|
||||
{ source: 'finance', target: 'executives', value: 12, color: '#e9456060' },
|
||||
{ source: 'finance', target: 'tax-havens', value: 6, color: '#e9456050' },
|
||||
{ source: 'finance', target: 'public-good', value: 2, color: '#e9456018' },
|
||||
],
|
||||
}
|
||||
|
||||
// S4: Regenerative alternative — redistributive mesh (labeled, acyclic)
|
||||
// Uses separate input/output nodes to represent the circular nature without actual cycles
|
||||
// S4: Regenerative — multi-dimensional flows that interconnect
|
||||
// Economic, governance, and knowledge flows between same nodes
|
||||
export const regenerativeFlows: FlowData = {
|
||||
nodes: [
|
||||
{ id: 'commons-in', label: 'Commons', color: '#2dd4bf' },
|
||||
{ id: 'labor-r', label: 'Labor', color: '#2dd4bfcc' },
|
||||
{ id: 'commons', label: 'Commons', color: '#2dd4bf' },
|
||||
{ id: 'labor-r', label: 'Workers', color: '#2dd4bfbb' },
|
||||
{ id: 'ecology', label: 'Ecology', color: '#34d399' },
|
||||
{ id: 'care', label: 'Care', color: '#a78bfa' },
|
||||
{ id: 'creativity-r', label: 'Creativity', color: '#60a5fa' },
|
||||
{ id: 'data-r', label: 'Data', color: '#60a5fa' },
|
||||
{ id: 'community', label: 'Community', color: '#fbbf24' },
|
||||
{ id: 'knowledge', label: 'Knowledge', color: '#f472b6' },
|
||||
{ id: 'stewardship', label: 'Stewardship', color: '#34d399cc' },
|
||||
{ id: 'commons-out', label: 'Commons', color: '#2dd4bf' },
|
||||
{ id: 'stewardship', label: 'Stewardship', color: '#34d399bb' },
|
||||
{ id: 'public', label: 'Public Good', color: '#2dd4bf' },
|
||||
],
|
||||
links: [
|
||||
{ source: 'commons-in', target: 'labor-r', value: 5, color: '#2dd4bf60' },
|
||||
{ source: 'commons-in', target: 'ecology', value: 6, color: '#2dd4bf60' },
|
||||
{ source: 'commons-in', target: 'care', value: 5, color: '#2dd4bf60' },
|
||||
{ source: 'commons-in', target: 'creativity-r', value: 4, color: '#2dd4bf60' },
|
||||
{ source: 'labor-r', target: 'community', value: 4, color: '#2dd4bf40' },
|
||||
{ source: 'labor-r', target: 'knowledge', value: 3, color: '#2dd4bf40' },
|
||||
{ source: 'ecology', target: 'stewardship', value: 4, color: '#34d39960' },
|
||||
{ source: 'ecology', target: 'community', value: 3, color: '#34d39940' },
|
||||
{ source: 'care', target: 'community', value: 4, color: '#a78bfa60' },
|
||||
{ source: 'care', target: 'knowledge', value: 3, color: '#a78bfa40' },
|
||||
{ source: 'creativity-r', target: 'knowledge', value: 3, color: '#60a5fa60' },
|
||||
{ source: 'creativity-r', target: 'community', value: 3, color: '#60a5fa40' },
|
||||
{ source: 'community', target: 'commons-out', value: 6, color: '#fbbf2460' },
|
||||
{ source: 'knowledge', target: 'commons-out', value: 4, color: '#f472b660' },
|
||||
{ source: 'stewardship', target: 'commons-out', value: 4, color: '#34d39960' },
|
||||
// Economic flows (teal)
|
||||
{ source: 'commons', target: 'labor-r', value: 5, color: '#2dd4bf45' },
|
||||
{ source: 'commons', target: 'ecology', value: 4, color: '#2dd4bf45' },
|
||||
{ source: 'labor-r', target: 'community', value: 4, color: '#2dd4bf35' },
|
||||
{ source: 'ecology', target: 'stewardship', value: 3, color: '#2dd4bf35' },
|
||||
// Delegation/governance flows (purple)
|
||||
{ source: 'commons', target: 'care', value: 4, color: '#a78bfa40' },
|
||||
{ source: 'care', target: 'community', value: 3, color: '#a78bfa35' },
|
||||
{ source: 'community', target: 'public', value: 5, color: '#a78bfa30' },
|
||||
// Data/knowledge flows (blue)
|
||||
{ source: 'commons', target: 'data-r', value: 4, color: '#60a5fa40' },
|
||||
{ source: 'data-r', target: 'knowledge', value: 4, color: '#60a5fa35' },
|
||||
{ source: 'knowledge', target: 'public', value: 4, color: '#60a5fa30' },
|
||||
// Cross-dimension connections
|
||||
{ source: 'care', target: 'knowledge', value: 2, color: '#a78bfa25' },
|
||||
{ source: 'ecology', target: 'community', value: 2, color: '#34d39930' },
|
||||
{ source: 'stewardship', target: 'public', value: 3, color: '#34d39930' },
|
||||
{ source: 'labor-r', target: 'knowledge', value: 2, color: '#2dd4bf25' },
|
||||
],
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue