feat: Add presentations page with shareable anchor links, new research images

- Add /presentations page with all 11 talks from canvas-website
- Each title is a clickable #hash anchor that copies shareable URL
- Auto-scrolls to hash target on page load
- Styled to match home page: cursor effect, animated blobs, tags, glass cards
- Replace 6 generic AI stock images with custom dark-theme illustrations
  matching the site's purple/teal color palette
- Add Presentations nav button to hero section
- Add sonner Toaster for copy-link toast notifications

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Jeff Emmett 2026-02-12 22:10:02 -07:00
parent 874257a29b
commit ab7bd076de
10 changed files with 275 additions and 6 deletions

View File

@ -2,6 +2,7 @@ import type React from "react"
import type { Metadata } from "next"
import { Inter, Space_Mono } from "next/font/google"
import { Analytics } from "@vercel/analytics/next"
import { Toaster } from "sonner"
import "./globals.css"
const inter = Inter({
@ -48,6 +49,7 @@ export default function RootLayout({
<html lang="en">
<body className={`${inter.variable} ${spaceMono.variable} font-sans antialiased`}>
{children}
<Toaster richColors position="bottom-center" />
<Analytics />
</body>
</html>

261
app/presentations/page.tsx Normal file
View File

@ -0,0 +1,261 @@
"use client"
import { useEffect } from "react"
import { Link2, ExternalLink, ArrowLeft } from "lucide-react"
import { Card } from "@/components/ui/card"
import { CursorEffect } from "@/components/cursor-effect"
import { toast } from "sonner"
const presentations = [
{
id: "osmotic-governance",
title: "Osmotic Governance",
description: "Exploring the intersection of mycelium and emancipatory technologies",
embedUrl: "https://online.fliphtml5.com/phqos/xfym/",
venue: "Team Human with Douglas Rushkoff",
videoUrl: "https://www.teamhuman.fm/episodes/238-jeff-emmett",
videoLabel: "Listen to the full episode",
tags: ["Mycelium", "Governance", "Emancipatory Tech"],
},
{
id: "exploring-mycofi",
title: "Exploring MycoFi",
description: "Mycelial design patterns for Web3 and beyond",
embedUrl: "https://online.fliphtml5.com/phqos/bqra/",
venue: "DevCon 7 in Bangkok",
videoUrl: "https://www.youtube.com/watch?v=0A4jXL5eBaI",
videoLabel: "Watch the full talk",
tags: ["MycoFi", "Web3", "Biomimicry"],
},
{
id: "mycofi-cofi-gathering",
title: "MycoFi talk at CoFi Gathering",
description: "Mycelial design patterns for Web3 and beyond",
embedUrl: "https://online.fliphtml5.com/phqos/vwmt/",
venue: "Greenpill Network",
videoUrl: "https://www.youtube.com/watch?v=AFJFDajuCSg",
videoLabel: "Watch the full talk",
tags: ["MycoFi", "Greenpill", "CoFi"],
},
{
id: "myco-mutualism",
title: "Myco-Mutualism",
description: "Exploring mutualistic relationships in mycelial networks and their applications to human systems",
embedUrl: "https://online.fliphtml5.com/phqos/caal/",
venue: "The Mutualist Society",
tags: ["Mutualism", "Mycelium", "Systems Design"],
},
{
id: "psilocybernetics",
title: "Psilocybernetics: The Emergence of Institutional Neuroplasticity",
description: "Exploring the intersection of mycelium and cybernetic institutional design",
embedUrl: "https://online.fliphtml5.com/phqos/pnlz/",
venue: "General Forum for Ethereum Localism",
tags: ["Cybernetics", "Institutions", "Neuroplasticity"],
},
{
id: "move-slow-fix-things",
title: "Move Slow & Fix Things: The Commons Stack Design Pattern",
description: "Design patterns for sustainable commons infrastructure",
embedUrl: "https://online.fliphtml5.com/phqos/bnnf/",
venue: "ReFi Unconf @ the Commons Hub Austria",
videoUrl: "https://www.youtube.com/live/i8qcg7FfpLM?si=onLcl8q5rz7cMViO&t=1362",
videoLabel: "Watch the full talk",
tags: ["Commons Stack", "ReFi", "Design Patterns"],
},
{
id: "commons-stack-launch",
title: "Commons Stack Launch & Open Sourcing cadCAD",
description: "The launch of Commons Stack and the open sourcing of cadCAD for token engineering",
embedUrl: "https://online.fliphtml5.com/phqos/hxac/",
venue: "Token Engineering Global Gathering (TEGG)",
videoUrl: "https://youtu.be/qjdjX2m_p0Q?si=r2AXVnVyzCIxIOSc&t=20",
videoLabel: "Watch the full talk",
tags: ["Commons Stack", "cadCAD", "Token Engineering"],
},
{
id: "conviction-voting",
title: "New Tools for Dynamic Collective Intelligence: Conviction Voting & Variations",
description: "Exploring innovative voting mechanisms for collective decision-making in decentralized systems",
embedUrl: "https://online.fliphtml5.com/phqos/fhos/",
venue: "Conviction Voting Presentation",
tags: ["Conviction Voting", "Governance", "Collective Intelligence"],
},
{
id: "polycentric-governance",
title: "Exploring Polycentric Governance in Web3 Ecosystems",
description: "Understanding multi-level governance structures in decentralized networks",
embedUrl: "https://online.fliphtml5.com/phqos/zzoy/",
venue: "OpenWeb Hackathon",
videoUrl: "https://youtu.be/ZIWskNogafg?si=DmUbOQJaSRE1rdzq",
videoLabel: "Watch the full talk",
tags: ["Polycentric Governance", "Web3", "Ostrom"],
},
{
id: "mycofi-myco-munnities",
title: "MycoFi for Myco-munnities",
description: "Exploring mycelial financial systems for community-based organizations",
embedUrl: "https://online.fliphtml5.com/phqos/xoea/",
venue: "CoFi Gathering in Liege",
tags: ["MycoFi", "Community Finance", "CoFi"],
},
{
id: "community-resilience",
title: "Building Community Resilience in an Age of Crisis",
description: "Internet outages during crises can disrupt communication, education, and access to vital information. Preparing for such disruptions is essential for communities operating in challenging environments.",
embedUrl: "https://online.fliphtml5.com/phqos/afbp/",
venue: "re:publica conference, May 2025",
videoUrl: "https://www.youtube.com/watch?v=rTOLk7k9Ad8",
videoLabel: "Watch the full talk",
tags: ["Resilience", "Crisis Response", "Community Networks"],
},
]
function copyLink(id: string) {
const url = `${window.location.origin}/presentations#${id}`
navigator.clipboard.writeText(url).then(() => {
toast.success("Link copied to clipboard")
})
}
export default function PresentationsPage() {
useEffect(() => {
if (window.location.hash) {
const id = window.location.hash.slice(1)
const el = document.getElementById(id)
if (el) {
setTimeout(() => {
el.scrollIntoView({ behavior: "smooth", block: "start" })
}, 100)
}
}
}, [])
return (
<>
<CursorEffect />
<main className="relative min-h-screen bg-background text-foreground">
{/* Animated background blobs */}
<div className="fixed inset-0 overflow-hidden opacity-15 pointer-events-none">
<div className="absolute top-1/4 left-1/3 h-[500px] w-[500px] rounded-full bg-primary blur-[150px] animate-float" />
<div
className="absolute bottom-1/3 right-1/4 h-[400px] w-[400px] rounded-full bg-accent blur-[150px]"
style={{ animationDelay: "3s" }}
/>
</div>
{/* Header */}
<div className="relative z-10 border-b border-border/50 bg-background/80 backdrop-blur-sm">
<div className="max-w-5xl mx-auto px-6 py-4 flex items-center justify-between">
<a
href="/"
className="inline-flex items-center gap-2 text-sm text-muted-foreground hover:text-primary transition-colors"
>
<ArrowLeft className="h-4 w-4" />
Jeff Emmett
</a>
<span className="text-sm font-mono text-muted-foreground border border-border px-3 py-1 rounded-full">
{"{ Presentations }"}
</span>
</div>
</div>
{/* Hero */}
<div className="relative z-10 max-w-5xl mx-auto px-6 pt-20 pb-16">
<h1 className="text-5xl md:text-6xl font-bold mb-6">Presentations</h1>
<p className="text-xl text-muted-foreground max-w-2xl text-balance leading-relaxed">
Research into the intersection of mycelium networks, emancipatory technologies,
and convivial tooling. Designing systems that support collective action and
community self-organization.
</p>
</div>
{/* Presentations grid */}
<div className="relative z-10 max-w-5xl mx-auto px-6 pb-32">
<div className="space-y-10">
{presentations.map((p) => (
<Card
key={p.id}
id={p.id}
className="group/card overflow-hidden bg-card/80 backdrop-blur-sm border-border hover:border-primary/50 transition-all duration-300 scroll-mt-24"
>
<div className="p-6 pb-4">
<h2 className="text-2xl font-semibold group-hover/card:text-primary transition-colors">
<a
href={`#${p.id}`}
onClick={(e) => {
e.preventDefault()
window.history.replaceState(null, "", `#${p.id}`)
document.getElementById(p.id)?.scrollIntoView({ behavior: "smooth", block: "start" })
copyLink(p.id)
}}
className="group/link inline-flex items-start gap-2"
>
<span>{p.title}</span>
<Link2 className="h-5 w-5 mt-1 opacity-0 group-hover/link:opacity-100 text-muted-foreground transition-opacity shrink-0" />
</a>
</h2>
<p className="text-muted-foreground mt-2 leading-relaxed">{p.description}</p>
{p.tags && (
<div className="flex flex-wrap gap-2 mt-3">
{p.tags.map((tag, i) => (
<span
key={i}
className="text-xs font-mono px-3 py-1 bg-secondary text-secondary-foreground rounded-full"
>
{tag}
</span>
))}
</div>
)}
</div>
<div className="px-6 pb-4">
<div className="rounded-lg overflow-hidden border border-border/50">
<div style={{ position: "relative", paddingTop: "max(60%, 324px)", width: "100%", height: 0 }}>
<iframe
style={{ position: "absolute", border: "none", width: "100%", height: "100%", left: 0, top: 0 }}
src={p.embedUrl}
seamless
scrolling="no"
frameBorder="0"
allowTransparency
allowFullScreen
title={p.title}
/>
</div>
</div>
</div>
<div className="px-6 pb-6 flex flex-wrap items-center justify-between gap-3 border-t border-border/30 pt-4 mx-6">
<span className="text-sm text-muted-foreground italic font-mono">{p.venue}</span>
{p.videoUrl ? (
<a
href={p.videoUrl}
target="_blank"
rel="noopener noreferrer"
className="group/ext inline-flex items-center gap-1.5 text-sm font-medium px-4 py-2 bg-secondary text-secondary-foreground rounded-lg transition-all hover:scale-105 hover:bg-primary hover:text-primary-foreground"
>
{p.videoLabel} <ExternalLink className="h-3.5 w-3.5" />
</a>
) : (
<span className="text-sm text-muted-foreground">Video coming soon</span>
)}
</div>
</Card>
))}
</div>
</div>
{/* Footer */}
<div className="relative z-10 border-t border-border py-8 bg-card/30">
<div className="max-w-5xl mx-auto px-6 text-center">
<p className="text-muted-foreground font-mono text-sm">
© 2025 Jeff Emmett. Built with Next.js & TailwindCSS
</p>
</div>
</div>
</main>
</>
)
}

View File

@ -62,6 +62,12 @@ export function HeroSection() {
<span className="relative z-10">View Research</span>
<div className="absolute inset-0 bg-accent opacity-0 group-hover:opacity-100 transition-opacity" />
</a>
<a
href="/presentations"
className="px-8 py-4 bg-secondary text-secondary-foreground rounded-lg font-medium transition-all hover:scale-105 hover:bg-secondary/80"
>
Presentations
</a>
<a
href="#contact"
className="px-8 py-4 bg-secondary text-secondary-foreground rounded-lg font-medium transition-all hover:scale-105 hover:bg-secondary/80"

View File

@ -6,42 +6,42 @@ const projects = [
description:
"Cyber-physical commons architecture translating Ostrom's principles into DAO templates. Building open-source, token engineered component libraries for communal management of public goods.",
tags: ["Token Engineering", "DAOs", "Ostrom Compliance", "Public Goods"],
image: "/commons-stack-dao-governance-blockchain.jpg",
image: "/commons-stack.png",
},
{
title: "Bonding Curve Research Group",
description:
"Research and development of Primary Issuance Markets enabling dynamic token supply. Challenging fixed supply paradigms with adaptive mechanisms that dampen volatility.",
tags: ["Bonding Curves", "cadCAD", "Token Economics", "DeFi"],
image: "/bonding-curve-token-economics-chart.jpg",
image: "/bonding-curves.png",
},
{
title: "MycoFi & Mycoeconomics",
description:
"Economic systems inspired by fungal networks. Regenerative protocols built on cooperation, mutual aid, and permaculture currency principles. Author of book.mycofi.earth.",
tags: ["Regenerative Economics", "Biomimicry", "Permaculture", "Web3"],
image: "/mycelium-network-nature-fungal.jpg",
image: "/mycofi-mycelium.png",
},
{
title: "Conviction Voting",
description:
"Novel continuous decision-making mechanism for DAO governance. Eliminates time-boxed voting attack vectors while increasing community participation and long-term alignment.",
tags: ["Governance", "Voting Systems", "Social Sensor Fusion", "cadCAD"],
image: "/conviction-voting-governance-dashboard.jpg",
image: "/conviction-voting.png",
},
{
title: "Augmented Bonding Curves",
description:
"Primary Issuance Markets that create economic boundaries for commons ecosystems. Enables continuous fundraising, algorithmic liquidity, and price volatility dampening.",
tags: ["Token Design", "AMMs", "Cryptoeconomics", "Funding Mechanisms"],
image: "/augmented-bonding-curve-economic-system.jpg",
image: "/augmented-bonding-curve.png",
},
{
title: "Token Engineering Commons",
description:
"First field test of Commons Stack components. Outperformed other public goods tokens in risk-adjusted returns, demonstrating benefits of primary issuance markets.",
tags: ["DAO", "TEC", "Token Engineering", "Community Governance"],
image: "/token-engineering-community-collaborative.jpg",
image: "/token-engineering-commons.png",
},
]

Binary file not shown.

After

Width:  |  Height:  |  Size: 559 KiB

BIN
public/bonding-curves.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 554 KiB

BIN
public/commons-stack.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 486 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 856 KiB

BIN
public/mycofi-mycelium.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 549 KiB