revert: Restore original v0 design

Reverts all redesign attempts back to the original v0-generated
personal website design.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Jeff Emmett 2025-12-27 02:11:53 -05:00
parent 033a38a312
commit 15f335ca98
10 changed files with 449 additions and 820 deletions

View File

@ -4,30 +4,79 @@
@custom-variant dark (&:is(.dark *));
:root {
/* Mycelial palette - dark earth, organic warmth */
--background: oklch(0.12 0.02 60);
--foreground: oklch(0.88 0.03 80);
--card: oklch(0.15 0.02 60);
--card-foreground: oklch(0.88 0.03 80);
--popover: oklch(0.14 0.02 60);
--popover-foreground: oklch(0.88 0.03 80);
--primary: oklch(0.72 0.12 85);
--primary-foreground: oklch(0.12 0.02 60);
--secondary: oklch(0.18 0.02 60);
--secondary-foreground: oklch(0.75 0.04 80);
--muted: oklch(0.22 0.02 60);
--muted-foreground: oklch(0.55 0.03 80);
--accent: oklch(0.65 0.10 140);
--accent-foreground: oklch(0.12 0.02 60);
--border: oklch(0.28 0.03 60);
--input: oklch(0.18 0.02 60);
--ring: oklch(0.72 0.12 85);
--radius: 0px;
--background: oklch(0.16 0.01 265);
--foreground: oklch(0.95 0.01 265);
--card: oklch(0.2 0.015 265);
--card-foreground: oklch(0.95 0.01 265);
--popover: oklch(0.2 0.015 265);
--popover-foreground: oklch(0.95 0.01 265);
--primary: oklch(0.7 0.15 265);
--primary-foreground: oklch(0.98 0.01 265);
--secondary: oklch(0.25 0.015 265);
--secondary-foreground: oklch(0.95 0.01 265);
--muted: oklch(0.25 0.015 265);
--muted-foreground: oklch(0.55 0.01 265);
--accent: oklch(0.65 0.18 185);
--accent-foreground: oklch(0.98 0.01 265);
--destructive: oklch(0.577 0.245 27.325);
--destructive-foreground: oklch(0.98 0.01 265);
--border: oklch(0.28 0.015 265);
--input: oklch(0.28 0.015 265);
--ring: oklch(0.7 0.15 265);
--chart-1: oklch(0.7 0.15 265);
--chart-2: oklch(0.65 0.18 185);
--chart-3: oklch(0.6 0.12 145);
--chart-4: oklch(0.75 0.16 285);
--chart-5: oklch(0.65 0.14 225);
--radius: 0.75rem;
--sidebar: oklch(0.985 0 0);
--sidebar-foreground: oklch(0.145 0 0);
--sidebar-primary: oklch(0.205 0 0);
--sidebar-primary-foreground: oklch(0.985 0 0);
--sidebar-accent: oklch(0.97 0 0);
--sidebar-accent-foreground: oklch(0.205 0 0);
--sidebar-border: oklch(0.922 0 0);
--sidebar-ring: oklch(0.708 0 0);
}
.dark {
--background: oklch(0.145 0 0);
--foreground: oklch(0.985 0 0);
--card: oklch(0.145 0 0);
--card-foreground: oklch(0.985 0 0);
--popover: oklch(0.145 0 0);
--popover-foreground: oklch(0.985 0 0);
--primary: oklch(0.985 0 0);
--primary-foreground: oklch(0.205 0 0);
--secondary: oklch(0.269 0 0);
--secondary-foreground: oklch(0.985 0 0);
--muted: oklch(0.269 0 0);
--muted-foreground: oklch(0.708 0 0);
--accent: oklch(0.269 0 0);
--accent-foreground: oklch(0.985 0 0);
--destructive: oklch(0.396 0.141 25.723);
--destructive-foreground: oklch(0.637 0.237 25.331);
--border: oklch(0.269 0 0);
--input: oklch(0.269 0 0);
--ring: oklch(0.439 0 0);
--chart-1: oklch(0.488 0.243 264.376);
--chart-2: oklch(0.696 0.17 162.48);
--chart-3: oklch(0.769 0.188 70.08);
--chart-4: oklch(0.627 0.265 303.9);
--chart-5: oklch(0.645 0.246 16.439);
--sidebar: oklch(0.205 0 0);
--sidebar-foreground: oklch(0.985 0 0);
--sidebar-primary: oklch(0.488 0.243 264.376);
--sidebar-primary-foreground: oklch(0.985 0 0);
--sidebar-accent: oklch(0.269 0 0);
--sidebar-accent-foreground: oklch(0.985 0 0);
--sidebar-border: oklch(0.269 0 0);
--sidebar-ring: oklch(0.439 0 0);
}
@theme inline {
--font-sans: "Inter", system-ui, sans-serif;
--font-mono: "JetBrains Mono", monospace;
--font-sans: "Geist", "Geist Fallback";
--font-mono: "Geist Mono", "Geist Mono Fallback";
--color-background: var(--background);
--color-foreground: var(--foreground);
--color-card: var(--card);
@ -42,56 +91,59 @@
--color-muted-foreground: var(--muted-foreground);
--color-accent: var(--accent);
--color-accent-foreground: var(--accent-foreground);
--color-destructive: var(--destructive);
--color-destructive-foreground: var(--destructive-foreground);
--color-border: var(--border);
--color-input: var(--input);
--color-ring: var(--ring);
--radius-sm: 0;
--radius-md: 0;
--radius-lg: 0;
--color-chart-1: var(--chart-1);
--color-chart-2: var(--chart-2);
--color-chart-3: var(--chart-3);
--color-chart-4: var(--chart-4);
--color-chart-5: var(--chart-5);
--radius-sm: calc(var(--radius) - 4px);
--radius-md: calc(var(--radius) - 2px);
--radius-lg: var(--radius);
--radius-xl: calc(var(--radius) + 4px);
--color-sidebar: var(--sidebar);
--color-sidebar-foreground: var(--sidebar-foreground);
--color-sidebar-primary: var(--sidebar-primary);
--color-sidebar-primary-foreground: var(--sidebar-primary-foreground);
--color-sidebar-accent: var(--sidebar-accent);
--color-sidebar-accent-foreground: var(--sidebar-accent-foreground);
--color-sidebar-border: var(--sidebar-border);
--color-sidebar-ring: var(--sidebar-ring);
}
@layer base {
* {
@apply border-border;
@apply border-border outline-ring/50;
}
body {
@apply bg-background text-foreground;
font-family: var(--font-sans);
cursor: none;
}
a,
button {
cursor: none;
}
html {
scroll-behavior: smooth;
}
}
::selection {
background: oklch(0.72 0.12 85 / 0.3);
@keyframes float {
0%,
100% {
transform: translateY(0px);
}
50% {
transform: translateY(-20px);
}
}
/* Simple link style */
a {
color: var(--primary);
text-decoration: none;
transition: opacity 0.15s;
}
a:hover {
opacity: 0.7;
}
/* Fade in */
@keyframes fadeIn {
from { opacity: 0; }
to { opacity: 1; }
}
.fade-in {
animation: fadeIn 0.8s ease-out forwards;
}
/* Cursor blink */
@keyframes blink {
0%, 50% { opacity: 1; }
51%, 100% { opacity: 0; }
.animate-float {
animation: float 6s ease-in-out infinite;
}

View File

@ -1,12 +1,20 @@
import { CursorEffect } from '@/components/cursor-effect'
import { HeroSection } from '@/components/hero-section'
import { WorkSection } from '@/components/work-section'
import { AboutSection } from '@/components/about-section'
import { SkillsSection } from '@/components/skills-section'
import { ContactSection } from '@/components/contact-section'
export default function Home() {
return (
<>
<CursorEffect />
<main>
<main className="relative">
<HeroSection />
<WorkSection />
<AboutSection />
<SkillsSection />
<ContactSection />
</main>
</>
)

View File

@ -1,126 +1,61 @@
"use client"
const FOCUS_AREAS = [
{
label: "Token Engineering",
description: "Designing sustainable crypto-economic systems",
items: ["Bonding Curves", "cadCAD Modeling", "Primary Issuance Markets"],
},
{
label: "Governance",
description: "Mechanisms for collective decision-making",
items: ["Conviction Voting", "DAO Templates", "Ostrom Principles"],
},
{
label: "Regenerative Economics",
description: "Beyond extractive growth models",
items: ["MycoFi", "Commons-based Systems", "Mutual Aid"],
},
]
export function AboutSection() {
return (
<section id="about" className="py-20 px-4 md:px-6 crosshatch">
<section className="py-32 px-6 bg-card/30">
<div className="max-w-4xl mx-auto">
{/* Section header */}
<div className="mb-12">
<span className="section-label">About</span>
<h2 className="text-3xl md:text-4xl font-light mt-6 mb-4">
Background
</h2>
<div className="mb-16">
<h2 className="text-5xl md:text-6xl font-bold mb-6">About Me</h2>
</div>
{/* Main content card */}
<div className="blueprint-card p-8 md:p-10 mb-12">
<div className="space-y-6 text-muted-foreground leading-relaxed">
<p>
I'm a token engineering researcher and systems designer exploring the
intersection of economics, ecology, and decentralized coordination. My work
focuses on creating tools and frameworks that enable communities to manage
shared resources sustainably and equitably.
</p>
<p>
As a co-founder of the <strong className="text-foreground">Commons Stack</strong>,
I've been instrumental in developing cyber-physical commons architectures
that translate Elinor Ostrom's principles into DAO templates. We build
customizable libraries of tools for communal management of public goods.
</p>
<p>
Through <strong className="text-foreground">MycoFi</strong>, I explore
mycoeconomicseconomic systems inspired by fungal networks. By emulating
nature's evolutionary resource allocation algorithms, we can design
regenerative protocols built on cooperation rather than extraction.
</p>
</div>
{/* Timeline markers */}
<div className="mt-10 pt-8 border-t border-border">
<div className="flex items-center gap-4 mb-4">
<div className="node-point filled" />
<span className="text-sm text-muted-foreground font-mono">2015</span>
<span className="text-sm">Entered Web3</span>
</div>
<svg className="ml-1.5 h-8 w-px text-border">
<line x1="0" y1="0" x2="0" y2="32" stroke="currentColor" strokeWidth="2" strokeDasharray="4 2" />
</svg>
<div className="flex items-center gap-4 mb-4">
<div className="node-point filled" />
<span className="text-sm text-muted-foreground font-mono">2018</span>
<span className="text-sm">Co-founded Commons Stack</span>
</div>
<svg className="ml-1.5 h-8 w-px text-border">
<line x1="0" y1="0" x2="0" y2="32" stroke="currentColor" strokeWidth="2" strokeDasharray="4 2" />
</svg>
<div className="flex items-center gap-4 mb-4">
<div className="node-point filled" />
<span className="text-sm text-muted-foreground font-mono">2023</span>
<span className="text-sm">Launched MycoFi</span>
</div>
<svg className="ml-1.5 h-8 w-px text-border">
<line x1="0" y1="0" x2="0" y2="32" stroke="currentColor" strokeWidth="2" strokeDasharray="4 2" />
</svg>
<div className="flex items-center gap-4">
<div className="node-point" />
<span className="text-sm text-muted-foreground font-mono">now</span>
<span className="text-sm text-muted-foreground">Continuing to build...</span>
</div>
</div>
</div>
{/* Focus areas as a diagram */}
<div className="grid md:grid-cols-3 gap-6">
{FOCUS_AREAS.map((area, index) => (
<div
key={area.label}
className="blueprint-card p-6 fade-in-up"
style={{ animationDelay: `${index * 0.1}s` }}
>
<div className="flex items-center gap-3 mb-4">
<div className="node-point filled" />
<h3 className="font-medium">{area.label}</h3>
</div>
<p className="text-sm text-muted-foreground mb-4">
{area.description}
</p>
<ul className="space-y-2">
{area.items.map((item) => (
<li key={item} className="text-sm flex items-center gap-2">
<span className="w-1.5 h-px bg-border" />
{item}
</li>
))}
</ul>
</div>
))}
</div>
{/* Annotation */}
<div className="mt-8">
<p className="annotation">
Just as bridges require engineering, our token economies need mathematical validation
<div className="space-y-6 text-lg leading-relaxed">
<p className="text-foreground/90">
I'm a token engineering researcher and systems designer exploring the intersection of economics, ecology,
and decentralized coordination. My work focuses on creating tools and frameworks that enable communities to
manage shared resources sustainably and equitablywhat I call "decent/ralised" systems.
</p>
<p className="text-muted-foreground">
As a co-founder of the Commons Stack, I've been instrumental in developing cyber-physical commons
architectures that translate Elinor Ostrom's principles into DAO templates. We're building customizable
libraries of tools for communal management of public goods, including innovations like Augmented Bonding
Curves and Conviction Votinga novel continuous decision-making mechanism that addresses critical attack
vectors in traditional governance systems.
</p>
<p className="text-muted-foreground">
Through the Bonding Curve Research Group, I research and develop Primary Issuance Markets that enable
dynamic token supply mechanisms. This work challenges the fixed supply paradigm dominant in Web3, offering
adaptive approaches that dampen volatility and generate sustainable revenue for token ecosystems. Our
research shows that tokens using primary issuance markets significantly outperform fixed-supply tokens in
price stability and risk-adjusted returns.
</p>
<p className="text-muted-foreground">
My MycoFi research explores mycoeconomicseconomic systems inspired by fungal networks. By emulating
nature's evolutionary resource allocation algorithms through mycelial intelligence, we can design
regenerative protocols built on cooperation, mutual aid, and permaculture currency principles rather than
extractive growth models. I authored book.mycofi.earth to share these insights.
</p>
<p className="text-muted-foreground">
I'm passionate about open-source token engineering tools like cadCAD, which I helped open source at the 2019
Token Engineering Global Gathering. Just as the Golden Gate Bridge required rigorous engineering, our token
economies need mathematical validation and simulation to serve as robust public infrastructure.
</p>
</div>
<div className="mt-16 grid md:grid-cols-3 gap-8">
<div>
<h3 className="text-3xl font-bold text-primary mb-2">8+</h3>
<p className="text-muted-foreground">Years in Token Engineering</p>
</div>
<div>
<h3 className="text-3xl font-bold text-primary mb-2">50+</h3>
<p className="text-muted-foreground">Research Publications</p>
</div>
<div>
<h3 className="text-3xl font-bold text-primary mb-2"></h3>
<p className="text-muted-foreground">Regenerative Impact</p>
</div>
</div>
</div>
</section>

View File

@ -1,122 +1,75 @@
"use client"
import { Github, Mail } from "lucide-react"
const CONNECTIONS = [
{
label: "Email",
value: "jeff@commonsstack.org",
href: "mailto:jeff@commonsstack.org",
},
const socials = [
{ icon: Mail, label: "Email", href: "mailto:jeff@emmett.com" },
{
icon: () => (
<svg className="h-5 w-5" fill="currentColor" viewBox="0 0 24 24">
<path d="M12 0C5.37 0 0 5.37 0 12s5.37 12 12 12 12-5.37 12-12S18.63 0 12 0zm5.01 18.5c-1.75 1.75-4.08 2.71-6.51 2.71s-4.76-.96-6.51-2.71C2.24 16.75 1.28 14.42 1.28 12s.96-4.76 2.71-6.51C5.74 3.74 8.07 2.78 10.5 2.78s4.76.96 6.51 2.71c1.75 1.75 2.71 4.08 2.71 6.51s-.96 4.76-2.71 6.51z" />
</svg>
),
label: "Bluesky",
value: "@jeffemmett",
href: "https://bsky.app/profile/jeffemmett.bsky.social",
},
{
label: "X/Twitter",
value: "@JeffEmmett",
href: "https://twitter.com/JeffEmmett",
},
{
icon: () => (
<svg className="h-5 w-5" fill="currentColor" viewBox="0 0 24 24">
<path d="M13.54 12a6.8 6.8 0 01-6.77 6.82A6.8 6.8 0 010 12a6.8 6.8 0 016.77-6.82A6.8 6.8 0 0113.54 12zM20.96 12c0 3.54-1.51 6.42-3.38 6.42-1.87 0-3.39-2.88-3.39-6.42s1.52-6.42 3.39-6.42 3.38 2.88 3.38 6.42M24 12c0 3.17-.53 5.75-1.19 5.75-.66 0-1.19-2.58-1.19-5.75s.53-5.75 1.19-5.75C23.47 6.25 24 8.83 24 12z" />
</svg>
),
label: "Medium",
value: "jeffemmett",
href: "https://medium.com/@jeffemmett",
},
]
const PROJECTS = [
{
icon: Github,
label: "Commons Stack",
href: "https://commonsstack.org",
},
{
icon: () => (
<svg className="h-5 w-5" fill="currentColor" viewBox="0 0 24 24">
<path d="M12 0c-6.626 0-12 5.373-12 12 0 5.302 3.438 9.8 8.207 11.387.599.111.793-.261.793-.577v-2.234c-3.338.726-4.033-1.416-4.033-1.416-.546-1.387-1.333-1.756-1.333-1.756-1.089-.745.083-.729.083-.729 1.205.084 1.839 1.237 1.839 1.237 1.07 1.834 2.807 1.304 3.492.997.107-.775.418-1.305.762-1.604-2.665-.305-5.467-1.334-5.467-5.931 0-1.311.469-2.381 1.236-3.221-.124-.303-.535-1.524.117-3.176 0 0 1.008-.322 3.301 1.23.957-.266 1.983-.399 3.003-.404 1.02.005 2.047.138 3.006.404 2.291-1.552 3.297-1.23 3.297-1.23.653 1.653.242 2.874.118 3.176.77.84 1.235 1.911 1.235 3.221 0 4.609-2.807 5.624-5.479 5.921.43.372.823 1.102.823 2.222v3.293c0 .319.192.694.801.576 4.765-1.589 8.199-6.086 8.199-11.386 0-6.627-5.373-12-12-12z" />
</svg>
),
label: "MycoFi",
href: "https://mycofi.earth",
},
{
label: "Token Engineering",
href: "https://tokenengineering.net",
},
]
export function ContactSection() {
return (
<section id="connect" className="py-20 px-4 md:px-6 crosshatch">
<div className="max-w-4xl mx-auto">
{/* Section header */}
<div className="mb-12">
<span className="section-label">Connect</span>
<h2 className="text-3xl md:text-4xl font-light mt-6 mb-4">
Get In Touch
</h2>
<p className="text-muted-foreground max-w-2xl">
Interested in token engineering, regenerative economics, or building
commons-based systems? Let's collaborate.
<section id="contact" className="py-32 px-6 bg-card/30">
<div className="max-w-4xl mx-auto text-center">
<div className="mb-16">
<h2 className="text-5xl md:text-6xl font-bold mb-6">Let's Connect</h2>
<p className="text-xl text-muted-foreground max-w-2xl mx-auto text-balance leading-relaxed">
Interested in token engineering, regenerative economics, or building commons-based systems? Let's
collaborate.
</p>
</div>
{/* Connection grid */}
<div className="grid md:grid-cols-2 gap-8 mb-12">
{/* Direct contact */}
<div className="blueprint-card p-6">
<div className="flex items-center gap-3 mb-6">
<div className="node-point filled" />
<h3 className="font-medium">Direct</h3>
</div>
<div className="space-y-4">
{CONNECTIONS.map((connection) => (
<a
key={connection.label}
href={connection.href}
target={connection.href.startsWith("mailto:") ? undefined : "_blank"}
rel="noopener noreferrer"
className="flex items-center justify-between py-2 group"
>
<span className="text-sm text-muted-foreground">
{connection.label}
</span>
<span className="text-sm blueprint-link">
{connection.value}
</span>
</a>
))}
</div>
</div>
{/* Projects */}
<div className="blueprint-card p-6">
<div className="flex items-center gap-3 mb-6">
<div className="node-point filled" />
<h3 className="font-medium">Projects</h3>
</div>
<div className="space-y-4">
{PROJECTS.map((project, index) => (
<a
key={project.label}
href={project.href}
target="_blank"
rel="noopener noreferrer"
className="flex items-center gap-3 py-2 group fade-in-up"
style={{ animationDelay: `${index * 0.1}s` }}
>
<div className="node-point group-hover:filled transition-colors" />
<span className="text-sm">{project.label}</span>
<span className="text-muted-foreground text-sm ml-auto"></span>
</a>
))}
</div>
</div>
<div className="flex flex-wrap gap-6 justify-center mb-12">
{socials.map((social) => {
const Icon = social.icon
return (
<a
key={social.label}
href={social.href}
target="_blank"
rel="noopener noreferrer"
className="group flex items-center gap-3 px-6 py-4 bg-secondary text-secondary-foreground rounded-lg font-medium transition-all hover:scale-105 hover:bg-primary hover:text-primary-foreground"
>
<Icon className="h-5 w-5" />
<span>{social.label}</span>
</a>
)
})}
</div>
{/* Footer */}
<div className="border-t border-border pt-8">
<div className="flex flex-col md:flex-row items-center justify-between gap-4">
<p className="text-sm text-muted-foreground">
© {new Date().getFullYear()} Jeff Emmett
</p>
<p className="annotation">
Building regenerative systems, one token at a time
</p>
</div>
<div className="pt-12 border-t border-border">
<p className="text-muted-foreground font-mono text-sm">
© 2025 Jeff Emmett. Built with Next.js & TailwindCSS
</p>
</div>
</div>
</section>

View File

@ -1,132 +1,79 @@
'use client'
import { useEffect, useRef } from 'react'
// Matrix-style characters: katakana, numbers, symbols
const MATRIX_CHARS = 'アイウエオカキクケコサシスセソタチツテトナニヌネハヒフヘホマミムメモヤユヨラリルレロワヲン0123456789@#$%^&*(){}[]|;:<>?/\\~`'
interface MatrixChar {
x: number
y: number
char: string
vx: number
vy: number
life: number
maxLife: number
size: number
rotation: number
rotationSpeed: number
}
import { useEffect, useState } from 'react'
export function CursorEffect() {
const canvasRef = useRef<HTMLCanvasElement>(null)
const charsRef = useRef<MatrixChar[]>([])
const frameRef = useRef<number>(0)
const [position, setPosition] = useState({ x: 0, y: 0 })
const [isHovering, setIsHovering] = useState(false)
const [trails, setTrails] = useState<Array<{ x: number; y: number; id: number }>>([])
useEffect(() => {
const canvas = canvasRef.current
if (!canvas) return
let trailId = 0
const ctx = canvas.getContext('2d')
if (!ctx) return
const handleMouseMove = (e: MouseEvent) => {
setPosition({ x: e.clientX, y: e.clientY })
// Add trail
const newTrail = { x: e.clientX, y: e.clientY, id: trailId++ }
setTrails(prev => [...prev.slice(-8), newTrail])
const resize = () => {
canvas.width = window.innerWidth
canvas.height = window.innerHeight
}
resize()
window.addEventListener('resize', resize)
const spawnChars = (x: number, y: number, count: number) => {
for (let i = 0; i < count; i++) {
const angle = (Math.PI * 2 * i) / count + (Math.random() - 0.5) * 0.5
const speed = 2 + Math.random() * 4
charsRef.current.push({
x,
y,
char: MATRIX_CHARS[Math.floor(Math.random() * MATRIX_CHARS.length)],
vx: Math.cos(angle) * speed,
vy: Math.sin(angle) * speed,
life: 1,
maxLife: 60 + Math.random() * 60,
size: 12 + Math.random() * 16,
rotation: Math.random() * Math.PI * 2,
rotationSpeed: (Math.random() - 0.5) * 0.2,
})
}
// Check if hovering over interactive element
const target = e.target as HTMLElement
const isInteractive = target.closest('a, button, [role="button"]')
setIsHovering(!!isInteractive)
}
const handleClick = (e: MouseEvent) => {
// Burst of matrix characters on click
spawnChars(e.clientX, e.clientY, 8 + Math.floor(Math.random() * 8))
}
window.addEventListener('click', handleClick)
const animate = () => {
// Clear with slight fade for trails
ctx.fillStyle = 'rgba(18, 16, 14, 0.15)'
ctx.fillRect(0, 0, canvas.width, canvas.height)
charsRef.current = charsRef.current.filter(char => {
// Update position
char.x += char.vx
char.y += char.vy
// Gravity and friction
char.vy += 0.08
char.vx *= 0.99
char.vy *= 0.99
// Update rotation
char.rotation += char.rotationSpeed
// Decay life
char.life -= 1 / char.maxLife
// Draw character
if (char.life > 0) {
ctx.save()
ctx.translate(char.x, char.y)
ctx.rotate(char.rotation)
const alpha = char.life * 0.9
// Primary color (warm gold/amber matching the theme)
ctx.fillStyle = `rgba(200, 170, 120, ${alpha})`
ctx.font = `${char.size}px "JetBrains Mono", monospace`
ctx.textAlign = 'center'
ctx.textBaseline = 'middle'
ctx.fillText(char.char, 0, 0)
// Glow effect
ctx.fillStyle = `rgba(200, 170, 120, ${alpha * 0.3})`
ctx.font = `${char.size * 1.1}px "JetBrains Mono", monospace`
ctx.fillText(char.char, 0, 0)
ctx.restore()
}
return char.life > 0
})
frameRef.current = requestAnimationFrame(animate)
}
frameRef.current = requestAnimationFrame(animate)
return () => {
window.removeEventListener('resize', resize)
window.removeEventListener('click', handleClick)
cancelAnimationFrame(frameRef.current)
}
window.addEventListener('mousemove', handleMouseMove)
return () => window.removeEventListener('mousemove', handleMouseMove)
}, [])
return (
<canvas
ref={canvasRef}
className="fixed inset-0 pointer-events-none z-0"
style={{ opacity: 0.9 }}
/>
<>
{/* Main cursor */}
<div
className="pointer-events-none fixed z-[9999] mix-blend-difference"
style={{
left: `${position.x}px`,
top: `${position.y}px`,
transform: 'translate(-50%, -50%)',
transition: 'width 0.2s, height 0.2s',
}}
>
<div
className={`rounded-full bg-primary transition-all duration-200 ${
isHovering ? 'h-12 w-12' : 'h-6 w-6'
}`}
/>
</div>
{/* Trail effect */}
{trails.map((trail, index) => (
<div
key={trail.id}
className="pointer-events-none fixed z-[9998] rounded-full bg-accent mix-blend-screen"
style={{
left: `${trail.x}px`,
top: `${trail.y}px`,
transform: 'translate(-50%, -50%)',
width: `${4 + index}px`,
height: `${4 + index}px`,
opacity: (index + 1) / trails.length * 0.3,
transition: 'opacity 0.5s',
}}
/>
))}
{/* Outer ring */}
<div
className="pointer-events-none fixed z-[9997] rounded-full border-2 border-primary/30 transition-all duration-300"
style={{
left: `${position.x}px`,
top: `${position.y}px`,
transform: 'translate(-50%, -50%)',
width: isHovering ? '64px' : '48px',
height: isHovering ? '64px' : '48px',
}}
/>
</>
)
}

View File

@ -2,109 +2,78 @@
import { useEffect, useState } from "react"
const DOMAINS = [
"mycoeconomics",
"psilocybernetics",
"post-capitalism",
"collective intelligence",
"regenerative systems",
"the undernet",
]
export function HeroSection() {
const [typedText, setTypedText] = useState("")
const [currentDomain, setCurrentDomain] = useState(0)
const [showCursor, setShowCursor] = useState(true)
const fullText = DOMAINS[currentDomain]
const [mousePosition, setMousePosition] = useState({ x: 0, y: 0 })
useEffect(() => {
let charIndex = 0
setTypedText("")
const handleMouseMove = (e: MouseEvent) => {
setMousePosition({
x: (e.clientX / window.innerWidth - 0.5) * 20,
y: (e.clientY / window.innerHeight - 0.5) * 20,
})
}
const typeInterval = setInterval(() => {
if (charIndex < fullText.length) {
setTypedText(fullText.slice(0, charIndex + 1))
charIndex++
} else {
clearInterval(typeInterval)
setTimeout(() => {
setCurrentDomain((prev) => (prev + 1) % DOMAINS.length)
}, 2500)
}
}, 70)
return () => clearInterval(typeInterval)
}, [currentDomain, fullText])
useEffect(() => {
const cursorInterval = setInterval(() => {
setShowCursor((prev) => !prev)
}, 530)
return () => clearInterval(cursorInterval)
window.addEventListener("mousemove", handleMouseMove)
return () => window.removeEventListener("mousemove", handleMouseMove)
}, [])
return (
<section className="min-h-screen flex items-center justify-center px-6 py-20">
<div className="max-w-2xl w-full">
<h1 className="text-4xl md:text-6xl font-light mb-6">
Jeff Emmett
</h1>
<section className="relative min-h-screen flex items-center justify-center overflow-hidden px-6">
{/* Animated background elements */}
<div className="absolute inset-0 overflow-hidden opacity-20">
<div
className="absolute top-1/4 left-1/4 h-96 w-96 rounded-full bg-primary blur-[120px] animate-float"
style={{
transform: `translate(${mousePosition.x}px, ${mousePosition.y}px)`,
transition: "transform 0.3s ease-out",
}}
/>
<div
className="absolute bottom-1/4 right-1/4 h-96 w-96 rounded-full bg-accent blur-[120px]"
style={{
transform: `translate(${-mousePosition.x}px, ${-mousePosition.y}px)`,
transition: "transform 0.3s ease-out",
animationDelay: "2s",
}}
/>
</div>
<p className="text-xl md:text-2xl text-muted-foreground mb-6">
Exploring{" "}
<span className="text-primary">
{typedText}
<span className={showCursor ? "opacity-100" : "opacity-0"}>|</span>
{/* Content */}
<div className="relative z-10 max-w-5xl text-center">
<div className="mb-6 inline-block">
<span className="text-sm font-mono text-muted-foreground border border-border px-4 py-2 rounded-full">
{"{ Token Engineering & Regenerative Economics }"}
</span>
</div>
<h1 className="text-6xl md:text-8xl font-bold mb-6 text-balance leading-tight">Jeff Emmett</h1>
<p className="text-xl md:text-2xl text-muted-foreground mb-12 max-w-3xl mx-auto text-balance leading-relaxed">
Token engineering researcher exploring bonding curves, Web3 economies, and mycoeconomics. Building tools for
regenerative communities and commons-based governance.
</p>
<p className="text-muted-foreground mb-12 leading-relaxed">
Mycelial explorer of alternative economic potentialities.
Designing tools for coordination and collective flourishing.
</p>
{/* Main project */}
<div className="mb-10">
<div className="flex flex-wrap gap-4 justify-center">
<a
href="https://mycofi.earth"
target="_blank"
rel="noopener noreferrer"
className="inline-block text-2xl md:text-3xl font-light hover:opacity-70 transition-opacity"
href="#work"
className="group relative px-8 py-4 bg-primary text-primary-foreground rounded-lg font-medium overflow-hidden transition-all hover:scale-105"
>
MycoFi
<span className="relative z-10">View Research</span>
<div className="absolute inset-0 bg-accent opacity-0 group-hover:opacity-100 transition-opacity" />
</a>
<p className="text-muted-foreground text-sm mt-2">
Mycelial design patterns for Web3 and beyond
</p>
</div>
{/* Links */}
<div className="flex flex-wrap gap-6 text-sm mb-10">
<a href="https://commonsstack.org" target="_blank" rel="noopener noreferrer">
Commons Stack
</a>
<a href="https://block.science" target="_blank" rel="noopener noreferrer">
BlockScience
</a>
<a href="https://medium.com/@jeffemmett" target="_blank" rel="noopener noreferrer">
Writing
<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"
>
Get in Touch
</a>
</div>
</div>
{/* Social */}
<div className="pt-6 border-t border-border">
<div className="flex flex-wrap gap-6 text-sm text-muted-foreground">
<a href="https://twitter.com/JeffEmmett" target="_blank" rel="noopener noreferrer">
Twitter
</a>
<a href="https://bsky.app/profile/jeffemmett.bsky.social" target="_blank" rel="noopener noreferrer">
Bluesky
</a>
<a href="https://github.com/Jeff-Emmett" target="_blank" rel="noopener noreferrer">
GitHub
</a>
</div>
{/* Scroll indicator */}
<div className="absolute bottom-12 left-1/2 -translate-x-1/2 animate-bounce">
<div className="h-12 w-8 rounded-full border-2 border-muted-foreground/30 flex items-start justify-center p-2">
<div className="h-2 w-1 bg-muted-foreground/50 rounded-full animate-pulse" />
</div>
</div>
</section>

View File

@ -1,134 +1,59 @@
"use client"
const SKILL_CATEGORIES = [
{
name: "Systems Design",
skills: [
{ name: "Token Engineering", level: 95 },
{ name: "Mechanism Design", level: 90 },
{ name: "Agent-Based Modeling", level: 85 },
{ name: "Complex Systems", level: 80 },
],
},
{
name: "Governance",
skills: [
{ name: "DAO Architecture", level: 90 },
{ name: "Voting Systems", level: 92 },
{ name: "Institutional Design", level: 85 },
{ name: "Commons Management", level: 88 },
],
},
{
name: "Technical",
skills: [
{ name: "cadCAD / Python", level: 88 },
{ name: "Solidity", level: 70 },
{ name: "Data Analysis", level: 82 },
{ name: "Simulation", level: 85 },
],
},
]
function SkillBar({ level }: { level: number }) {
return (
<div className="flex-1 h-2 bg-secondary rounded-sm overflow-hidden">
<div
className="h-full bg-primary/60 transition-all duration-500"
style={{ width: `${level}%` }}
/>
</div>
)
const skills = {
"Token Engineering": [
"Bonding Curves",
"cadCAD Modeling",
"Primary Issuance Markets",
"Dynamic Supply Tokens",
"Cryptoeconomics",
"Agent-Based Modeling",
],
"DAO Tooling": [
"Conviction Voting",
"Augmented Bonding Curves",
"Commons Stack",
"Governance Systems",
"Cyber-Physical Commons",
"Ostrom Compliance",
],
"Research Areas": [
"Regenerative Economics",
"Mycoeconomics",
"Complex Systems",
"Behavioral Economics",
"Token Design",
"Public Goods Funding",
],
Technical: ["Python", "Solidity", "Simulation", "Data Analysis", "Systems Design", "Web3"],
}
export function SkillsSection() {
return (
<section id="skills" className="py-20 px-4 md:px-6">
<div className="max-w-4xl mx-auto">
{/* Section header */}
<div className="mb-12">
<span className="section-label">Expertise</span>
<h2 className="text-3xl md:text-4xl font-light mt-6 mb-4">
Skills & Focus Areas
</h2>
<p className="text-muted-foreground max-w-2xl">
Interdisciplinary approach to building resilient token economies
and regenerative systems.
<section className="py-32 px-6">
<div className="max-w-6xl mx-auto">
<div className="mb-16">
<h2 className="text-5xl md:text-6xl font-bold mb-6">Expertise & Focus Areas</h2>
<p className="text-xl text-muted-foreground max-w-2xl text-balance leading-relaxed">
Interdisciplinary approach to building resilient token economies and regenerative systems
</p>
</div>
{/* Skills diagram */}
<div className="grid md:grid-cols-3 gap-8">
{SKILL_CATEGORIES.map((category, catIndex) => (
<div
key={category.name}
className="blueprint-card p-6 fade-in-up"
style={{ animationDelay: `${catIndex * 0.1}s` }}
>
<div className="flex items-center gap-3 mb-6">
<div className="node-point filled" />
<h3 className="font-medium">{category.name}</h3>
</div>
<div className="space-y-4">
{category.skills.map((skill) => (
<div key={skill.name}>
<div className="flex items-center justify-between mb-1">
<span className="text-sm">{skill.name}</span>
<span className="text-xs text-muted-foreground font-mono">
{skill.level}%
</span>
</div>
<SkillBar level={skill.level} />
</div>
<div className="grid md:grid-cols-2 gap-12">
{Object.entries(skills).map(([category, items]) => (
<div key={category}>
<h3 className="text-2xl font-semibold mb-6 text-primary">{category}</h3>
<div className="flex flex-wrap gap-3">
{items.map((skill) => (
<span
key={skill}
className="px-4 py-2 bg-secondary text-secondary-foreground rounded-lg font-medium hover:bg-primary hover:text-primary-foreground transition-colors"
>
{skill}
</span>
))}
</div>
</div>
))}
</div>
{/* Connection diagram between categories */}
<div className="mt-12 flex justify-center">
<svg
viewBox="0 0 400 60"
className="w-full max-w-md h-16 text-border"
>
{/* Connection lines */}
<line
x1="80" y1="30" x2="200" y2="30"
stroke="currentColor"
strokeWidth="1.5"
strokeDasharray="4 2"
/>
<line
x1="200" y1="30" x2="320" y2="30"
stroke="currentColor"
strokeWidth="1.5"
strokeDasharray="4 2"
/>
{/* Nodes */}
<circle cx="80" cy="30" r="6" fill="var(--primary)" />
<circle cx="200" cy="30" r="6" fill="var(--primary)" />
<circle cx="320" cy="30" r="6" fill="var(--primary)" />
{/* Labels */}
<text x="80" y="55" textAnchor="middle" className="graph-label">
Design
</text>
<text x="200" y="55" textAnchor="middle" className="graph-label">
Govern
</text>
<text x="320" y="55" textAnchor="middle" className="graph-label">
Build
</text>
</svg>
</div>
{/* Annotation */}
<div className="mt-8 text-center">
<p className="annotation">
Skills interconnect like mycelial networkseach node strengthens the whole
</p>
</div>
</div>
</section>
)

View File

@ -1,233 +1,93 @@
"use client"
import { Card } from "@/components/ui/card"
import { useState } from "react"
interface ResearchItem {
id: string
title: string
category: string
year: string
abstract: string
tags: string[]
link?: string
status: "published" | "working" | "ongoing"
}
const RESEARCH_ITEMS: ResearchItem[] = [
const projects = [
{
id: "bonding-curves",
title: "Bonding Curves: A Mathematical Primitive for Collective Intelligence",
category: "token_engineering",
year: "2019",
abstract:
"Exploration of automated market makers as coordination mechanisms for decentralized communities. Analysis of augmented bonding curves for sustainable funding of public goods.",
tags: ["AMM", "DeFi", "public goods", "cadCAD"],
link: "https://medium.com/commonsstack",
status: "published",
title: "Commons Stack",
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",
},
{
id: "conviction-voting",
title: "Conviction Voting: A Novel Continuous Decision Making Framework",
category: "governance",
year: "2020",
abstract:
"Time-weighted voting mechanism that allows preferences to accumulate over time, reducing plutocratic attack vectors and enabling more nuanced collective decision-making.",
tags: ["governance", "voting", "mechanism design"],
link: "https://blog.giveth.io/conviction-voting",
status: "published",
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",
},
{
id: "mycofi",
title: "MycoFi: Towards Mycelial Finance and Regenerative Economics",
category: "mycoeconomics",
year: "2023",
abstract:
"Framework for understanding economic systems through the lens of fungal networks. Proposes biomimetic approaches to resource allocation and value flow in decentralized systems.",
tags: ["biomimicry", "regenerative", "networks", "ecology"],
link: "https://mycofi.earth",
status: "ongoing",
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",
},
{
id: "institutional-neuroplasticity",
title: "Institutional Neuroplasticity: Adaptive Governance for Complex Systems",
category: "governance",
year: "2024",
abstract:
"Applying principles of neural plasticity to institutional design. How organizations can maintain coherence while adapting to changing conditions through distributed learning.",
tags: ["institutions", "adaptation", "complexity"],
status: "working",
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",
},
{
id: "zk-local-first",
title: "Zero-Knowledge Local-First: Privacy-Preserving Decentralized Coordination",
category: "cryptography",
year: "2025",
abstract:
"Architecture for local-first applications with ZK proofs for selective disclosure. Enabling community coordination without surveillance capitalism.",
tags: ["ZK", "privacy", "local-first", "p2p"],
status: "working",
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",
},
{
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",
},
]
const CATEGORIES = [
{ id: "all", label: "All" },
{ id: "token_engineering", label: "Token Engineering" },
{ id: "governance", label: "Governance" },
{ id: "mycoeconomics", label: "Mycoeconomics" },
{ id: "cryptography", label: "Cryptography" },
]
export function WorkSection() {
const [activeCategory, setActiveCategory] = useState("all")
const [expandedItem, setExpandedItem] = useState<string | null>(null)
const filteredItems =
activeCategory === "all"
? RESEARCH_ITEMS
: RESEARCH_ITEMS.filter((item) => item.category === activeCategory)
return (
<section id="research" className="py-20 px-4 md:px-6">
<div className="max-w-4xl mx-auto">
{/* Section header */}
<div className="mb-12">
<span className="section-label">Research</span>
<h2 className="text-3xl md:text-4xl font-light mt-6 mb-4">
Working Papers & Publications
</h2>
<p className="text-muted-foreground max-w-2xl">
Exploring regenerative systems, token engineering, and collective intelligence
through research and open-source tooling.
<section id="work" className="py-32 px-6">
<div className="max-w-7xl mx-auto">
<div className="mb-16">
<h2 className="text-5xl md:text-6xl font-bold mb-6">Research & Projects</h2>
<p className="text-xl text-muted-foreground max-w-2xl text-balance leading-relaxed">
Exploring token engineering, regenerative economics, and decentralized governance systems
</p>
</div>
{/* Category filter */}
<div className="flex flex-wrap gap-2 mb-8">
{CATEGORIES.map((cat) => (
<button
key={cat.id}
onClick={() => setActiveCategory(cat.id)}
className={`tag transition-colors ${
activeCategory === cat.id ? "primary" : ""
}`}
<div className="grid md:grid-cols-2 lg:grid-cols-3 gap-8">
{projects.map((project, index) => (
<Card
key={index}
className="group relative overflow-hidden bg-card border-border hover:border-primary/50 transition-all duration-300 hover:scale-[1.02]"
>
{cat.label}
</button>
))}
</div>
{/* Research items as diagram nodes */}
<div className="space-y-4">
{filteredItems.map((item, index) => (
<div
key={item.id}
className="blueprint-card overflow-hidden fade-in-up"
style={{ animationDelay: `${index * 0.1}s` }}
>
<div
className="p-6 cursor-pointer"
onClick={() =>
setExpandedItem(expandedItem === item.id ? null : item.id)
}
>
{/* Header row */}
<div className="flex items-start gap-4">
{/* Node indicator */}
<div className="mt-1.5">
<div
className={`node-point ${
item.status === "published" ? "filled" : ""
}`}
style={{
borderColor:
item.status === "ongoing"
? "var(--accent)"
: item.status === "working"
? "var(--primary)"
: undefined,
}}
/>
</div>
{/* Content */}
<div className="flex-1 min-w-0">
<div className="flex flex-wrap items-center gap-3 mb-2">
<span
className={`tag ${
item.status === "published"
? "primary"
: ""
}`}
>
{item.status}
</span>
<span className="text-xs text-muted-foreground font-mono">
{item.year}
</span>
</div>
<h3 className="text-lg font-medium text-foreground mb-2">
{item.title}
</h3>
<div className="flex flex-wrap gap-2">
{item.tags.map((tag) => (
<span
key={tag}
className="text-xs text-muted-foreground"
>
#{tag}
</span>
))}
</div>
</div>
{/* Expand indicator */}
<svg
width="20"
height="20"
viewBox="0 0 20 20"
className={`text-muted-foreground transition-transform ${
expandedItem === item.id ? "rotate-180" : ""
}`}
>
<path
d="M5 8 L10 13 L15 8"
stroke="currentColor"
strokeWidth="1.5"
fill="none"
/>
</svg>
</div>
{/* Expanded content */}
{expandedItem === item.id && (
<div className="mt-6 pt-6 border-t border-border ml-8">
<p className="text-muted-foreground text-sm leading-relaxed mb-4">
{item.abstract}
</p>
{item.link && (
<a
href={item.link}
target="_blank"
rel="noopener noreferrer"
className="blueprint-link text-sm"
onClick={(e) => e.stopPropagation()}
>
Read more
</a>
)}
</div>
)}
<div className="aspect-video overflow-hidden bg-muted">
<img
src={project.image || "/placeholder.svg"}
alt={project.title}
className="w-full h-full object-cover transition-transform duration-500 group-hover:scale-110"
/>
</div>
</div>
<div className="p-6">
<h3 className="text-2xl font-semibold mb-3 group-hover:text-primary transition-colors">
{project.title}
</h3>
<p className="text-muted-foreground mb-4 leading-relaxed">{project.description}</p>
<div className="flex flex-wrap gap-2">
{project.tags.map((tag, tagIndex) => (
<span
key={tagIndex}
className="text-xs font-mono px-3 py-1 bg-secondary text-secondary-foreground rounded-full"
>
{tag}
</span>
))}
</div>
</div>
</Card>
))}
</div>
{/* Annotation */}
<div className="mt-8">
<p className="annotation">
Open access research for the commons
</p>
</div>
</div>
</section>
)

6
next-env.d.ts vendored
View File

@ -1,6 +0,0 @@
/// <reference types="next" />
/// <reference types="next/image-types/global" />
import "./.next/types/routes.d.ts";
// NOTE: This file should not be edited
// see https://nextjs.org/docs/app/api-reference/config/typescript for more information.

View File

@ -1,10 +1,6 @@
{
"compilerOptions": {
"lib": [
"dom",
"dom.iterable",
"esnext"
],
"lib": ["dom", "dom.iterable", "esnext"],
"allowJs": true,
"target": "ES6",
"skipLibCheck": true,
@ -15,7 +11,7 @@
"moduleResolution": "bundler",
"resolveJsonModule": true,
"isolatedModules": true,
"jsx": "react-jsx",
"jsx": "preserve",
"incremental": true,
"plugins": [
{
@ -23,19 +19,9 @@
}
],
"paths": {
"@/*": [
"./*"
]
"@/*": ["./*"]
}
},
"include": [
"next-env.d.ts",
"**/*.ts",
"**/*.tsx",
".next/types/**/*.ts",
".next/dev/types/**/*.ts"
],
"exclude": [
"node_modules"
]
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
"exclude": ["node_modules"]
}