Initialized repository for chat Bonding Curve website

Co-authored-by: Jeff Emmett <46964190+Jeff-Emmett@users.noreply.github.com>
This commit is contained in:
v0 2025-11-08 00:42:55 +00:00
commit d9df38a8ca
32 changed files with 4425 additions and 0 deletions

27
.gitignore vendored Normal file
View File

@ -0,0 +1,27 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
# dependencies
/node_modules
# next.js
/.next/
/out/
# production
/build
# debug
npm-debug.log*
yarn-debug.log*
yarn-error.log*
.pnpm-debug.log*
# env files
.env*
# vercel
.vercel
# typescript
*.tsbuildinfo
next-env.d.ts

30
README.md Normal file
View File

@ -0,0 +1,30 @@
# Bonding Curve website
*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-bonding-curve-website)
[![Built with v0](https://img.shields.io/badge/Built%20with-v0.app-black?style=for-the-badge)](https://v0.app/chat/n3RHr4w55ja)
## 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-bonding-curve-website](https://vercel.com/jeff-emmetts-projects/v0-bonding-curve-website)**
## Build your app
Continue building your app on:
**[https://v0.app/chat/n3RHr4w55ja](https://v0.app/chat/n3RHr4w55ja)**
## 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

125
app/globals.css Normal file
View File

@ -0,0 +1,125 @@
@import "tailwindcss";
@import "tw-animate-css";
@custom-variant dark (&:is(.dark *));
:root {
--background: oklch(0.985 0.002 264);
--foreground: oklch(0.18 0.015 264);
--card: oklch(1 0 0);
--card-foreground: oklch(0.18 0.015 264);
--popover: oklch(1 0 0);
--popover-foreground: oklch(0.18 0.015 264);
--primary: oklch(0.24 0.018 264);
--primary-foreground: oklch(0.985 0 0);
--secondary: oklch(0.35 0.045 195);
--secondary-foreground: oklch(0.985 0 0);
--muted: oklch(0.95 0.002 264);
--muted-foreground: oklch(0.48 0.01 264);
--accent: oklch(0.35 0.045 195);
--accent-foreground: oklch(0.985 0 0);
--destructive: oklch(0.577 0.245 27.325);
--destructive-foreground: oklch(0.985 0 0);
--border: oklch(0.88 0.005 264);
--input: oklch(0.88 0.005 264);
--ring: oklch(0.35 0.045 195);
--chart-1: oklch(0.35 0.045 195);
--chart-2: oklch(0.24 0.018 264);
--chart-3: oklch(0.48 0.01 264);
--chart-4: oklch(0.65 0.08 195);
--chart-5: oklch(0.45 0.06 220);
--radius: 0.5rem;
--sidebar: oklch(0.985 0 0);
--sidebar-foreground: oklch(0.18 0.015 264);
--sidebar-primary: oklch(0.24 0.018 264);
--sidebar-primary-foreground: oklch(0.985 0 0);
--sidebar-accent: oklch(0.95 0.002 264);
--sidebar-accent-foreground: oklch(0.18 0.015 264);
--sidebar-border: oklch(0.88 0.005 264);
--sidebar-ring: oklch(0.35 0.045 195);
}
.dark {
--background: oklch(0.145 0.01 264);
--foreground: oklch(0.93 0.005 264);
--card: oklch(0.18 0.012 264);
--card-foreground: oklch(0.93 0.005 264);
--popover: oklch(0.18 0.012 264);
--popover-foreground: oklch(0.93 0.005 264);
--primary: oklch(0.93 0.005 264);
--primary-foreground: oklch(0.18 0.015 264);
--secondary: oklch(0.45 0.06 195);
--secondary-foreground: oklch(0.985 0 0);
--muted: oklch(0.24 0.015 264);
--muted-foreground: oklch(0.62 0.008 264);
--accent: oklch(0.45 0.06 195);
--accent-foreground: oklch(0.985 0 0);
--destructive: oklch(0.396 0.141 25.723);
--destructive-foreground: oklch(0.985 0 0);
--border: oklch(0.28 0.015 264);
--input: oklch(0.28 0.015 264);
--ring: oklch(0.45 0.06 195);
--chart-1: oklch(0.45 0.06 195);
--chart-2: oklch(0.65 0.08 195);
--chart-3: oklch(0.62 0.008 264);
--chart-4: oklch(0.35 0.045 195);
--chart-5: oklch(0.55 0.07 220);
--sidebar: oklch(0.18 0.012 264);
--sidebar-foreground: oklch(0.93 0.005 264);
--sidebar-primary: oklch(0.45 0.06 195);
--sidebar-primary-foreground: oklch(0.985 0 0);
--sidebar-accent: oklch(0.24 0.015 264);
--sidebar-accent-foreground: oklch(0.93 0.005 264);
--sidebar-border: oklch(0.28 0.015 264);
--sidebar-ring: oklch(0.45 0.06 195);
}
@theme inline {
--font-sans: "Geist", "Geist Fallback";
--font-mono: "Geist Mono", "Geist Mono Fallback";
--color-background: var(--background);
--color-foreground: var(--foreground);
--color-card: var(--card);
--color-card-foreground: var(--card-foreground);
--color-popover: var(--popover);
--color-popover-foreground: var(--popover-foreground);
--color-primary: var(--primary);
--color-primary-foreground: var(--primary-foreground);
--color-secondary: var(--secondary);
--color-secondary-foreground: var(--secondary-foreground);
--color-muted: var(--muted);
--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);
--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 outline-ring/50;
}
body {
@apply bg-background text-foreground;
}
}

45
app/layout.tsx Normal file
View File

@ -0,0 +1,45 @@
import type React from "react"
import type { Metadata } from "next"
import { Inter } from "next/font/google"
import { Analytics } from "@vercel/analytics/next"
import "./globals.css"
const inter = Inter({ subsets: ["latin"] })
export const metadata: Metadata = {
title: "Bonding Curve Research Group",
description: "Independent research collective studying bonding curves and programmable financial primitives",
generator: "v0.app",
icons: {
icon: [
{
url: "/icon-light-32x32.png",
media: "(prefers-color-scheme: light)",
},
{
url: "/icon-dark-32x32.png",
media: "(prefers-color-scheme: dark)",
},
{
url: "/icon.svg",
type: "image/svg+xml",
},
],
apple: "/apple-icon.png",
},
}
export default function RootLayout({
children,
}: Readonly<{
children: React.ReactNode
}>) {
return (
<html lang="en">
<body className={`${inter.className} antialiased`}>
{children}
<Analytics />
</body>
</html>
)
}

21
app/page.tsx Normal file
View File

@ -0,0 +1,21 @@
import { Navigation } from "@/components/navigation"
import { HeroSection } from "@/components/hero-section"
import { AboutSection } from "@/components/about-section"
import { ResearchSection } from "@/components/research-section"
import { LibrarySection } from "@/components/library-section"
import { OpenSourceSection } from "@/components/open-source-section"
import { Footer } from "@/components/footer"
export default function Home() {
return (
<main className="min-h-screen">
<Navigation />
<HeroSection />
<AboutSection />
<ResearchSection />
<LibrarySection />
<OpenSourceSection />
<Footer />
</main>
)
}

21
components.json Normal file
View File

@ -0,0 +1,21 @@
{
"$schema": "https://ui.shadcn.com/schema.json",
"style": "new-york",
"rsc": true,
"tsx": true,
"tailwind": {
"config": "",
"css": "app/globals.css",
"baseColor": "neutral",
"cssVariables": true,
"prefix": ""
},
"aliases": {
"components": "@/components",
"utils": "@/lib/utils",
"ui": "@/components/ui",
"lib": "@/lib",
"hooks": "@/hooks"
},
"iconLibrary": "lucide"
}

View File

@ -0,0 +1,61 @@
import { Card } from "@/components/ui/card"
import { Users, Lightbulb, Code, BookOpen } from "lucide-react"
export function AboutSection() {
const values = [
{
icon: Users,
title: "Collaborative",
description:
"A diverse mix of expertise spanning systems engineering, mathematical modeling, economics, and data science.",
},
{
icon: Lightbulb,
title: "Innovative",
description: "Driving innovation that broadens the potential applications of programmable financial primitives.",
},
{
icon: Code,
title: "Open Source",
description:
"Committed to building reliable tooling that empowers projects and developers in the Web3 ecosystem.",
},
{
icon: BookOpen,
title: "Educational",
description:
"Simplifying the understanding and implementation of bonding curves to democratize these complex concepts.",
},
]
return (
<section id="about" className="py-20 px-4 sm:px-6 lg:px-8 bg-muted/30">
<div className="max-w-7xl mx-auto">
<div className="max-w-2xl mb-16">
<h2 className="text-4xl md:text-5xl font-bold mb-6 text-balance">About the BCRG</h2>
<p className="text-lg text-muted-foreground leading-relaxed text-pretty">
The Bonding Curve Research Group is an independent, decentralized collective united in our dedication to
advancing the understanding and application of bonding curves in crypto-economics. We bring together
expertise from multiple disciplines to create tools and knowledge that benefit the entire Web3 community.
</p>
</div>
<div className="grid grid-cols-1 md:grid-cols-2 gap-6">
{values.map((value, index) => (
<Card key={index} className="p-6 hover:shadow-lg transition-shadow">
<div className="flex items-start gap-4">
<div className="p-2 rounded-lg bg-accent/10">
<value.icon className="h-6 w-6 text-accent" />
</div>
<div>
<h3 className="text-xl font-semibold mb-2">{value.title}</h3>
<p className="text-muted-foreground leading-relaxed">{value.description}</p>
</div>
</div>
</Card>
))}
</div>
</div>
</section>
)
}

80
components/footer.tsx Normal file
View File

@ -0,0 +1,80 @@
import Link from "next/link"
import { Github, Twitter } from "lucide-react"
export function Footer() {
return (
<footer className="border-t border-border bg-card">
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-12">
<div className="grid grid-cols-1 md:grid-cols-4 gap-8">
<div className="col-span-1 md:col-span-2">
<div className="flex items-center gap-2 mb-4">
<div className="w-8 h-8 bg-primary rounded-sm" />
<span className="text-lg font-semibold">BCRG</span>
</div>
<p className="text-sm text-muted-foreground leading-relaxed max-w-md">
The Bonding Curve Research Group is an independent research collective dedicated to advancing the
understanding and application of bonding curves in Web3.
</p>
</div>
<div>
<h3 className="font-semibold mb-4">Resources</h3>
<ul className="space-y-2 text-sm text-muted-foreground">
<li>
<Link
href="https://bonding-curve-research-group.gitbook.io/bonding-curve-research-group-library"
target="_blank"
className="hover:text-foreground transition-colors"
>
Library
</Link>
</li>
<li>
<Link
href="https://mirror.xyz/0x8fF6Fe58b468B1F18d2C54e2B0870b4e847C730d"
target="_blank"
className="hover:text-foreground transition-colors"
>
Research
</Link>
</li>
<li>
<Link
href="https://github.com/bonding-curves"
target="_blank"
className="hover:text-foreground transition-colors"
>
GitHub
</Link>
</li>
</ul>
</div>
<div>
<h3 className="font-semibold mb-4">Connect</h3>
<div className="flex gap-4">
<Link
href="https://github.com/bonding-curves"
target="_blank"
className="text-muted-foreground hover:text-foreground transition-colors"
>
<Github className="h-5 w-5" />
</Link>
<Link
href="https://x.com/Bonding_Curves"
target="_blank"
className="text-muted-foreground hover:text-foreground transition-colors"
>
<Twitter className="h-5 w-5" />
</Link>
</div>
</div>
</div>
<div className="mt-12 pt-8 border-t border-border text-center text-sm text-muted-foreground">
<p>&copy; {new Date().getFullYear()} Bonding Curve Research Group. All rights reserved.</p>
</div>
</div>
</footer>
)
}

View File

@ -0,0 +1,44 @@
import { Button } from "@/components/ui/button"
import Link from "next/link"
import { ArrowRight } from "lucide-react"
export function HeroSection() {
return (
<section className="pt-32 pb-20 px-4 sm:px-6 lg:px-8">
<div className="max-w-7xl mx-auto">
<div className="max-w-3xl">
<div className="inline-flex items-center gap-2 px-3 py-1 rounded-full bg-accent/20 border border-accent/30 text-accent-foreground text-sm mb-6">
<div className="w-1.5 h-1.5 rounded-full bg-accent" />
Independent Research Collective
</div>
<h1 className="text-5xl md:text-6xl lg:text-7xl font-bold tracking-tight mb-6 text-balance">
Bonding Curve Research Group
</h1>
<p className="text-xl md:text-2xl text-muted-foreground mb-8 leading-relaxed text-pretty">
We are a decentralized collective of scholars, engineers, and researchers dedicated to the comprehensive
study, development, and practical implementation of bonding curves as programmable financial primitives.
</p>
<div className="flex flex-wrap gap-4">
<Button asChild size="lg" className="bg-primary hover:bg-primary/90">
<Link href="#research">
Explore Research
<ArrowRight className="ml-2 h-4 w-4" />
</Link>
</Button>
<Button asChild variant="outline" size="lg">
<Link
href="https://bonding-curve-research-group.gitbook.io/bonding-curve-research-group-library"
target="_blank"
>
View Library
</Link>
</Button>
</div>
</div>
</div>
</section>
)
}

View File

@ -0,0 +1,80 @@
import { Card } from "@/components/ui/card"
import { Button } from "@/components/ui/button"
import { BookOpen, Database, LineChart, Code2 } from "lucide-react"
import Link from "next/link"
export function LibrarySection() {
const features = [
{
icon: Database,
title: "Data Loading",
description: "Easy data loading from Dune dashboards for analyzing existing bonding curves deployed on-chain.",
},
{
icon: LineChart,
title: "Interactive Models",
description: "Collection of bonding curve models with interactive parameterization and visualization dashboards.",
},
{
icon: Code2,
title: "Python Library",
description: 'Open source Python library "conding" for modeling, simulation, and analysis of bonding curves.',
},
{
icon: BookOpen,
title: "Documentation",
description: "Comprehensive guides and documentation to help you understand and implement bonding curves.",
},
]
return (
<section id="library" className="py-20 px-4 sm:px-6 lg:px-8 bg-muted/30">
<div className="max-w-7xl mx-auto">
<div className="max-w-2xl mb-16">
<h2 className="text-4xl md:text-5xl font-bold mb-6 text-balance">BCRG Library</h2>
<p className="text-lg text-muted-foreground leading-relaxed text-pretty">
A comprehensive toolkit for exploring the design space of bonding curves, producing re-usable tooling as
infrastructure for future research and practical implementations.
</p>
</div>
<div className="grid grid-cols-1 md:grid-cols-2 gap-6 mb-12">
{features.map((feature, index) => (
<Card key={index} className="p-6">
<div className="flex items-start gap-4">
<div className="p-2 rounded-lg bg-accent/10">
<feature.icon className="h-6 w-6 text-accent" />
</div>
<div>
<h3 className="text-xl font-semibold mb-2">{feature.title}</h3>
<p className="text-muted-foreground leading-relaxed">{feature.description}</p>
</div>
</div>
</Card>
))}
</div>
<Card className="p-8 bg-card border-2">
<div className="flex flex-col md:flex-row items-center justify-between gap-6">
<div className="flex-1">
<h3 className="text-2xl font-bold mb-3">Get Started with the Library</h3>
<p className="text-muted-foreground leading-relaxed mb-4">
Access our comprehensive documentation and tutorials to start modeling and analyzing bonding curves
today.
</p>
<code className="block bg-muted px-4 py-2 rounded text-sm font-mono">pip install conding</code>
</div>
<Button asChild size="lg" className="bg-primary hover:bg-primary/90">
<Link
href="https://bonding-curve-research-group.gitbook.io/bonding-curve-research-group-library"
target="_blank"
>
View Documentation
</Link>
</Button>
</div>
</Card>
</div>
</section>
)
}

39
components/navigation.tsx Normal file
View File

@ -0,0 +1,39 @@
"use client"
import Link from "next/link"
import { Button } from "@/components/ui/button"
export function Navigation() {
return (
<nav className="fixed top-0 left-0 right-0 z-50 bg-background/80 backdrop-blur-sm border-b border-border">
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<div className="flex items-center justify-between h-16">
<Link href="/" className="flex items-center gap-2">
<div className="w-8 h-8 bg-primary rounded-sm" />
<span className="text-lg font-semibold">BCRG</span>
</Link>
<div className="hidden md:flex items-center gap-8">
<Link href="#about" className="text-sm text-muted-foreground hover:text-foreground transition-colors">
About
</Link>
<Link href="#research" className="text-sm text-muted-foreground hover:text-foreground transition-colors">
Research
</Link>
<Link href="#library" className="text-sm text-muted-foreground hover:text-foreground transition-colors">
Library
</Link>
<Link href="#open-source" className="text-sm text-muted-foreground hover:text-foreground transition-colors">
Open Source
</Link>
<Button asChild size="sm" className="bg-primary hover:bg-primary/90">
<Link href="https://github.com/bonding-curves" target="_blank">
GitHub
</Link>
</Button>
</div>
</div>
</div>
</nav>
)
}

View File

@ -0,0 +1,99 @@
import { Card } from "@/components/ui/card"
import { Button } from "@/components/ui/button"
import { Github, ExternalLink, Star } from "lucide-react"
import Link from "next/link"
export function OpenSourceSection() {
const projects = [
{
name: "conding",
description:
"Python library for modeling, simulation, and analysis of bonding curves. Features data loading from Dune and interactive visualization dashboards.",
link: "https://github.com/bonding-curves/conding",
topics: ["Python", "Data Science", "Modeling"],
},
{
name: "Research Papers",
description:
"Collection of our research publications exploring bonding curves, PAMMs, SAMMs, and their applications in token engineering.",
link: "https://mirror.xyz/0x8fF6Fe58b468B1F18d2C54e2B0870b4e847C730d",
topics: ["Research", "Token Engineering", "DeFi"],
},
{
name: "Library Documentation",
description:
"Comprehensive documentation and guides for understanding and implementing bonding curves in your projects.",
link: "https://bonding-curve-research-group.gitbook.io/bonding-curve-research-group-library",
topics: ["Documentation", "Tutorials", "Guides"],
},
]
return (
<section id="open-source" className="py-20 px-4 sm:px-6 lg:px-8">
<div className="max-w-7xl mx-auto">
<div className="max-w-2xl mb-16">
<h2 className="text-4xl md:text-5xl font-bold mb-6 text-balance">Open Source Contributions</h2>
<p className="text-lg text-muted-foreground leading-relaxed text-pretty">
All of our work is open source and freely available to the community. We believe in building in public and
contributing to the knowledge commons of crypto-economic primitives.
</p>
</div>
<div className="grid grid-cols-1 gap-6 mb-12">
{projects.map((project, index) => (
<Card key={index} className="p-6 hover:shadow-lg transition-shadow">
<div className="flex flex-col md:flex-row md:items-center md:justify-between gap-4">
<div className="flex-1">
<div className="flex items-center gap-2 mb-2">
<Github className="h-5 w-5" />
<h3 className="text-xl font-semibold">{project.name}</h3>
</div>
<p className="text-muted-foreground mb-3 leading-relaxed">{project.description}</p>
<div className="flex flex-wrap gap-2">
{project.topics.map((topic, i) => (
<span key={i} className="px-3 py-1 bg-accent/10 text-accent text-sm rounded-full">
{topic}
</span>
))}
</div>
</div>
<Button asChild variant="outline" className="self-start md:self-center bg-transparent">
<Link href={project.link} target="_blank">
View Project
<ExternalLink className="ml-2 h-4 w-4" />
</Link>
</Button>
</div>
</Card>
))}
</div>
<Card className="p-8 bg-primary text-primary-foreground">
<div className="flex flex-col md:flex-row items-center justify-between gap-6">
<div className="flex-1">
<h3 className="text-2xl font-bold mb-3">Join Our Community</h3>
<p className="text-primary-foreground/90 leading-relaxed">
Follow our research, contribute to our projects, and join the conversation about bonding curves and
token engineering on GitHub and Twitter.
</p>
</div>
<div className="flex flex-col sm:flex-row gap-3">
<Button asChild variant="secondary" size="lg">
<Link href="https://github.com/bonding-curves" target="_blank">
<Github className="mr-2 h-5 w-5" />
GitHub
</Link>
</Button>
<Button asChild variant="secondary" size="lg">
<Link href="https://x.com/Bonding_Curves" target="_blank">
<Star className="mr-2 h-5 w-5" />
Twitter
</Link>
</Button>
</div>
</div>
</Card>
</div>
</section>
)
}

View File

@ -0,0 +1,76 @@
import { Card } from "@/components/ui/card"
import { Button } from "@/components/ui/button"
import { ExternalLink, Calendar } from "lucide-react"
import Link from "next/link"
export function ResearchSection() {
const publications = [
{
title: "Modeling & Simulating Bonding Curves",
description:
"Introducing our open source library to model and simulate Bonding Curves and discussing our methodology for data science approaches to crypto-economic primitives.",
date: "July 21, 2023",
link: "https://mirror.xyz/0x8fF6Fe58b468B1F18d2C54e2B0870b4e847C730d/3gTCNW1LcsNd_O8zgfgERXnZhA_8wYyyHkZRe-oxIns",
},
{
title: "Exploring Bonding Curves: PAMMs vs SAMMs",
description:
"A comprehensive comparison of Primary and Secondary Automated Market Makers, exploring their different applications in token ecosystems and market design.",
date: "June 29, 2023",
link: "https://mirror.xyz/0x8fF6Fe58b468B1F18d2C54e2B0870b4e847C730d/1Pxl_fbIPifIQ4_y0xoJGZGEk70qfOM3Gi9nWycm-8k",
},
{
title: "The Importance of Systems Engineering in Token Design",
description:
"How modeling and simulating bonding curves enables the exploration of design space and assists in the implementation and deployment of bonding curve ecosystems.",
date: "May 28, 2024",
link: "https://bonding-curve-research-group.gitbook.io/bonding-curve-research-group-library/modeling-and-simulating-bonding-curves",
},
]
return (
<section id="research" className="py-20 px-4 sm:px-6 lg:px-8">
<div className="max-w-7xl mx-auto">
<div className="max-w-2xl mb-16">
<h2 className="text-4xl md:text-5xl font-bold mb-6 text-balance">Research & Publications</h2>
<p className="text-lg text-muted-foreground leading-relaxed text-pretty">
Our research focuses on empirical analysis, practical applications, and in-depth exploration of bonding
curves as vital components for crafting robust digital economies in the DeFi ecosystem.
</p>
</div>
<div className="grid grid-cols-1 gap-6">
{publications.map((pub, index) => (
<Card key={index} className="p-6 hover:shadow-lg transition-shadow">
<div className="flex flex-col md:flex-row md:items-center md:justify-between gap-4">
<div className="flex-1">
<h3 className="text-xl font-semibold mb-2">{pub.title}</h3>
<p className="text-muted-foreground mb-3 leading-relaxed">{pub.description}</p>
<div className="flex items-center gap-2 text-sm text-muted-foreground">
<Calendar className="h-4 w-4" />
<span>{pub.date}</span>
</div>
</div>
<Button asChild variant="outline" className="self-start md:self-center bg-transparent">
<Link href={pub.link} target="_blank">
Read More
<ExternalLink className="ml-2 h-4 w-4" />
</Link>
</Button>
</div>
</Card>
))}
</div>
<div className="mt-12 text-center">
<Button asChild size="lg" variant="outline">
<Link href="https://mirror.xyz/0x8fF6Fe58b468B1F18d2C54e2B0870b4e847C730d" target="_blank">
View All Publications on Mirror
<ExternalLink className="ml-2 h-4 w-4" />
</Link>
</Button>
</div>
</div>
</section>
)
}

View File

@ -0,0 +1,11 @@
'use client'
import * as React from 'react'
import {
ThemeProvider as NextThemesProvider,
type ThemeProviderProps,
} from 'next-themes'
export function ThemeProvider({ children, ...props }: ThemeProviderProps) {
return <NextThemesProvider {...props}>{children}</NextThemesProvider>
}

60
components/ui/button.tsx Normal file
View File

@ -0,0 +1,60 @@
import * as React from 'react'
import { Slot } from '@radix-ui/react-slot'
import { cva, type VariantProps } from 'class-variance-authority'
import { cn } from '@/lib/utils'
const buttonVariants = cva(
"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive",
{
variants: {
variant: {
default: 'bg-primary text-primary-foreground hover:bg-primary/90',
destructive:
'bg-destructive text-white hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60',
outline:
'border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50',
secondary:
'bg-secondary text-secondary-foreground hover:bg-secondary/80',
ghost:
'hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50',
link: 'text-primary underline-offset-4 hover:underline',
},
size: {
default: 'h-9 px-4 py-2 has-[>svg]:px-3',
sm: 'h-8 rounded-md gap-1.5 px-3 has-[>svg]:px-2.5',
lg: 'h-10 rounded-md px-6 has-[>svg]:px-4',
icon: 'size-9',
'icon-sm': 'size-8',
'icon-lg': 'size-10',
},
},
defaultVariants: {
variant: 'default',
size: 'default',
},
},
)
function Button({
className,
variant,
size,
asChild = false,
...props
}: React.ComponentProps<'button'> &
VariantProps<typeof buttonVariants> & {
asChild?: boolean
}) {
const Comp = asChild ? Slot : 'button'
return (
<Comp
data-slot="button"
className={cn(buttonVariants({ variant, size, className }))}
{...props}
/>
)
}
export { Button, buttonVariants }

92
components/ui/card.tsx Normal file
View File

@ -0,0 +1,92 @@
import * as React from 'react'
import { cn } from '@/lib/utils'
function Card({ className, ...props }: React.ComponentProps<'div'>) {
return (
<div
data-slot="card"
className={cn(
'bg-card text-card-foreground flex flex-col gap-6 rounded-xl border py-6 shadow-sm',
className,
)}
{...props}
/>
)
}
function CardHeader({ className, ...props }: React.ComponentProps<'div'>) {
return (
<div
data-slot="card-header"
className={cn(
'@container/card-header grid auto-rows-min grid-rows-[auto_auto] items-start gap-2 px-6 has-data-[slot=card-action]:grid-cols-[1fr_auto] [.border-b]:pb-6',
className,
)}
{...props}
/>
)
}
function CardTitle({ className, ...props }: React.ComponentProps<'div'>) {
return (
<div
data-slot="card-title"
className={cn('leading-none font-semibold', className)}
{...props}
/>
)
}
function CardDescription({ className, ...props }: React.ComponentProps<'div'>) {
return (
<div
data-slot="card-description"
className={cn('text-muted-foreground text-sm', className)}
{...props}
/>
)
}
function CardAction({ className, ...props }: React.ComponentProps<'div'>) {
return (
<div
data-slot="card-action"
className={cn(
'col-start-2 row-span-2 row-start-1 self-start justify-self-end',
className,
)}
{...props}
/>
)
}
function CardContent({ className, ...props }: React.ComponentProps<'div'>) {
return (
<div
data-slot="card-content"
className={cn('px-6', className)}
{...props}
/>
)
}
function CardFooter({ className, ...props }: React.ComponentProps<'div'>) {
return (
<div
data-slot="card-footer"
className={cn('flex items-center px-6 [.border-t]:pt-6', className)}
{...props}
/>
)
}
export {
Card,
CardHeader,
CardFooter,
CardTitle,
CardAction,
CardDescription,
CardContent,
}

6
lib/utils.ts Normal file
View File

@ -0,0 +1,6 @@
import { clsx, type ClassValue } from 'clsx'
import { twMerge } from 'tailwind-merge'
export function cn(...inputs: ClassValue[]) {
return twMerge(clsx(inputs))
}

14
next.config.mjs Normal file
View File

@ -0,0 +1,14 @@
/** @type {import('next').NextConfig} */
const nextConfig = {
eslint: {
ignoreDuringBuilds: true,
},
typescript: {
ignoreBuildErrors: true,
},
images: {
unoptimized: true,
},
}
export default nextConfig

73
package.json Normal file
View File

@ -0,0 +1,73 @@
{
"name": "my-v0-project",
"version": "0.1.0",
"private": true,
"scripts": {
"build": "next build",
"dev": "next dev",
"lint": "eslint .",
"start": "next start"
},
"dependencies": {
"@hookform/resolvers": "^3.10.0",
"@radix-ui/react-accordion": "1.2.2",
"@radix-ui/react-alert-dialog": "1.1.4",
"@radix-ui/react-aspect-ratio": "1.1.1",
"@radix-ui/react-avatar": "1.1.2",
"@radix-ui/react-checkbox": "1.1.3",
"@radix-ui/react-collapsible": "1.1.2",
"@radix-ui/react-context-menu": "2.2.4",
"@radix-ui/react-dialog": "1.1.4",
"@radix-ui/react-dropdown-menu": "2.1.4",
"@radix-ui/react-hover-card": "1.1.4",
"@radix-ui/react-label": "2.1.1",
"@radix-ui/react-menubar": "1.1.4",
"@radix-ui/react-navigation-menu": "1.2.3",
"@radix-ui/react-popover": "1.1.4",
"@radix-ui/react-progress": "1.1.1",
"@radix-ui/react-radio-group": "1.2.2",
"@radix-ui/react-scroll-area": "1.2.2",
"@radix-ui/react-select": "2.1.4",
"@radix-ui/react-separator": "1.1.1",
"@radix-ui/react-slider": "1.2.2",
"@radix-ui/react-slot": "1.1.1",
"@radix-ui/react-switch": "1.1.2",
"@radix-ui/react-tabs": "1.1.2",
"@radix-ui/react-toast": "1.2.4",
"@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",
"cmdk": "1.0.4",
"date-fns": "4.1.0",
"embla-carousel-react": "8.5.1",
"input-otp": "1.4.1",
"lucide-react": "^0.454.0",
"next": "16.0.0",
"next-themes": "^0.4.6",
"react": "19.2.0",
"react-day-picker": "9.8.0",
"react-dom": "19.2.0",
"react-hook-form": "^7.60.0",
"react-resizable-panels": "^2.1.7",
"recharts": "2.15.4",
"sonner": "^1.7.4",
"tailwind-merge": "^2.5.5",
"tailwindcss-animate": "^1.0.7",
"vaul": "^0.9.9",
"zod": "3.25.76"
},
"devDependencies": {
"@tailwindcss/postcss": "^4.1.9",
"@types/node": "^22",
"@types/react": "^19",
"@types/react-dom": "^19",
"postcss": "^8.5",
"tailwindcss": "^4.1.9",
"tw-animate-css": "1.3.3",
"typescript": "^5"
}
}

3233
pnpm-lock.yaml Normal file

File diff suppressed because it is too large Load Diff

8
postcss.config.mjs Normal file
View File

@ -0,0 +1,8 @@
/** @type {import('postcss-load-config').Config} */
const config = {
plugins: {
'@tailwindcss/postcss': {},
},
}
export default config

BIN
public/apple-icon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

BIN
public/icon-dark-32x32.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 585 B

BIN
public/icon-light-32x32.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 566 B

26
public/icon.svg Normal file
View File

@ -0,0 +1,26 @@
<svg width="180" height="180" viewBox="0 0 180 180" fill="none" xmlns="http://www.w3.org/2000/svg">
<style>
@media (prefers-color-scheme: light) {
.background { fill: black; }
.foreground { fill: white; }
}
@media (prefers-color-scheme: dark) {
.background { fill: white; }
.foreground { fill: black; }
}
</style>
<g clip-path="url(#clip0_7960_43945)">
<rect class="background" width="180" height="180" rx="37" />
<g style="transform: scale(95%); transform-origin: center">
<path class="foreground"
d="M101.141 53H136.632C151.023 53 162.689 64.6662 162.689 79.0573V112.904H148.112V79.0573C148.112 78.7105 148.098 78.3662 148.072 78.0251L112.581 112.898C112.701 112.902 112.821 112.904 112.941 112.904H148.112V126.672H112.941C98.5504 126.672 86.5638 114.891 86.5638 100.5V66.7434H101.141V100.5C101.141 101.15 101.191 101.792 101.289 102.422L137.56 66.7816C137.255 66.7563 136.945 66.7434 136.632 66.7434H101.141V53Z" />
<path class="foreground"
d="M65.2926 124.136L14 66.7372H34.6355L64.7495 100.436V66.7372H80.1365V118.47C80.1365 126.278 70.4953 129.958 65.2926 124.136Z" />
</g>
</g>
<defs>
<clipPath id="clip0_7960_43945">
<rect width="180" height="180" fill="white" />
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 1.3 KiB

BIN
public/placeholder-logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 568 B

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="215" height="48" fill="none"><path fill="#000" d="M57.588 9.6h6L73.828 38h-5.2l-2.36-6.88h-11.36L52.548 38h-5.2l10.24-28.4Zm7.16 17.16-4.16-12.16-4.16 12.16h8.32Zm23.694-2.24c-.186-1.307-.706-2.32-1.56-3.04-.853-.72-1.866-1.08-3.04-1.08-1.68 0-2.986.613-3.92 1.84-.906 1.227-1.36 2.947-1.36 5.16s.454 3.933 1.36 5.16c.934 1.227 2.24 1.84 3.92 1.84 1.254 0 2.307-.373 3.16-1.12.854-.773 1.387-1.867 1.6-3.28l5.12.24c-.186 1.68-.733 3.147-1.64 4.4-.906 1.227-2.08 2.173-3.52 2.84-1.413.667-2.986 1-4.72 1-2.08 0-3.906-.453-5.48-1.36-1.546-.907-2.76-2.2-3.64-3.88-.853-1.68-1.28-3.627-1.28-5.84 0-2.24.427-4.187 1.28-5.84.88-1.68 2.094-2.973 3.64-3.88 1.574-.907 3.4-1.36 5.48-1.36 1.68 0 3.227.32 4.64.96 1.414.64 2.56 1.56 3.44 2.76.907 1.2 1.454 2.6 1.64 4.2l-5.12.28Zm11.486-7.72.12 3.4c.534-1.227 1.307-2.173 2.32-2.84 1.04-.693 2.267-1.04 3.68-1.04 1.494 0 2.76.387 3.8 1.16 1.067.747 1.827 1.813 2.28 3.2.507-1.44 1.294-2.52 2.36-3.24 1.094-.747 2.414-1.12 3.96-1.12 1.414 0 2.64.307 3.68.92s1.84 1.52 2.4 2.72c.56 1.2.84 2.667.84 4.4V38h-4.96V25.92c0-1.813-.293-3.187-.88-4.12-.56-.96-1.413-1.44-2.56-1.44-.906 0-1.68.213-2.32.64-.64.427-1.133 1.053-1.48 1.88-.32.827-.48 1.84-.48 3.04V38h-4.56V25.92c0-1.2-.133-2.213-.4-3.04-.24-.827-.626-1.453-1.16-1.88-.506-.427-1.133-.64-1.88-.64-.906 0-1.68.227-2.32.68-.64.427-1.133 1.053-1.48 1.88-.32.827-.48 1.827-.48 3V38h-4.96V16.8h4.48Zm26.723 10.6c0-2.24.427-4.187 1.28-5.84.854-1.68 2.067-2.973 3.64-3.88 1.574-.907 3.4-1.36 5.48-1.36 1.84 0 3.494.413 4.96 1.24 1.467.827 2.64 2.08 3.52 3.76.88 1.653 1.347 3.693 1.4 6.12v1.32h-15.08c.107 1.813.614 3.227 1.52 4.24.907.987 2.134 1.48 3.68 1.48.987 0 1.88-.253 2.68-.76a4.803 4.803 0 0 0 1.84-2.2l5.08.36c-.64 2.027-1.84 3.64-3.6 4.84-1.733 1.173-3.733 1.76-6 1.76-2.08 0-3.906-.453-5.48-1.36-1.573-.907-2.786-2.2-3.64-3.88-.853-1.68-1.28-3.627-1.28-5.84Zm15.16-2.04c-.213-1.733-.76-3.013-1.64-3.84-.853-.827-1.893-1.24-3.12-1.24-1.44 0-2.6.453-3.48 1.36-.88.88-1.44 2.12-1.68 3.72h9.92ZM163.139 9.6V38h-5.04V9.6h5.04Zm8.322 7.2.24 5.88-.64-.36c.32-2.053 1.094-3.56 2.32-4.52 1.254-.987 2.787-1.48 4.6-1.48 2.32 0 4.107.733 5.36 2.2 1.254 1.44 1.88 3.387 1.88 5.84V38h-4.96V25.92c0-1.253-.12-2.28-.36-3.08-.24-.8-.64-1.413-1.2-1.84-.533-.427-1.253-.64-2.16-.64-1.44 0-2.573.48-3.4 1.44-.8.933-1.2 2.307-1.2 4.12V38h-4.96V16.8h4.48Zm30.003 7.72c-.186-1.307-.706-2.32-1.56-3.04-.853-.72-1.866-1.08-3.04-1.08-1.68 0-2.986.613-3.92 1.84-.906 1.227-1.36 2.947-1.36 5.16s.454 3.933 1.36 5.16c.934 1.227 2.24 1.84 3.92 1.84 1.254 0 2.307-.373 3.16-1.12.854-.773 1.387-1.867 1.6-3.28l5.12.24c-.186 1.68-.733 3.147-1.64 4.4-.906 1.227-2.08 2.173-3.52 2.84-1.413.667-2.986 1-4.72 1-2.08 0-3.906-.453-5.48-1.36-1.546-.907-2.76-2.2-3.64-3.88-.853-1.68-1.28-3.627-1.28-5.84 0-2.24.427-4.187 1.28-5.84.88-1.68 2.094-2.973 3.64-3.88 1.574-.907 3.4-1.36 5.48-1.36 1.68 0 3.227.32 4.64.96 1.414.64 2.56 1.56 3.44 2.76.907 1.2 1.454 2.6 1.64 4.2l-5.12.28Zm11.443 8.16V38h-5.6v-5.32h5.6Z"/><path fill="#171717" fill-rule="evenodd" d="m7.839 40.783 16.03-28.054L20 6 0 40.783h7.839Zm8.214 0H40L27.99 19.894l-4.02 7.032 3.976 6.914H20.02l-3.967 6.943Z" clip-rule="evenodd"/></svg>

After

Width:  |  Height:  |  Size: 3.1 KiB

BIN
public/placeholder-user.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

BIN
public/placeholder.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

1
public/placeholder.svg Normal file
View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="1200" height="1200" fill="none"><rect width="1200" height="1200" fill="#EAEAEA" rx="3"/><g opacity=".5"><g opacity=".5"><path fill="#FAFAFA" d="M600.709 736.5c-75.454 0-136.621-61.167-136.621-136.62 0-75.454 61.167-136.621 136.621-136.621 75.453 0 136.62 61.167 136.62 136.621 0 75.453-61.167 136.62-136.62 136.62Z"/><path stroke="#C9C9C9" stroke-width="2.418" d="M600.709 736.5c-75.454 0-136.621-61.167-136.621-136.62 0-75.454 61.167-136.621 136.621-136.621 75.453 0 136.62 61.167 136.62 136.621 0 75.453-61.167 136.62-136.62 136.62Z"/></g><path stroke="url(#a)" stroke-width="2.418" d="M0-1.209h553.581" transform="scale(1 -1) rotate(45 1163.11 91.165)"/><path stroke="url(#b)" stroke-width="2.418" d="M404.846 598.671h391.726"/><path stroke="url(#c)" stroke-width="2.418" d="M599.5 795.742V404.017"/><path stroke="url(#d)" stroke-width="2.418" d="m795.717 796.597-391.441-391.44"/><path fill="#fff" d="M600.709 656.704c-31.384 0-56.825-25.441-56.825-56.824 0-31.384 25.441-56.825 56.825-56.825 31.383 0 56.824 25.441 56.824 56.825 0 31.383-25.441 56.824-56.824 56.824Z"/><g clip-path="url(#e)"><path fill="#666" fill-rule="evenodd" d="M616.426 586.58h-31.434v16.176l3.553-3.554.531-.531h9.068l.074-.074 8.463-8.463h2.565l7.18 7.181V586.58Zm-15.715 14.654 3.698 3.699 1.283 1.282-2.565 2.565-1.282-1.283-5.2-5.199h-6.066l-5.514 5.514-.073.073v2.876a2.418 2.418 0 0 0 2.418 2.418h26.598a2.418 2.418 0 0 0 2.418-2.418v-8.317l-8.463-8.463-7.181 7.181-.071.072Zm-19.347 5.442v4.085a6.045 6.045 0 0 0 6.046 6.045h26.598a6.044 6.044 0 0 0 6.045-6.045v-7.108l1.356-1.355-1.282-1.283-.074-.073v-17.989h-38.689v23.43l-.146.146.146.147Z" clip-rule="evenodd"/></g><path stroke="#C9C9C9" stroke-width="2.418" d="M600.709 656.704c-31.384 0-56.825-25.441-56.825-56.824 0-31.384 25.441-56.825 56.825-56.825 31.383 0 56.824 25.441 56.824 56.825 0 31.383-25.441 56.824-56.824 56.824Z"/></g><defs><linearGradient id="a" x1="554.061" x2="-.48" y1=".083" y2=".087" gradientUnits="userSpaceOnUse"><stop stop-color="#C9C9C9" stop-opacity="0"/><stop offset=".208" stop-color="#C9C9C9"/><stop offset=".792" stop-color="#C9C9C9"/><stop offset="1" stop-color="#C9C9C9" stop-opacity="0"/></linearGradient><linearGradient id="b" x1="796.912" x2="404.507" y1="599.963" y2="599.965" gradientUnits="userSpaceOnUse"><stop stop-color="#C9C9C9" stop-opacity="0"/><stop offset=".208" stop-color="#C9C9C9"/><stop offset=".792" stop-color="#C9C9C9"/><stop offset="1" stop-color="#C9C9C9" stop-opacity="0"/></linearGradient><linearGradient id="c" x1="600.792" x2="600.794" y1="403.677" y2="796.082" gradientUnits="userSpaceOnUse"><stop stop-color="#C9C9C9" stop-opacity="0"/><stop offset=".208" stop-color="#C9C9C9"/><stop offset=".792" stop-color="#C9C9C9"/><stop offset="1" stop-color="#C9C9C9" stop-opacity="0"/></linearGradient><linearGradient id="d" x1="404.85" x2="796.972" y1="403.903" y2="796.02" gradientUnits="userSpaceOnUse"><stop stop-color="#C9C9C9" stop-opacity="0"/><stop offset=".208" stop-color="#C9C9C9"/><stop offset=".792" stop-color="#C9C9C9"/><stop offset="1" stop-color="#C9C9C9" stop-opacity="0"/></linearGradient><clipPath id="e"><path fill="#fff" d="M581.364 580.535h38.689v38.689h-38.689z"/></clipPath></defs></svg>

After

Width:  |  Height:  |  Size: 3.2 KiB

125
styles/globals.css Normal file
View File

@ -0,0 +1,125 @@
@import 'tailwindcss';
@import 'tw-animate-css';
@custom-variant dark (&:is(.dark *));
:root {
--background: oklch(1 0 0);
--foreground: oklch(0.145 0 0);
--card: oklch(1 0 0);
--card-foreground: oklch(0.145 0 0);
--popover: oklch(1 0 0);
--popover-foreground: oklch(0.145 0 0);
--primary: oklch(0.205 0 0);
--primary-foreground: oklch(0.985 0 0);
--secondary: oklch(0.97 0 0);
--secondary-foreground: oklch(0.205 0 0);
--muted: oklch(0.97 0 0);
--muted-foreground: oklch(0.556 0 0);
--accent: oklch(0.97 0 0);
--accent-foreground: oklch(0.205 0 0);
--destructive: oklch(0.577 0.245 27.325);
--destructive-foreground: oklch(0.577 0.245 27.325);
--border: oklch(0.922 0 0);
--input: oklch(0.922 0 0);
--ring: oklch(0.708 0 0);
--chart-1: oklch(0.646 0.222 41.116);
--chart-2: oklch(0.6 0.118 184.704);
--chart-3: oklch(0.398 0.07 227.392);
--chart-4: oklch(0.828 0.189 84.429);
--chart-5: oklch(0.769 0.188 70.08);
--radius: 0.625rem;
--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: 'Geist', 'Geist Fallback';
--font-mono: 'Geist Mono', 'Geist Mono Fallback';
--color-background: var(--background);
--color-foreground: var(--foreground);
--color-card: var(--card);
--color-card-foreground: var(--card-foreground);
--color-popover: var(--popover);
--color-popover-foreground: var(--popover-foreground);
--color-primary: var(--primary);
--color-primary-foreground: var(--primary-foreground);
--color-secondary: var(--secondary);
--color-secondary-foreground: var(--secondary-foreground);
--color-muted: var(--muted);
--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);
--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 outline-ring/50;
}
body {
@apply bg-background text-foreground;
}
}

27
tsconfig.json Normal file
View File

@ -0,0 +1,27 @@
{
"compilerOptions": {
"lib": ["dom", "dom.iterable", "esnext"],
"allowJs": true,
"target": "ES6",
"skipLibCheck": true,
"strict": true,
"noEmit": true,
"esModuleInterop": true,
"module": "esnext",
"moduleResolution": "bundler",
"resolveJsonModule": true,
"isolatedModules": true,
"jsx": "preserve",
"incremental": true,
"plugins": [
{
"name": "next"
}
],
"paths": {
"@/*": ["./*"]
}
},
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
"exclude": ["node_modules"]
}