diff --git a/apps/web/app/(dashboard)/layout.tsx b/apps/web/app/(dashboard)/layout.tsx index da4002d..8afb423 100644 --- a/apps/web/app/(dashboard)/layout.tsx +++ b/apps/web/app/(dashboard)/layout.tsx @@ -1,6 +1,7 @@ import { CookieBanner } from '@/components/cookie-banner'; import { Logo } from '@/components/logo'; import { MobileActionBar } from '@/components/mobile-action-bar'; +import { PulseLink } from '@/components/pulse'; import { UserMenu } from '@/components/user-menu'; import { FileClock, LayoutGrid, Package, Server, Settings } from 'lucide-react'; import Link from 'next/link'; @@ -33,12 +34,12 @@ export default function DashboardLayout({ children }: { children: React.ReactNod
- + New server - +
diff --git a/apps/web/app/(marketing)/page.tsx b/apps/web/app/(marketing)/page.tsx index 734a5de..6438d07 100644 --- a/apps/web/app/(marketing)/page.tsx +++ b/apps/web/app/(marketing)/page.tsx @@ -1,6 +1,7 @@ import { HeroStepRotator } from '@/components/hero-step-rotator'; import { JsonLd } from '@/components/json-ld'; import { ParticleHero } from '@/components/particle-hero'; +import { PulseLink } from '@/components/pulse'; import { ScrollCue } from '@/components/scroll-cue'; import { StaticCodeBlock } from '@/components/static-code-block'; import { FAQ, faqJsonLd } from '@/lib/seo'; @@ -92,14 +93,20 @@ export default function Landing() { three artifacts (prompt → build.log → claude config) with a mouse-reactive 3D tilt and a step indicator. Shorter overall so the video section below is teased above the fold. */} -
+
{/* WebGL particle field — capability-detected client component. Sits behind the hero content at z-0 with pointer-events:none so the CTAs above remain fully interactive. The canvas listens for pointermove on window itself, so the ring still tracks - the cursor through the content above. */} + the cursor through the content above. With the hero now + filling the full first-viewport (minus the 48px sticky nav), + the field has cinematic-scale room and the indigo radial + glow + dot mask read as the dominant background motif. */} -
+
v0.1 — updated 2026-05-20 @@ -116,18 +123,18 @@ export default function Landing() { for Claude, Cursor and ChatGPT.

- Start building free - - + Read the docs - +
diff --git a/apps/web/app/globals.css b/apps/web/app/globals.css index 01f4dfc..ecec493 100644 --- a/apps/web/app/globals.css +++ b/apps/web/app/globals.css @@ -168,3 +168,29 @@ transform: translateY(0); } } + +/* Click-pulse for primary actions (see components/pulse.tsx). + Scales a small indigo dot from 1x to 80x over 650ms — on a 2px base + that's ~160px max radius, comfortably larger than any button on the + site. The translate(-50%, -50%) keeps the dot anchored to the click + point as it grows. Reduced-motion users get an instant fade-out so + the click action still proceeds without the bloom. */ +@keyframes glow-pulse { + 0% { + transform: translate(-50%, -50%) scale(1); + opacity: 0.85; + } + 100% { + transform: translate(-50%, -50%) scale(80); + opacity: 0; + } +} +@media (prefers-reduced-motion: reduce) { + @keyframes glow-pulse { + 0%, + 100% { + transform: translate(-50%, -50%) scale(1); + opacity: 0; + } + } +} diff --git a/apps/web/components/marketing-auth-buttons.tsx b/apps/web/components/marketing-auth-buttons.tsx index a126603..6394d53 100644 --- a/apps/web/components/marketing-auth-buttons.tsx +++ b/apps/web/components/marketing-auth-buttons.tsx @@ -1,7 +1,7 @@ 'use client'; +import { PulseLink } from '@/components/pulse'; import { apiFetch } from '@/lib/api'; -import Link from 'next/link'; import { useEffect, useState } from 'react'; /** @@ -26,11 +26,11 @@ export function MarketingAuthButtons() { const showDashboard = authed === true; return ( - {showDashboard ? 'Dashboard' : 'Login'} - + ); } diff --git a/apps/web/components/pulse.tsx b/apps/web/components/pulse.tsx new file mode 100644 index 0000000..6511b35 --- /dev/null +++ b/apps/web/components/pulse.tsx @@ -0,0 +1,121 @@ +'use client'; + +import Link from 'next/link'; +import { + type ComponentProps, + type MouseEvent as ReactMouseEvent, + useRef, + useState, +} from 'react'; + +interface Pulse { + id: number; + x: number; // percentage 0-100 + y: number; +} + +/** + * Shared indigo glow-pulse-on-click effect used by hero CTAs and other + * primary actions across the site. Same visual language as the hero + * load-in glow — a small bright dot detonates from the click point and + * scales out fast, fading to transparent. + * + * Two variants exposed: + * - wraps next/link + * - wraps a native + ); +}