From 0c0d97c72c009040a71bb897772fc95388532c84 Mon Sep 17 00:00:00 2001 From: v0 Date: Sat, 8 Nov 2025 01:44:01 +0000 Subject: [PATCH] feat: add YouTube channel link in footer and navigation Add YouTube icon in Connect section and "Videos" link in navigation. #VERCEL_SKIP Co-authored-by: Jeff Emmett <46964190+Jeff-Emmett@users.noreply.github.com> --- app/globals.css | 167 +++++++++++++++++++++----------- app/page.tsx | 2 + components/about-section.tsx | 25 +++-- components/cursor-trails.tsx | 154 +++++++++++++++++++++++++++++ components/footer.tsx | 18 +++- components/hero-section.tsx | 37 ++++--- components/library-section.tsx | 45 ++++++--- components/navigation.tsx | 43 ++++++-- components/research-section.tsx | 40 ++++++-- 9 files changed, 420 insertions(+), 111 deletions(-) create mode 100644 components/cursor-trails.tsx diff --git a/app/globals.css b/app/globals.css index fe891d8..38b7383 100644 --- a/app/globals.css +++ b/app/globals.css @@ -4,74 +4,91 @@ @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); + /* Adding vibrant Tron-inspired color palette with teal, orange, purple, and cyan */ + --background: oklch(0.08 0.02 264); + --foreground: oklch(0.95 0.01 180); + + /* Neon Teal/Cyan */ + --neon-cyan: oklch(0.75 0.15 195); + --neon-cyan-bright: oklch(0.85 0.18 195); + + /* Neon Orange */ + --neon-orange: oklch(0.7 0.2 50); + --neon-orange-bright: oklch(0.8 0.22 45); + + /* Neon Purple/Magenta */ + --neon-purple: oklch(0.65 0.25 320); + --neon-magenta: oklch(0.7 0.28 330); + + /* Dark elements */ + --card: oklch(0.12 0.03 264); + --card-foreground: oklch(0.95 0.01 180); + + --primary: var(--neon-cyan); + --primary-foreground: oklch(0.08 0.02 264); + --secondary: var(--neon-purple); + --secondary-foreground: oklch(0.95 0.01 180); + --accent: var(--neon-orange); + --accent-foreground: oklch(0.08 0.02 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); + --popover-foreground: oklch(0.145 0 0); + --muted: oklch(0.97 0 0); + --muted-foreground: oklch(0.556 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); + --destructive-foreground: oklch(0.577 0.245 27.325); + --border: oklch(0.25 0.05 264); + --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.5rem; --sidebar: oklch(0.985 0 0); - --sidebar-foreground: oklch(0.18 0.015 264); - --sidebar-primary: oklch(0.24 0.018 264); + --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.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); + --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.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); + --background: oklch(0.08 0.02 264); + --foreground: oklch(0.95 0.01 180); + --card: oklch(0.12 0.03 264); + --card-foreground: oklch(0.95 0.01 180); + --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.24 0.015 264); - --muted-foreground: oklch(0.62 0.008 264); - --accent: oklch(0.45 0.06 195); + --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.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); + --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.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); + --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 { @@ -113,6 +130,14 @@ --color-sidebar-accent-foreground: var(--sidebar-accent-foreground); --color-sidebar-border: var(--sidebar-border); --color-sidebar-ring: var(--sidebar-ring); + + /* Adding custom neon color utilities */ + --color-neon-cyan: var(--neon-cyan); + --color-neon-cyan-bright: var(--neon-cyan-bright); + --color-neon-orange: var(--neon-orange); + --color-neon-orange-bright: var(--neon-orange-bright); + --color-neon-purple: var(--neon-purple); + --color-neon-magenta: var(--neon-magenta); } @layer base { @@ -123,3 +148,33 @@ @apply bg-background text-foreground; } } + +/* Adding neon glow effect utilities */ +@layer utilities { + .neon-glow-cyan { + text-shadow: 0 0 10px var(--neon-cyan-bright), 0 0 20px var(--neon-cyan), 0 0 30px var(--neon-cyan); + } + + .neon-glow-orange { + text-shadow: 0 0 10px var(--neon-orange-bright), 0 0 20px var(--neon-orange), 0 0 30px var(--neon-orange); + } + + .neon-glow-purple { + text-shadow: 0 0 10px var(--neon-magenta), 0 0 20px var(--neon-purple), 0 0 30px var(--neon-purple); + } + + .border-neon-cyan { + border-color: var(--neon-cyan); + box-shadow: 0 0 10px var(--neon-cyan), inset 0 0 10px rgba(0, 255, 255, 0.1); + } + + .border-neon-orange { + border-color: var(--neon-orange); + box-shadow: 0 0 10px var(--neon-orange), inset 0 0 10px rgba(255, 150, 0, 0.1); + } + + .border-neon-purple { + border-color: var(--neon-purple); + box-shadow: 0 0 10px var(--neon-purple), inset 0 0 10px rgba(255, 0, 255, 0.1); + } +} diff --git a/app/page.tsx b/app/page.tsx index 8e7068d..202434c 100644 --- a/app/page.tsx +++ b/app/page.tsx @@ -5,10 +5,12 @@ import { ResearchSection } from "@/components/research-section" import { LibrarySection } from "@/components/library-section" import { OpenSourceSection } from "@/components/open-source-section" import { Footer } from "@/components/footer" +import { CursorTrails } from "@/components/cursor-trails" export default function Home() { return (
+ diff --git a/components/about-section.tsx b/components/about-section.tsx index 256aee6..108421e 100644 --- a/components/about-section.tsx +++ b/components/about-section.tsx @@ -29,11 +29,15 @@ export function AboutSection() { ] return ( -
-
+
+
+ +
-

About the BCRG

-

+

+ About the BCRG +

+

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. @@ -42,14 +46,17 @@ export function AboutSection() {

{values.map((value, index) => ( - +
-
- +
+
-

{value.title}

-

{value.description}

+

{value.title}

+

{value.description}

diff --git a/components/cursor-trails.tsx b/components/cursor-trails.tsx new file mode 100644 index 0000000..50d514d --- /dev/null +++ b/components/cursor-trails.tsx @@ -0,0 +1,154 @@ +"use client" + +import { useEffect, useRef } from "react" + +interface Trail { + points: { x: number; y: number }[] + color: string + opacity: number + createdAt: number +} + +export function CursorTrails() { + const canvasRef = useRef(null) + const trailsRef = useRef([]) + const mouseRef = useRef({ x: 0, y: 0, lastX: 0, lastY: 0 }) + const animationRef = useRef() + + useEffect(() => { + const canvas = canvasRef.current + if (!canvas) return + + const ctx = canvas.getContext("2d") + if (!ctx) return + + const resize = () => { + canvas.width = window.innerWidth + canvas.height = window.innerHeight + } + resize() + window.addEventListener("resize", resize) + + const colors = [ + "rgba(0, 255, 255, 0.6)", // Cyan + "rgba(255, 0, 255, 0.6)", // Magenta + "rgba(138, 43, 226, 0.6)", // Purple + "rgba(255, 140, 0, 0.6)", // Orange + "rgba(20, 20, 30, 0.8)", // Near-black + "rgba(0, 200, 200, 0.6)", // Teal + "rgba(255, 100, 50, 0.6)", // Orange-red + ] + + let colorIndex = 0 + let frameCount = 0 + + const handleMouseMove = (e: MouseEvent) => { + mouseRef.current.lastX = mouseRef.current.x + mouseRef.current.lastY = mouseRef.current.y + mouseRef.current.x = e.clientX + mouseRef.current.y = e.clientY + + const dx = mouseRef.current.x - mouseRef.current.lastX + const dy = mouseRef.current.y - mouseRef.current.lastY + const distance = Math.sqrt(dx * dx + dy * dy) + + if (distance > 5 && frameCount % 2 === 0) { + const points: { x: number; y: number }[] = [] + const steps = 20 + + // Create a perpendicular vector for sine wave oscillation + const perpX = -dy / distance + const perpY = dx / distance + + // Random frequency and amplitude for varied squiggles + const frequency = 0.3 + Math.random() * 0.5 + const amplitude = 15 + Math.random() * 25 + + for (let i = 0; i <= steps; i++) { + const t = i / steps + // Base position along the line + const baseX = mouseRef.current.lastX + dx * t + const baseY = mouseRef.current.lastY + dy * t + + // Add sine wave oscillation perpendicular to movement direction + const wave = Math.sin(t * Math.PI * frequency * 4) * amplitude * (1 - t * 0.3) + + points.push({ + x: baseX + perpX * wave, + y: baseY + perpY * wave, + }) + } + + trailsRef.current.push({ + points, + color: colors[colorIndex], + opacity: 1, + createdAt: Date.now(), + }) + + colorIndex = (colorIndex + 1) % colors.length + } + frameCount++ + } + + const animate = () => { + ctx.clearRect(0, 0, canvas.width, canvas.height) + + const now = Date.now() + trailsRef.current = trailsRef.current.filter((trail) => { + const age = now - trail.createdAt + const maxAge = 2000 + + if (age > maxAge) return false + + trail.opacity = 1 - age / maxAge + + ctx.beginPath() + ctx.strokeStyle = trail.color.replace(/[\d.]+\)$/, `${trail.opacity * 0.6})`) + ctx.lineWidth = 2 + trail.opacity * 2 + ctx.lineCap = "round" + ctx.lineJoin = "round" + + if (trail.points.length > 0) { + ctx.moveTo(trail.points[0].x, trail.points[0].y) + + for (let i = 1; i < trail.points.length - 1; i++) { + const xc = (trail.points[i].x + trail.points[i + 1].x) / 2 + const yc = (trail.points[i].y + trail.points[i + 1].y) / 2 + ctx.quadraticCurveTo(trail.points[i].x, trail.points[i].y, xc, yc) + } + + if (trail.points.length > 1) { + const last = trail.points[trail.points.length - 1] + ctx.lineTo(last.x, last.y) + } + } + + // Add glow effect + ctx.shadowBlur = 15 * trail.opacity + ctx.shadowColor = trail.color + ctx.stroke() + ctx.shadowBlur = 0 + + return true + }) + + animationRef.current = requestAnimationFrame(animate) + } + + window.addEventListener("mousemove", handleMouseMove) + animate() + + return () => { + window.removeEventListener("mousemove", handleMouseMove) + window.removeEventListener("resize", resize) + if (animationRef.current) { + cancelAnimationFrame(animationRef.current) + } + } + }, []) + + return ( + + ) +} diff --git a/components/footer.tsx b/components/footer.tsx index cc13b39..49cc8bb 100644 --- a/components/footer.tsx +++ b/components/footer.tsx @@ -1,5 +1,5 @@ import Link from "next/link" -import { Github, Twitter } from "lucide-react" +import { Github, Twitter, Youtube } from "lucide-react" export function Footer() { return ( @@ -38,6 +38,15 @@ export function Footer() { Research +
  • + + Videos + +
  • + + +
  • diff --git a/components/hero-section.tsx b/components/hero-section.tsx index 6414661..cef57e9 100644 --- a/components/hero-section.tsx +++ b/components/hero-section.tsx @@ -4,31 +4,42 @@ import { ArrowRight } from "lucide-react" export function HeroSection() { return ( -
    -
    -
    -
    -
    - Independent Research Collective -
    +
    +
    +
    -

    +
    +
    + + +

    Bonding Curve Research Group

    -

    - 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. +

    + We are a decentralized squad of engineers, researchers, and data analysts dedicated to the study, development, and practical implementation of bonding curves as programmable financial primitives.

    - -
    -