Compare commits

..

1 Commits
main ... dev

Author SHA1 Message Date
Jeff Emmett bd918093ca feat: add redirect from /board/* to canvas.jeffemmett.com
Old canvas board URLs now redirect to the new canvas subdomain:
- jeffemmett.com/board/mycofi -> canvas.jeffemmett.com/mycofi

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-02 15:28:32 +01:00
15 changed files with 79 additions and 47 deletions

View File

@ -1 +1,30 @@
# Personal website redesign
*Automatically synced with your [v0.app](https://v0.app) deployments*
[![Deployed on Vercel](https://img.shields.io/badge/Deployed%20on-Vercel-black?style=for-the-badge&logo=vercel)](https://vercel.com/jeff-emmetts-projects/v0-personal-website-redesign)
[![Built with v0](https://img.shields.io/badge/Built%20with-v0.app-black?style=for-the-badge)](https://v0.app/chat/c8jGR8t3eSX)
## Overview
This repository will stay in sync with your deployed chats on [v0.app](https://v0.app).
Any changes you make to your deployed app will be automatically pushed to this repository from [v0.app](https://v0.app).
## Deployment
Your project is live at:
**[https://vercel.com/jeff-emmetts-projects/v0-personal-website-redesign](https://vercel.com/jeff-emmetts-projects/v0-personal-website-redesign)**
## Build your app
Continue building your app on:
**[https://v0.app/chat/c8jGR8t3eSX](https://v0.app/chat/c8jGR8t3eSX)**
## How It Works
1. Create and modify your project using [v0.app](https://v0.app)
2. Deploy your chats from the v0 interface
3. Changes are automatically pushed to this repository
4. Vercel deploys the latest version from this repository

View File

@ -1,7 +1,7 @@
import type React from "react"
import type { Metadata } from "next"
import { Inter, Space_Mono } from "next/font/google"
import { Toaster } from "sonner"
import { Analytics } from "@vercel/analytics/next"
import "./globals.css"
const inter = Inter({
@ -19,6 +19,7 @@ export const metadata: Metadata = {
title: "Jeff Emmett - Token Engineering & Regenerative Economics",
description:
"Token engineering researcher exploring bonding curves, Web3 economies, and mycoeconomics. Co-founder of Commons Stack and MycoFi.",
generator: "v0.app",
icons: {
icon: [
{
@ -47,7 +48,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>
)

View File

@ -1,15 +0,0 @@
"use client"
import { useEffect } from "react"
export default function PresentationsRedirect() {
useEffect(() => {
window.location.replace(`https://slides.jeffemmett.com/${window.location.hash}`)
}, [])
return (
<div className="flex items-center justify-center min-h-screen bg-background text-muted-foreground">
<p>Redirecting to slides.jeffemmett.com...</p>
</div>
)
}

View File

@ -20,15 +20,6 @@ const socials = [
label: "Medium",
href: "https://medium.com/@jeffemmett",
},
{
icon: () => (
<svg className="h-5 w-5" fill="currentColor" viewBox="0 0 24 24">
<path d="M16.074 2.398L4.066 14.406l-1.478 6.284a.5.5 0 00.602.602l6.284-1.478L21.482 7.806l-5.408-5.408zM3.5 22a.5.5 0 01-.354-.146.5.5 0 01-.146-.354L3.5 22zm15.56-15.56l-1.414 1.414-2.121-2.121 1.414-1.414 2.121 2.121z" />
</svg>
),
label: "Earlier Writings",
href: "https://thoughtsglapbaan.wordpress.com/",
},
{
icon: Github,
label: "Commons Stack",

View File

@ -62,12 +62,6 @@ 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="https://slides.jeffemmett.com"
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.png",
image: "/commons-stack-dao-governance-blockchain.jpg",
},
{
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-curves.png",
image: "/bonding-curve-token-economics-chart.jpg",
},
{
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: "/mycofi-mycelium.png",
image: "/mycelium-network-nature-fungal.jpg",
},
{
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.png",
image: "/conviction-voting-governance-dashboard.jpg",
},
{
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.png",
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-commons.png",
image: "/token-engineering-community-collaborative.jpg",
},
]

View File

@ -9,15 +9,12 @@ const nextConfig = {
},
async redirects() {
return [
// Redirect old canvas board URLs to new canvas subdomain
// jeffemmett.com/board/mycofi -> canvas.jeffemmett.com/mycofi
{
source: '/presentations',
destination: 'https://slides.jeffemmett.com',
permanent: true,
},
{
source: '/presentations/:path*',
destination: 'https://slides.jeffemmett.com/:path*',
permanent: true,
source: '/board/:path*',
destination: 'https://canvas.jeffemmett.com/:path*',
permanent: true, // 308 redirect for SEO
},
]
},

View File

@ -37,6 +37,7 @@
"@radix-ui/react-toggle": "1.1.1",
"@radix-ui/react-toggle-group": "1.1.1",
"@radix-ui/react-tooltip": "1.1.6",
"@vercel/analytics": "latest",
"autoprefixer": "^10.4.20",
"class-variance-authority": "^0.7.1",
"clsx": "^2.1.1",
@ -69,4 +70,4 @@
"tw-animate-css": "1.3.3",
"typescript": "^5"
}
}
}

View File

@ -92,6 +92,9 @@ importers:
'@radix-ui/react-tooltip':
specifier: 1.1.6
version: 1.1.6(@types/react-dom@19.0.0)(@types/react@19.0.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)
'@vercel/analytics':
specifier: latest
version: 1.6.1(next@16.0.3(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(react@19.2.0)
autoprefixer:
specifier: ^10.4.20
version: 10.4.20(postcss@8.5.0)
@ -1209,6 +1212,32 @@ packages:
'@types/react@19.0.0':
resolution: {integrity: sha512-MY3oPudxvMYyesqs/kW1Bh8y9VqSmf+tzqw3ae8a9DZW68pUe3zAdHeI1jc6iAysuRdACnVknHP8AhwD4/dxtg==}
'@vercel/analytics@1.6.1':
resolution: {integrity: sha512-oH9He/bEM+6oKlv3chWuOOcp8Y6fo6/PSro8hEkgCW3pu9/OiCXiUpRUogDh3Fs3LH2sosDrx8CxeOLBEE+afg==}
peerDependencies:
'@remix-run/react': ^2
'@sveltejs/kit': ^1 || ^2
next: '>= 13'
react: ^18 || ^19 || ^19.0.0-rc
svelte: '>= 4'
vue: ^3
vue-router: ^4
peerDependenciesMeta:
'@remix-run/react':
optional: true
'@sveltejs/kit':
optional: true
next:
optional: true
react:
optional: true
svelte:
optional: true
vue:
optional: true
vue-router:
optional: true
aria-hidden@1.2.6:
resolution: {integrity: sha512-ik3ZgC9dY/lYVVM++OISsaYDeg1tb0VtP5uL3ouh1koGOaUMDPpbFIei4JkFimWUFPn90sbMNMXQAIVOlnYKJA==}
engines: {node: '>=10'}
@ -2711,6 +2740,11 @@ snapshots:
dependencies:
csstype: 3.2.3
'@vercel/analytics@1.6.1(next@16.0.3(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(react@19.2.0)':
optionalDependencies:
next: 16.0.3(react-dom@19.2.0(react@19.2.0))(react@19.2.0)
react: 19.2.0
aria-hidden@1.2.6:
dependencies:
tslib: 2.8.1

Binary file not shown.

Before

Width:  |  Height:  |  Size: 559 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 554 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 486 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 856 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 549 KiB