Initialized repository for chat Rspace.tech website
Co-authored-by: Jeff Emmett <46964190+Jeff-Emmett@users.noreply.github.com>
|
|
@ -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
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
# Rspace.tech website
|
||||
|
||||
*Automatically synced with your [v0.app](https://v0.app) deployments*
|
||||
|
||||
[](https://vercel.com/jeff-emmetts-projects/v0-rspace-tech-website)
|
||||
[](https://v0.app/chat/gpj3pGIGbtj)
|
||||
|
||||
## 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-rspace-tech-website](https://vercel.com/jeff-emmetts-projects/v0-rspace-tech-website)**
|
||||
|
||||
## Build your app
|
||||
|
||||
Continue building your app on:
|
||||
|
||||
**[https://v0.app/chat/gpj3pGIGbtj](https://v0.app/chat/gpj3pGIGbtj)**
|
||||
|
||||
## 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
|
||||
|
|
@ -0,0 +1,152 @@
|
|||
@import "tailwindcss";
|
||||
@import "tw-animate-css";
|
||||
|
||||
@custom-variant dark (&:is(.dark *));
|
||||
|
||||
:root {
|
||||
/* More vibrant MySpace-inspired colors with hot pink accent */
|
||||
--background: oklch(0.12 0.01 264);
|
||||
--foreground: oklch(0.98 0.01 180);
|
||||
--card: oklch(0.18 0.02 264);
|
||||
--card-foreground: oklch(0.98 0.01 180);
|
||||
--popover: oklch(0.15 0.02 264);
|
||||
--popover-foreground: oklch(0.98 0.01 180);
|
||||
--primary: oklch(0.75 0.18 195); /* cyan */
|
||||
--primary-foreground: oklch(0.12 0.01 264);
|
||||
--secondary: oklch(0.72 0.19 45); /* orange */
|
||||
--secondary-foreground: oklch(0.12 0.01 264);
|
||||
--muted: oklch(0.25 0.02 264);
|
||||
--muted-foreground: oklch(0.65 0.02 264);
|
||||
--accent: oklch(0.75 0.22 330); /* hot pink for that MySpace vibe */
|
||||
--accent-foreground: oklch(0.12 0.01 264);
|
||||
--destructive: oklch(0.577 0.245 27.325);
|
||||
--destructive-foreground: oklch(0.98 0.01 180);
|
||||
--border: oklch(0.28 0.02 264);
|
||||
--input: oklch(0.22 0.02 264);
|
||||
--ring: oklch(0.75 0.18 195);
|
||||
--chart-1: oklch(0.75 0.18 195);
|
||||
--chart-2: oklch(0.72 0.19 45);
|
||||
--chart-3: oklch(0.65 0.18 295);
|
||||
--chart-4: oklch(0.7 0.15 150);
|
||||
--chart-5: oklch(0.68 0.2 330);
|
||||
--radius: 0.5rem;
|
||||
--sidebar: oklch(0.15 0.02 264);
|
||||
--sidebar-foreground: oklch(0.98 0.01 180);
|
||||
--sidebar-primary: oklch(0.75 0.18 195);
|
||||
--sidebar-primary-foreground: oklch(0.12 0.01 264);
|
||||
--sidebar-accent: oklch(0.22 0.02 264);
|
||||
--sidebar-accent-foreground: oklch(0.98 0.01 180);
|
||||
--sidebar-border: oklch(0.28 0.02 264);
|
||||
--sidebar-ring: oklch(0.75 0.18 195);
|
||||
}
|
||||
|
||||
.dark {
|
||||
--background: oklch(0.08 0.01 264);
|
||||
--foreground: oklch(0.98 0.01 180);
|
||||
--card: oklch(0.12 0.02 264);
|
||||
--card-foreground: oklch(0.98 0.01 180);
|
||||
--popover: oklch(0.1 0.02 264);
|
||||
--popover-foreground: oklch(0.98 0.01 180);
|
||||
--primary: oklch(0.75 0.18 195);
|
||||
--primary-foreground: oklch(0.08 0.01 264);
|
||||
--secondary: oklch(0.72 0.19 45);
|
||||
--secondary-foreground: oklch(0.08 0.01 264);
|
||||
--muted: oklch(0.2 0.02 264);
|
||||
--muted-foreground: oklch(0.6 0.02 264);
|
||||
--accent: oklch(0.75 0.22 330);
|
||||
--accent-foreground: oklch(0.08 0.01 264);
|
||||
--destructive: oklch(0.577 0.245 27.325);
|
||||
--destructive-foreground: oklch(0.98 0.01 180);
|
||||
--border: oklch(0.25 0.02 264);
|
||||
--input: oklch(0.18 0.02 264);
|
||||
--ring: oklch(0.75 0.18 195);
|
||||
--chart-1: oklch(0.75 0.18 195);
|
||||
--chart-2: oklch(0.72 0.19 45);
|
||||
--chart-3: oklch(0.65 0.18 295);
|
||||
--chart-4: oklch(0.7 0.15 150);
|
||||
--chart-5: oklch(0.68 0.2 330);
|
||||
--sidebar: oklch(0.1 0.02 264);
|
||||
--sidebar-foreground: oklch(0.98 0.01 180);
|
||||
--sidebar-primary: oklch(0.75 0.18 195);
|
||||
--sidebar-primary-foreground: oklch(0.08 0.01 264);
|
||||
--sidebar-accent: oklch(0.18 0.02 264);
|
||||
--sidebar-accent-foreground: oklch(0.98 0.01 180);
|
||||
--sidebar-border: oklch(0.25 0.02 264);
|
||||
--sidebar-ring: oklch(0.75 0.18 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;
|
||||
}
|
||||
}
|
||||
|
||||
/* Add MySpace-style glitter animation effect */
|
||||
@keyframes glitter {
|
||||
0%,
|
||||
100% {
|
||||
opacity: 0.5;
|
||||
transform: scale(1);
|
||||
}
|
||||
50% {
|
||||
opacity: 1;
|
||||
transform: scale(1.1);
|
||||
}
|
||||
}
|
||||
|
||||
.glitter {
|
||||
animation: glitter 2s ease-in-out infinite;
|
||||
}
|
||||
|
||||
/* Add retro box shadow effects */
|
||||
.retro-shadow {
|
||||
box-shadow: 3px 3px 0px oklch(var(--primary)), 6px 6px 0px oklch(var(--secondary));
|
||||
}
|
||||
|
||||
.retro-shadow-sm {
|
||||
box-shadow: 2px 2px 0px oklch(var(--primary));
|
||||
}
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
import type React from "react"
|
||||
import type { Metadata } from "next"
|
||||
import { Geist, Geist_Mono } from "next/font/google"
|
||||
import { Analytics } from "@vercel/analytics/next"
|
||||
import "./globals.css"
|
||||
|
||||
const _geist = Geist({ subsets: ["latin"] })
|
||||
const _geistMono = Geist_Mono({ subsets: ["latin"] })
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: "rspace.tech - Reclaim Your Space on the New Web",
|
||||
description:
|
||||
"Build communities of purpose with local-first principles, zero-knowledge privacy, and collaborative freedom. Outside the walls of big tech monopolies.",
|
||||
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={`font-sans antialiased`}>
|
||||
{children}
|
||||
<Analytics />
|
||||
</body>
|
||||
</html>
|
||||
)
|
||||
}
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
import { Hero } from "@/components/hero"
|
||||
import { RealWorldExamples } from "@/components/real-world-examples"
|
||||
import { Features } from "@/components/features"
|
||||
import { Philosophy } from "@/components/philosophy"
|
||||
import { HowItWorks } from "@/components/how-it-works"
|
||||
import { Network } from "@/components/network"
|
||||
import { Footer } from "@/components/footer"
|
||||
|
||||
export default function Home() {
|
||||
return (
|
||||
<main className="min-h-screen">
|
||||
<Hero />
|
||||
<RealWorldExamples />
|
||||
<Features />
|
||||
<Philosophy />
|
||||
<HowItWorks />
|
||||
<Network />
|
||||
<Footer />
|
||||
</main>
|
||||
)
|
||||
}
|
||||
|
|
@ -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"
|
||||
}
|
||||
|
|
@ -0,0 +1,90 @@
|
|||
import { Card } from "@/components/ui/card"
|
||||
import { MessageSquare, FolderOpen, Shield, BarChart3, Coins, Lock } from "lucide-react"
|
||||
|
||||
const features = [
|
||||
{
|
||||
icon: MessageSquare,
|
||||
title: "Secure Messaging",
|
||||
description:
|
||||
"End-to-end encrypted communication channels for your community. Nobody can read your messages, not even us.",
|
||||
color: "text-primary",
|
||||
bgColor: "bg-primary/10",
|
||||
},
|
||||
{
|
||||
icon: FolderOpen,
|
||||
title: "File Sharing",
|
||||
description: "Share files and create collaborative views over data with localized, zero-knowledge storage.",
|
||||
color: "text-secondary",
|
||||
bgColor: "bg-secondary/10",
|
||||
},
|
||||
{
|
||||
icon: Shield,
|
||||
title: "Delegated Authority",
|
||||
description: "Manage group permissions and authority structures democratically. Your space, your rules.",
|
||||
color: "text-accent",
|
||||
bgColor: "bg-accent/10",
|
||||
},
|
||||
{
|
||||
icon: Coins,
|
||||
title: "Shared Funds",
|
||||
description: "Allocate and manage community resources through transparent, multi-sig controls.",
|
||||
color: "text-primary",
|
||||
bgColor: "bg-primary/10",
|
||||
},
|
||||
{
|
||||
icon: BarChart3,
|
||||
title: "Interactive Dashboards",
|
||||
description: "Multidimensional views of your data powered by folkjs - HTML as a computing substrate.",
|
||||
color: "text-secondary",
|
||||
bgColor: "bg-secondary/10",
|
||||
},
|
||||
{
|
||||
icon: Lock,
|
||||
title: "Data Privacy",
|
||||
description: "Zero-knowledge architecture ensures your data never exists unencrypted outside your control.",
|
||||
color: "text-accent",
|
||||
bgColor: "bg-accent/10",
|
||||
},
|
||||
]
|
||||
|
||||
export function Features() {
|
||||
return (
|
||||
<section className="border-b-4 border-primary bg-card/50 py-24">
|
||||
<div className="mx-auto max-w-7xl px-4 sm:px-6 lg:px-8">
|
||||
<div className="text-center">
|
||||
<h2 className="text-3xl font-bold tracking-tight text-foreground sm:text-4xl retro-shadow-sm">
|
||||
Shared Digital Spaces for <span className="text-primary">Collaboration</span>
|
||||
</h2>
|
||||
<p className="mt-4 text-lg text-muted-foreground">
|
||||
Everything you need to build thriving communities outside big tech's surveillance apparatus
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="mt-16 grid gap-6 sm:grid-cols-2 lg:grid-cols-3">
|
||||
{features.map((feature, index) => {
|
||||
const Icon = feature.icon
|
||||
return (
|
||||
<Card
|
||||
key={index}
|
||||
className="group relative overflow-hidden border-2 border-border bg-card p-6 transition-all hover:border-primary hover:-translate-y-1 hover:retro-shadow-sm"
|
||||
>
|
||||
<div
|
||||
className={`absolute inset-0 ${feature.bgColor} opacity-0 transition-opacity group-hover:opacity-100`}
|
||||
/>
|
||||
<div className="relative">
|
||||
<div
|
||||
className={`mb-4 inline-flex rounded-lg ${feature.bgColor} p-3 ${feature.color} border-2 border-current`}
|
||||
>
|
||||
<Icon className="h-6 w-6" />
|
||||
</div>
|
||||
<h3 className="mb-2 text-xl font-semibold text-card-foreground">{feature.title}</h3>
|
||||
<p className="text-sm leading-relaxed text-muted-foreground">{feature.description}</p>
|
||||
</div>
|
||||
</Card>
|
||||
)
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
)
|
||||
}
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
export function Footer() {
|
||||
return (
|
||||
<footer className="bg-card py-12">
|
||||
<div className="mx-auto max-w-7xl px-4 sm:px-6 lg:px-8">
|
||||
<div className="flex flex-col items-center justify-between gap-4 sm:flex-row">
|
||||
<div className="text-center sm:text-left">
|
||||
<p className="text-lg font-bold">
|
||||
<span className="text-primary">r</span>
|
||||
<span className="text-foreground">space</span>
|
||||
<span className="text-secondary">.tech</span>
|
||||
</p>
|
||||
<p className="mt-1 text-sm text-muted-foreground">Reclaim space on the new web</p>
|
||||
</div>
|
||||
|
||||
<div className="flex flex-col items-center gap-2 text-sm text-muted-foreground sm:items-end">
|
||||
<p>Built for communities, by communities</p>
|
||||
<p className="text-xs">Outside the walls of big tech monopolies</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="mt-8 border-t border-border pt-8 text-center">
|
||||
<p className="text-xs text-muted-foreground">Local-first • Zero-knowledge • Community-owned</p>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
)
|
||||
}
|
||||
|
|
@ -0,0 +1,74 @@
|
|||
import { Button } from "@/components/ui/button"
|
||||
import { Sparkles } from "lucide-react"
|
||||
|
||||
export function Hero() {
|
||||
return (
|
||||
<section className="relative overflow-hidden border-b-4 border-primary">
|
||||
<div className="absolute inset-0 bg-[linear-gradient(45deg,transparent_25%,oklch(0.75_0.18_195/0.05)_25%,oklch(0.75_0.18_195/0.05)_50%,transparent_50%,transparent_75%,oklch(0.75_0.18_195/0.05)_75%)] bg-[length:20px_20px]" />
|
||||
<div className="absolute inset-0 bg-[radial-gradient(circle_at_50%_50%,oklch(0.72_0.19_45/0.1),transparent_50%)]" />
|
||||
|
||||
<div className="relative mx-auto max-w-7xl px-4 py-24 sm:px-6 lg:px-8 lg:py-32">
|
||||
<div className="text-center">
|
||||
<div className="mb-8 flex justify-center">
|
||||
<div className="relative">
|
||||
<div className="absolute inset-0 animate-pulse blur-2xl bg-primary/30" />
|
||||
<div className="absolute -inset-4 animate-pulse blur-3xl bg-accent/20 glitter" />
|
||||
<h1 className="relative text-6xl font-bold tracking-tight sm:text-7xl lg:text-9xl retro-shadow">
|
||||
<span className="text-primary drop-shadow-[0_0_15px_oklch(0.75_0.18_195)]">r</span>
|
||||
<span className="text-foreground">space</span>
|
||||
<span className="text-secondary drop-shadow-[0_0_15px_oklch(0.72_0.19_45)]">.tech</span>
|
||||
</h1>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="mx-auto max-w-3xl space-y-4">
|
||||
<p className="text-2xl font-bold leading-relaxed text-primary sm:text-3xl text-balance">
|
||||
Remember when the internet was <span className="text-accent">cool</span>?
|
||||
</p>
|
||||
<p className="text-xl leading-relaxed text-muted-foreground sm:text-2xl text-balance">
|
||||
<span className="font-bold text-foreground">r</span>space isn't just <em>my</em>space —
|
||||
</p>
|
||||
<p className="text-3xl font-bold leading-relaxed sm:text-4xl text-balance">
|
||||
It's <span className="text-secondary drop-shadow-[0_0_10px_oklch(0.72_0.19_45)]">OUR</span>
|
||||
<span className="text-foreground">space</span>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<p className="mx-auto mt-8 max-w-2xl text-lg leading-relaxed text-muted-foreground sm:text-xl">
|
||||
Build digital spaces that improve your <span className="font-semibold text-primary">physical world</span>.
|
||||
Local-first, zero-knowledge privacy, outside the walls of big tech monopolies.
|
||||
</p>
|
||||
|
||||
<div className="mt-12 flex flex-col items-center justify-center gap-4 sm:flex-row">
|
||||
<Button
|
||||
size="lg"
|
||||
className="group relative overflow-hidden bg-primary text-primary-foreground hover:bg-primary/90 retro-shadow-sm hover:translate-x-[2px] hover:translate-y-[2px] hover:shadow-none transition-all"
|
||||
>
|
||||
<span className="relative z-10 flex items-center gap-2">
|
||||
<Sparkles className="h-5 w-5" />
|
||||
Create Your rSpace
|
||||
</span>
|
||||
</Button>
|
||||
<Button
|
||||
size="lg"
|
||||
variant="outline"
|
||||
className="border-2 border-secondary text-secondary hover:bg-secondary hover:text-secondary-foreground bg-transparent retro-shadow-sm hover:translate-x-[2px] hover:translate-y-[2px] hover:shadow-none transition-all"
|
||||
>
|
||||
See Real Examples
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
<div className="mt-16 inline-flex flex-wrap items-center justify-center gap-4 rounded-lg border-2 border-primary bg-card/80 px-8 py-4 text-sm backdrop-blur-sm retro-shadow">
|
||||
<span className="font-bold text-primary">★</span>
|
||||
<span className="text-muted-foreground">Zero-Knowledge Privacy</span>
|
||||
<span className="text-primary">•</span>
|
||||
<span className="text-muted-foreground">Community Owned</span>
|
||||
<span className="text-secondary">•</span>
|
||||
<span className="text-muted-foreground">Local-First</span>
|
||||
<span className="font-bold text-secondary">★</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
)
|
||||
}
|
||||
|
|
@ -0,0 +1,68 @@
|
|||
import { Code2, Database, Cpu } from "lucide-react"
|
||||
|
||||
const steps = [
|
||||
{
|
||||
number: "01",
|
||||
icon: Code2,
|
||||
title: "Built on folkjs",
|
||||
description:
|
||||
"HTML as a computing substrate. Interactive, reactive interfaces using familiar web technologies - no complex frameworks required.",
|
||||
},
|
||||
{
|
||||
number: "02",
|
||||
icon: Database,
|
||||
title: "Local-First Storage",
|
||||
description:
|
||||
"Your data lives on your device. Distributed sync protocols keep your rspace updated across the mesh without centralized servers.",
|
||||
},
|
||||
{
|
||||
number: "03",
|
||||
icon: Cpu,
|
||||
title: "Zero-Knowledge Architecture",
|
||||
description:
|
||||
"All encryption happens on your device. Share selectively through cryptographic proofs. Nobody can access what they shouldn't see.",
|
||||
},
|
||||
]
|
||||
|
||||
export function HowItWorks() {
|
||||
return (
|
||||
<section className="border-b border-border bg-card/30 py-24">
|
||||
<div className="mx-auto max-w-7xl px-4 sm:px-6 lg:px-8">
|
||||
<div className="text-center">
|
||||
<h2 className="text-3xl font-bold tracking-tight text-foreground sm:text-4xl">Built Different</h2>
|
||||
<p className="mt-4 text-lg text-muted-foreground">A new substrate for digital collaboration</p>
|
||||
</div>
|
||||
|
||||
<div className="mt-16 grid gap-8 md:grid-cols-3">
|
||||
{steps.map((step, index) => {
|
||||
const Icon = step.icon
|
||||
return (
|
||||
<div key={index} className="relative">
|
||||
<div className="flex flex-col items-start">
|
||||
<div className="mb-4 text-7xl font-bold text-primary/10">{step.number}</div>
|
||||
<div className="mb-4 inline-flex rounded-lg bg-primary/10 p-3 text-primary">
|
||||
<Icon className="h-6 w-6" />
|
||||
</div>
|
||||
<h3 className="mb-3 text-xl font-semibold text-foreground">{step.title}</h3>
|
||||
<p className="text-sm leading-relaxed text-muted-foreground">{step.description}</p>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
})}
|
||||
</div>
|
||||
|
||||
<div className="mt-16 rounded-lg border border-border bg-card p-8">
|
||||
<div className="text-center">
|
||||
<p className="text-lg font-medium text-foreground">
|
||||
Powered by <span className="font-mono text-primary">folkjs</span> - bringing the internet back to what it
|
||||
was always meant to be
|
||||
</p>
|
||||
<p className="mt-2 text-sm text-muted-foreground">
|
||||
A basic HTML computing substrate for building truly interactive, local-first applications
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
)
|
||||
}
|
||||
|
|
@ -0,0 +1,65 @@
|
|||
import { Button } from "@/components/ui/button"
|
||||
import { ExternalLink } from "lucide-react"
|
||||
|
||||
const links = [
|
||||
{
|
||||
name: "post-appitalism.app",
|
||||
url: "https://post-appitalism.app",
|
||||
description: "Breaking free from app dependencies. Together.",
|
||||
},
|
||||
{
|
||||
name: "alltor.net",
|
||||
url: "https://alltor.net",
|
||||
description: "The alternative internet. Distributed, local-first, free from corporate control.",
|
||||
},
|
||||
]
|
||||
|
||||
export function Network() {
|
||||
return (
|
||||
<section className="border-b border-border py-24">
|
||||
<div className="mx-auto max-w-7xl px-4 sm:px-6 lg:px-8">
|
||||
<div className="text-center">
|
||||
<h2 className="text-3xl font-bold tracking-tight text-foreground sm:text-4xl">
|
||||
Join the <span className="text-secondary">Movement</span>
|
||||
</h2>
|
||||
<p className="mt-4 text-lg text-muted-foreground">
|
||||
Part of a growing ecosystem building alternatives to surveillance capitalism
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="mt-12 grid gap-6 md:grid-cols-2">
|
||||
{links.map((link, index) => (
|
||||
<a
|
||||
key={index}
|
||||
href={link.url}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="group relative overflow-hidden rounded-lg border border-border bg-card p-6 transition-all hover:border-primary/50 hover:shadow-lg hover:shadow-primary/5"
|
||||
>
|
||||
<div className="absolute inset-0 bg-gradient-to-br from-primary/5 to-transparent opacity-0 transition-opacity group-hover:opacity-100" />
|
||||
<div className="relative">
|
||||
<div className="mb-3 flex items-start justify-between">
|
||||
<h3 className="text-xl font-semibold text-primary group-hover:text-primary">{link.name}</h3>
|
||||
<ExternalLink className="h-5 w-5 text-muted-foreground transition-colors group-hover:text-primary" />
|
||||
</div>
|
||||
<p className="text-sm leading-relaxed text-muted-foreground">{link.description}</p>
|
||||
</div>
|
||||
</a>
|
||||
))}
|
||||
</div>
|
||||
|
||||
<div className="mt-16 text-center">
|
||||
<div className="inline-flex flex-col items-center gap-4 rounded-lg border border-secondary/20 bg-card p-8">
|
||||
<h3 className="text-2xl font-bold text-foreground">Ready to Reclaim Your Digital Space?</h3>
|
||||
<p className="max-w-lg text-balance text-muted-foreground">
|
||||
Join communities building the future of the web - one rspace at a time
|
||||
</p>
|
||||
<Button size="lg" className="mt-4 bg-secondary text-secondary-foreground hover:bg-secondary/90">
|
||||
Get Started
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
)
|
||||
}
|
||||
|
|
@ -0,0 +1,55 @@
|
|||
export function Philosophy() {
|
||||
return (
|
||||
<section className="border-b border-border py-24">
|
||||
<div className="mx-auto max-w-7xl px-4 sm:px-6 lg:px-8">
|
||||
<div className="grid gap-12 lg:grid-cols-2 lg:gap-16">
|
||||
<div>
|
||||
<h2 className="text-3xl font-bold tracking-tight text-foreground sm:text-4xl">
|
||||
The Internet as It Was <span className="text-secondary">Always Meant to Be</span>
|
||||
</h2>
|
||||
<div className="mt-6 space-y-4 text-base leading-relaxed text-muted-foreground">
|
||||
<p>
|
||||
The legacy internet has become a collection of walled gardens controlled by a handful of corporations.
|
||||
Your data is commodified. Your attention is sold. Your privacy is an illusion.
|
||||
</p>
|
||||
<p>
|
||||
<span className="font-semibold text-primary">rspace</span> is built on a simple principle: technology
|
||||
should serve people, not profit margins.
|
||||
</p>
|
||||
<p>
|
||||
We're bringing back the spirit of the early web - when MySpace let you express yourself, when
|
||||
communities formed around shared purpose, when the internet felt like it belonged to everyone.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="space-y-6">
|
||||
<div className="rounded-lg border border-primary/20 bg-card p-6">
|
||||
<h3 className="mb-3 text-xl font-semibold text-primary">Local-First Principles</h3>
|
||||
<p className="text-sm leading-relaxed text-muted-foreground">
|
||||
Your data lives on your devices. Work offline. Sync when connected. No central servers controlling your
|
||||
access or mining your information.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="rounded-lg border border-secondary/20 bg-card p-6">
|
||||
<h3 className="mb-3 text-xl font-semibold text-secondary">Communities of Purpose</h3>
|
||||
<p className="text-sm leading-relaxed text-muted-foreground">
|
||||
Build spaces around what matters - not what drives engagement metrics. Organize, collaborate, and govern
|
||||
democratically.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="rounded-lg border border-primary/20 bg-card p-6">
|
||||
<h3 className="mb-3 text-xl font-semibold text-primary">Zero Knowledge Privacy</h3>
|
||||
<p className="text-sm leading-relaxed text-muted-foreground">
|
||||
End-to-end encrypted by default. Your data never exists unencrypted outside your control. Surveillance
|
||||
capitalism has no place here.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
)
|
||||
}
|
||||
|
|
@ -0,0 +1,106 @@
|
|||
import { Card } from "@/components/ui/card"
|
||||
import { MapPin, Snowflake, Sprout, Users, Calendar, Coins } from "lucide-react"
|
||||
|
||||
const examples = [
|
||||
{
|
||||
icon: MapPin,
|
||||
title: "Litter Cleanup Bounties",
|
||||
description:
|
||||
"Map trash hotspots in your neighborhood, set bounties for cleanup tasks, track progress on an interactive dashboard, and reward community members who pitch in.",
|
||||
color: "text-primary",
|
||||
bgColor: "bg-primary/10",
|
||||
},
|
||||
{
|
||||
icon: Snowflake,
|
||||
title: "Snow Shoveling Co-op",
|
||||
description:
|
||||
"Elderly neighbors need help? Create a schedule, assign volunteers, track completed driveways, and manage community appreciation funds—all in your rspace.",
|
||||
color: "text-secondary",
|
||||
bgColor: "bg-secondary/10",
|
||||
},
|
||||
{
|
||||
icon: Sprout,
|
||||
title: "Lawn Care Exchange",
|
||||
description:
|
||||
"Trade services with neighbors: mow a lawn, earn credits for garden help. Track commitments, share equipment calendars, and build real community connections.",
|
||||
color: "text-accent",
|
||||
bgColor: "bg-accent/10",
|
||||
},
|
||||
{
|
||||
icon: Users,
|
||||
title: "Community Tool Library",
|
||||
description:
|
||||
"Share tools collectively. Schedule borrowing, track inventory, split maintenance costs through shared funds, and reduce waste by owning things together.",
|
||||
color: "text-primary",
|
||||
bgColor: "bg-primary/10",
|
||||
},
|
||||
{
|
||||
icon: Calendar,
|
||||
title: "Neighborhood Events",
|
||||
description:
|
||||
"Plan block parties, potlucks, or skill-sharing workshops. Poll for dates, coordinate food signups, and manage event budgets transparently.",
|
||||
color: "text-secondary",
|
||||
bgColor: "bg-secondary/10",
|
||||
},
|
||||
{
|
||||
icon: Coins,
|
||||
title: "Local Mutual Aid",
|
||||
description:
|
||||
"Pool resources for emergency support. Transparent fund management, democratic decision-making on aid distribution, all with zero-knowledge privacy.",
|
||||
color: "text-accent",
|
||||
bgColor: "bg-accent/10",
|
||||
},
|
||||
]
|
||||
|
||||
export function RealWorldExamples() {
|
||||
return (
|
||||
<section className="border-b-4 border-secondary bg-muted/30 py-24">
|
||||
<div className="mx-auto max-w-7xl px-4 sm:px-6 lg:px-8">
|
||||
<div className="text-center">
|
||||
<h2 className="text-4xl font-bold tracking-tight text-foreground sm:text-5xl retro-shadow-sm">
|
||||
Digital Spaces for <span className="text-primary">Physical</span> Impact
|
||||
</h2>
|
||||
<p className="mt-6 text-xl text-muted-foreground max-w-3xl mx-auto leading-relaxed">
|
||||
rspaces aren't just for chatting online—they're tools for making your{" "}
|
||||
<span className="font-semibold text-foreground">real neighborhood</span> better. Here's how communities are
|
||||
already using them:
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="mt-16 grid gap-6 sm:grid-cols-2 lg:grid-cols-3">
|
||||
{examples.map((example, index) => {
|
||||
const Icon = example.icon
|
||||
return (
|
||||
<Card
|
||||
key={index}
|
||||
className="group relative overflow-hidden border-2 border-border bg-card p-6 transition-all hover:border-primary hover:-translate-y-1 hover:retro-shadow-sm"
|
||||
>
|
||||
<div
|
||||
className={`absolute inset-0 ${example.bgColor} opacity-0 transition-opacity group-hover:opacity-100`}
|
||||
/>
|
||||
<div className="relative">
|
||||
<div
|
||||
className={`mb-4 inline-flex rounded-lg ${example.bgColor} p-3 ${example.color} border-2 border-current`}
|
||||
>
|
||||
<Icon className="h-7 w-7" />
|
||||
</div>
|
||||
<h3 className="mb-3 text-xl font-bold text-card-foreground">{example.title}</h3>
|
||||
<p className="text-sm leading-relaxed text-muted-foreground">{example.description}</p>
|
||||
</div>
|
||||
</Card>
|
||||
)
|
||||
})}
|
||||
</div>
|
||||
|
||||
<div className="mt-16 text-center">
|
||||
<div className="inline-block rounded-lg border-2 border-accent bg-accent/10 px-6 py-4 backdrop-blur-sm retro-shadow-sm">
|
||||
<p className="text-lg font-semibold text-foreground">
|
||||
<span className="text-accent">Your space.</span> <span className="text-primary">Your community.</span>{" "}
|
||||
<span className="text-secondary">Your rules.</span>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
)
|
||||
}
|
||||
|
|
@ -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>
|
||||
}
|
||||
|
|
@ -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 }
|
||||
|
|
@ -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,
|
||||
}
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
import { clsx, type ClassValue } from 'clsx'
|
||||
import { twMerge } from 'tailwind-merge'
|
||||
|
||||
export function cn(...inputs: ClassValue[]) {
|
||||
return twMerge(clsx(inputs))
|
||||
}
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
/** @type {import('next').NextConfig} */
|
||||
const nextConfig = {
|
||||
eslint: {
|
||||
ignoreDuringBuilds: true,
|
||||
},
|
||||
typescript: {
|
||||
ignoreBuildErrors: true,
|
||||
},
|
||||
images: {
|
||||
unoptimized: true,
|
||||
},
|
||||
}
|
||||
|
||||
export default nextConfig
|
||||
|
|
@ -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"
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
/** @type {import('postcss-load-config').Config} */
|
||||
const config = {
|
||||
plugins: {
|
||||
'@tailwindcss/postcss': {},
|
||||
},
|
||||
}
|
||||
|
||||
export default config
|
||||
|
After Width: | Height: | Size: 2.6 KiB |
|
After Width: | Height: | Size: 585 B |
|
After Width: | Height: | Size: 566 B |
|
|
@ -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 |
|
After Width: | Height: | Size: 568 B |
|
|
@ -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 |
|
After Width: | Height: | Size: 1.6 KiB |
|
After Width: | Height: | Size: 1.0 KiB |
|
|
@ -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 |
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
@ -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"]
|
||||
}
|
||||