From b95977ee4b4fb977cc01fb999ff8fc9f1cb7d1a5 Mon Sep 17 00:00:00 2001 From: dexalien Date: Mon, 1 Jun 2026 01:40:57 -0400 Subject: [PATCH 001/103] chore: remove package-lock.json, use pnpm only Co-Authored-By: Claude Sonnet 4.6 --- pnpm-workspace.yaml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index 581a9d5..cc26c4c 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -1,3 +1,6 @@ +packages: + - "." + ignoredBuiltDependencies: - sharp - unrs-resolver From 155cf46e2c043b31b7ce1389ed25985e50b336ce Mon Sep 17 00:00:00 2001 From: dexalien Date: Mon, 1 Jun 2026 04:11:42 -0400 Subject: [PATCH 002/103] feat: migrate v0 aesthetic to openhouse landing page - Rebuilt hero with v0 2x2 grid layout, ScrambleText, floating mascot, gradient CTA button - Replaced Features (2 cards) with 3-pillar layout: Communities / Hack Spaces / Hacker Houses - Migrated Archetypes, HowItWorks, FinalCta to v0 hex color style - Added new sections: Marquee strip, Verification, HackTheWorld, ProblemWeSolve - Removed EventCallout (ETH Global Cannes) - Updated navbar and auth button to v0 gradient style - Copied assets from v0: logo.png, logo-text.png, globe-logo.gif, cat gifs - Fixed favicon: removed default Next.js ico, use cat mascot via icon.png + metadata - Color scheme: #180149 bg, #1A1740 cards, no framer-motion (Tailwind transitions) Co-Authored-By: Claude Sonnet 4.6 --- .../_components/landing/archetypes.tsx | 83 ++++----- app/(public)/_components/landing/features.tsx | 159 +++++++++--------- .../_components/landing/final-cta.tsx | 42 +---- app/(public)/_components/landing/footer.tsx | 3 - .../_components/landing/hack-the-world.tsx | 69 ++++++++ app/(public)/_components/landing/hero-cta.tsx | 17 +- app/(public)/_components/landing/hero.tsx | 126 ++++++-------- .../_components/landing/how-it-works.tsx | 82 +++------ app/(public)/_components/landing/marquee.tsx | 18 ++ app/(public)/_components/landing/navbar.tsx | 14 +- .../_components/landing/problem-we-solve.tsx | 66 ++++++++ .../_components/landing/scramble-text.tsx | 78 +++++++++ .../_components/landing/verification.tsx | 40 +++++ app/(public)/page.tsx | 12 +- app/apple-icon.png | Bin 0 -> 2626 bytes app/favicon.ico | Bin 25931 -> 0 bytes app/globals.css | 9 + app/icon.png | Bin 0 -> 3627451 bytes app/layout.tsx | 4 + components/auth/auth-button.tsx | 14 +- public/cypher-kitten/cat-crying.gif | Bin 0 -> 6725 bytes public/cypher-kitten/cats-happy.png | Bin 0 -> 3455 bytes public/globe-logo.gif | Bin 0 -> 1338413 bytes public/logo-text.png | Bin 0 -> 626980 bytes public/logo.png | Bin 0 -> 3627451 bytes 25 files changed, 506 insertions(+), 330 deletions(-) create mode 100644 app/(public)/_components/landing/hack-the-world.tsx create mode 100644 app/(public)/_components/landing/marquee.tsx create mode 100644 app/(public)/_components/landing/problem-we-solve.tsx create mode 100644 app/(public)/_components/landing/scramble-text.tsx create mode 100644 app/(public)/_components/landing/verification.tsx create mode 100644 app/apple-icon.png delete mode 100644 app/favicon.ico create mode 100644 app/icon.png create mode 100644 public/cypher-kitten/cat-crying.gif create mode 100644 public/cypher-kitten/cats-happy.png create mode 100644 public/globe-logo.gif create mode 100644 public/logo-text.png create mode 100644 public/logo.png diff --git a/app/(public)/_components/landing/archetypes.tsx b/app/(public)/_components/landing/archetypes.tsx index f65a360..25129fe 100644 --- a/app/(public)/_components/landing/archetypes.tsx +++ b/app/(public)/_components/landing/archetypes.tsx @@ -1,78 +1,82 @@ const archetypes = [ { name: "The Visionary", - tagline: "You have the idea. The vision is clear — the team isn't.", + emoji: "💡", + tagline: "The one with the idea", body: "You define direction, generate narrative, and attract talent. You need builders who can execute on what you see.", skills: ["Founder", "Product", "Vision"], - colorVar: "--visionary", + color: "#990070", }, { name: "The Strategist", - tagline: "You see the whole board. You connect the pieces.", + emoji: "♟", + tagline: "The one who connects the dots", body: "GTM, ops, partnerships, execution. You turn chaos into roadmap. You need a Visionary's idea and a Builder's hands.", skills: ["GTM", "Operations", "Partnerships"], - colorVar: "--strategist", + color: "#8B78E6", }, { name: "The Builder", + emoji: "⚙️", tagline: "You ship. That's it. That's the whole bio.", body: "Frontend, backend, smart contracts, design — you make the thing real. The most wanted archetype on the protocol.", skills: ["Frontend", "Backend", "Smart Contracts", "Design"], - colorVar: "--builder-archetype", + color: "#6EE76E", }, ] export function Archetypes() { return ( -
-
- {/* Header */} -
-

- Every builder has a role. +
+
+
+

+ {"What's your archetype?"}

-

+

The protocol matches you based on yours.

- {/* Cards */} -
- {archetypes.map((archetype) => ( +
+ {archetypes.map((a) => (
-
-

- {archetype.name} +
+ {a.emoji} +
+ +
+

+ {a.name}

-

- {archetype.tagline} +

+ {a.tagline}

-

- {archetype.body} +

+ {a.body}

- {/* Skill pills */} -
- {archetype.skills.map((skill) => ( +
+ {a.skills.map((skill) => ( {skill} @@ -83,8 +87,7 @@ export function Archetypes() { ))}
- {/* Footer line */} -

+

Choose your archetype. The algorithm does the rest.

diff --git a/app/(public)/_components/landing/features.tsx b/app/(public)/_components/landing/features.tsx index ae50c29..782edde 100644 --- a/app/(public)/_components/landing/features.tsx +++ b/app/(public)/_components/landing/features.tsx @@ -1,94 +1,87 @@ +import { Users, Map, Home } from "lucide-react" + +const features = [ + { + icon: Users, + title: "Communities", + subtitle: "Build your scene. Grow your tribe.", + body: "Permanent hubs for groups with identity — DAOs, local scenes, builder collectives. Unlimited members, public or private. Spawn Hack Spaces and Hacker Houses directly from your community.", + tags: ["DAOs", "Local Scenes", "Protocols", "Collectives"], + color: "#8B78E6", + }, + { + icon: Map, + title: "Hack Spaces", + subtitle: "Project rooms for teams building in public.", + body: "Post your project, define the roles you need, and match with builders who complement your skills — not who replicate them. Your on-chain credentials speak for you.", + tags: ["DeFi", "AI", "Smart Contracts", "DAO"], + color: "#6B00C9", + }, + { + icon: Home, + title: "Hacker Houses", + subtitle: "Co-living IRL. Skin in the game.", + body: "Stake to secure your slot. A Key NFT per room. Physical spaces during events and in active builder cities — coordinated, filtered, and optimized for shipping code.", + tags: ["Free", "Paid", "With Staking"], + color: "#6EE76E", + }, +] + export function Features() { return ( -
-
- {/* Header */} -
-

- Two ways to build. One protocol. +
+
+
+

+ One protocol. Three ways to build.

- {/* Cards */} -
- {/* Hack Spaces — primary feature */} -
-
- 🔗 -

- Hack Spaces -

-

- Find your team. Build together. -

-
- -

- Post your project, define the roles you need, and let the algorithm - match you with builders who fit — by archetype, skills, region, and - language. -

-

- No scrolling through profiles. No cold DMs into the void. Just - high-signal matches for the work you actually want to ship. -

- -
    - {[ - "Algorithmic matching by archetype and skill set", - "Post a project or join one already forming", - "Your on-chain credentials speak for you", - ].map((item) => ( -
  • - - → - - {item} -
  • - ))} -
-
+
+ {features.map((f) => { + const Icon = f.icon + return ( +
+
+ +
- {/* Hacker Houses */} -
-
- 🏠 -

- Hacker Houses -

-

- Live with your team. Show up IRL. -

-
+
+

+ {f.title} +

+

+ {f.subtitle} +

+
-

- When your team is ready to meet in person, spin up a Hacker House. - Co-living with builders in event cities — coordinated, filtered, and - builder-optimized. -

-

- Not Airbnb. Not a hostel. A protocol for building together in the - same room. -

+

+ {f.body} +

-
    - {[ - "Spaces in key cities and event hubs", - "Builder-filtered — no randoms", - "Sponsored houses available from verified organizations", - ].map((item) => ( -
  • - - → - - {item} -
  • - ))} -
-
+
+ {f.tags.map((tag) => ( + + {tag} + + ))} +
+
+ ) + })}
diff --git a/app/(public)/_components/landing/final-cta.tsx b/app/(public)/_components/landing/final-cta.tsx index 4ff7365..b773a5c 100644 --- a/app/(public)/_components/landing/final-cta.tsx +++ b/app/(public)/_components/landing/final-cta.tsx @@ -2,43 +2,15 @@ import { AuthButton } from "@/components/auth/auth-button" export function FinalCta() { return ( -
-
- {/* Headline */} -
-

- The builder OS is live. -

-

- Join the protocol. Find your team. Ship. -

-
+
+
+

+ Ready to create your own Hacker House? +

+ + - {/* Supporting copy */} -
-

- Browse Hack Spaces, post your project, match with co-founders by - archetype, and coordinate IRL at Hacker Houses near you. -

-

- Free. Always. -

-
- {/* CTA */} -
- -

- No credit card. Connect your wallet or sign up with email. -

-
) diff --git a/app/(public)/_components/landing/footer.tsx b/app/(public)/_components/landing/footer.tsx index dcf0998..008b293 100644 --- a/app/(public)/_components/landing/footer.tsx +++ b/app/(public)/_components/landing/footer.tsx @@ -59,9 +59,6 @@ export function Footer() { {/* Bottom line */}
-

- Built by builders. For builders. -

hackerhouse.app · © 2026 Hacker House Protocol

diff --git a/app/(public)/_components/landing/hack-the-world.tsx b/app/(public)/_components/landing/hack-the-world.tsx new file mode 100644 index 0000000..cf3ba43 --- /dev/null +++ b/app/(public)/_components/landing/hack-the-world.tsx @@ -0,0 +1,69 @@ +export function HackTheWorld() { + return ( +
+
+
+ {/* Left — text */} +
+

+ Hack The World +

+

+ From Arbitrum Open House to DevCon — HHP is the coordination + layer for builders who show up IRL. We create spaces where you + can live, work, and ship together. +

+ +
+ {[ + { + number: "1", + color: "#6EE76E", + title: "Co-living during events", + desc: "Share a house with fellow hackers during major hackathons and conferences.", + }, + { + number: "2", + color: "#8B78E6", + title: "Match before you arrive", + desc: "Form your team online with complementary archetypes — show up ready to build.", + }, + { + number: "3", + color: "#990070", + title: "Ship together", + desc: "Collaborate in-person, build winning projects, and keep building after the event ends.", + }, + ].map((item) => ( +
+
+ {item.number} +
+
+

{item.title}

+

{item.desc}

+
+
+ ))} +
+
+ + {/* Right — globe */} +
+ Global network of hacker houses +
+
+
+
+ ) +} diff --git a/app/(public)/_components/landing/hero-cta.tsx b/app/(public)/_components/landing/hero-cta.tsx index 79bfcc8..4579e72 100644 --- a/app/(public)/_components/landing/hero-cta.tsx +++ b/app/(public)/_components/landing/hero-cta.tsx @@ -1,10 +1,12 @@ "use client" import Link from "next/link" -import { Button } from "@/components/ui/button" import { AuthButton } from "@/components/auth/auth-button" import { useAuth } from "@/hooks/use-auth" +const btnClass = + "h-14 px-10 inline-flex items-center justify-center bg-gradient-to-r from-pink-500 to-purple-600 hover:from-pink-600 hover:to-purple-700 text-white text-lg font-bold rounded-xl border-2 border-purple-400/30 shadow-2xl transition-all duration-300 hover:scale-[1.02]" + export function HeroCta() { const { isAuthenticated, isLoading } = useAuth() @@ -12,16 +14,11 @@ export function HeroCta() { if (isAuthenticated) { return ( - + + Go to Dashboard → + ) } - return ( - - ) + return } diff --git a/app/(public)/_components/landing/hero.tsx b/app/(public)/_components/landing/hero.tsx index 10b36db..5fa339d 100644 --- a/app/(public)/_components/landing/hero.tsx +++ b/app/(public)/_components/landing/hero.tsx @@ -1,100 +1,68 @@ import { MatrixBackground } from "./matrix-background" import { HeroCta } from "./hero-cta" +import { ScrambleText } from "./scramble-text" export function Hero() { return ( -
+
- {/* Background glow */} -
-
- {/* Left — copy */} -
- {/* Badges */} -
- {["Open Beta", "Free to use", "Web3-native"].map((label) => ( - - {label} - - ))} -
- - {/* Headline */} -
-

- Match. -

-

- Build. -

-

- Co-Live. -

-
- - {/* Subheadline */} -
-

- The operating system for the builder scene. -

-

- Connect with Visionaries, Strategists, and Builders. -

-

- Form your team online. Show up IRL. -

-
+ {/* Mobile layout — stacked */} +
+ Hacker House Protocol + Hacker House Protocol +

+ +

+ +
- {/* CTA */} -
- -

- Free forever. Connect your wallet or sign up with email. -

-
+ {/* Desktop layout — 2×2 grid */} +
+ {/* Row 1, Col 1: Logo text */} +
+ Hacker House Protocol
- {/* Right — visual */} -
+ {/* Row 1, Col 2: Mascot */} +
Hacker House Protocol - {/* Archetype color dots */} -
- - - -
+
+ + {/* Row 2, Col 1: Headline */} +
+

+ +

+
+ + {/* Row 2, Col 2: CTA */} +
+
diff --git a/app/(public)/_components/landing/how-it-works.tsx b/app/(public)/_components/landing/how-it-works.tsx index b767bfa..706e3df 100644 --- a/app/(public)/_components/landing/how-it-works.tsx +++ b/app/(public)/_components/landing/how-it-works.tsx @@ -1,83 +1,51 @@ const steps = [ { - number: "01", + number: "1", title: "Create your Cypher Identity", - body: "Connect your wallet or sign up with email. Your on-chain credentials — POAPs, contributions, Talent Protocol score — import automatically.", - footnote: "Your identity lives on the protocol. Not on a platform.", + body: "Connect wallet or email. POAPs, NFTs and on-chain credentials import automatically.", }, { - number: "02", - title: "Find your match", - body: "Browse Hack Spaces looking for your archetype and skills. Or post your own project and let builders find you.", - footnote: "The algorithm surfaces the right fits. You pick who to build with.", + number: "2", + title: "Match with complementary builders", + body: "Post your project or browse Hack Spaces. The algorithm finds who fits — not who copies you.", }, { - number: "03", - title: "Build IRL", - body: "When the team is ready, spin up a Hacker House. Meet. Build. Ship.", - footnote: "The protocol takes you from idea to room in the same building.", + number: "3", + title: "Coordinate, build, ship", + body: "Join a Community, spin up a Hack Space, or secure your slot in a Hacker House. Meet IRL. Ship.", }, ] export function HowItWorks() { return ( -
-
- {/* Header */} -
-

- Three steps. Then you're building. +
+
+
+

+ How It Works

- {/* Steps */} -
- {/* Connector line — desktop only */} -
- - {steps.map((step, i) => ( +
+ {steps.map((step) => (
- {/* Vertical connector — mobile only */} - {i < steps.length - 1 && ( -
- )} - - {/* Step number */} - - {step.number} - - +
+
+ + {step.number} + +
+
-

+

{step.title}

-

+

{step.body}

-

- {step.footnote} -

))} diff --git a/app/(public)/_components/landing/marquee.tsx b/app/(public)/_components/landing/marquee.tsx new file mode 100644 index 0000000..221e969 --- /dev/null +++ b/app/(public)/_components/landing/marquee.tsx @@ -0,0 +1,18 @@ +export function Marquee() { + return ( +
+
+ {[...Array(4)].map((_, i) => ( + + FIND YOUR COMMUNITY  ·  BUILD YOUR HACK SPACE  ·  CO-LIVE IN HACKER HOUSES AROUND THE WORLD  ·   + + ))} + {[...Array(4)].map((_, i) => ( + + FIND YOUR COMMUNITY  ·  BUILD YOUR HACK SPACE  ·  CO-LIVE IN HACKER HOUSES AROUND THE WORLD  ·   + + ))} +
+
+ ) +} diff --git a/app/(public)/_components/landing/navbar.tsx b/app/(public)/_components/landing/navbar.tsx index cf689f2..e4b841a 100644 --- a/app/(public)/_components/landing/navbar.tsx +++ b/app/(public)/_components/landing/navbar.tsx @@ -6,7 +6,6 @@ import Image from "next/image" import { cn } from "@/lib/utils" import { AuthButton } from "@/components/auth/auth-button" import { useAuth } from "@/hooks/use-auth" -import { Button } from "@/components/ui/button" export function Navbar() { const [scrolled, setScrolled] = useState(false) @@ -42,15 +41,14 @@ export function Navbar() {
{!isLoading && isAuthenticated ? ( - + Join the protocol + ) : ( - + )} diff --git a/app/(public)/_components/landing/problem-we-solve.tsx b/app/(public)/_components/landing/problem-we-solve.tsx new file mode 100644 index 0000000..e349103 --- /dev/null +++ b/app/(public)/_components/landing/problem-we-solve.tsx @@ -0,0 +1,66 @@ +const problems = [ + { + title: "No Coordination Layer", + body: "You meet the right builder at a hackathon. Pure luck. There's no system to match you by what you actually bring — only by who you happen to sit next to.", + color: "#990070", + }, + { + title: "Housing is a Nightmare", + body: "Expensive hotels, sketchy Airbnbs, or sleeping at the venue. Finding trusted builders to co-live with requires weeks of manual pre-selection.", + color: "#8B78E6", + }, + { + title: "Connections That Fade", + body: "You meet your future co-founder at DevCon. Then Discord. Then silence. There's no persistent layer to keep builders building together after events end.", + color: "#6EE76E", + }, +] + +export function ProblemWeSolve() { + return ( +
+
+
+

+ The Problem We Solve +

+

+ Hackathons are where builders meet. But the coordination layer has + never existed — until now. +

+
+ +
+ {/* Cat */} +
+ Frustrated builder +
+ + {/* Problem cards */} +
+ {problems.map((p) => ( +
+

+ {p.title} +

+

+ {p.body} +

+
+ ))} +
+
+
+
+ ) +} diff --git a/app/(public)/_components/landing/scramble-text.tsx b/app/(public)/_components/landing/scramble-text.tsx new file mode 100644 index 0000000..126e55c --- /dev/null +++ b/app/(public)/_components/landing/scramble-text.tsx @@ -0,0 +1,78 @@ +"use client" + +import { useEffect, useState, useRef } from "react" + +interface ScrambleTextProps { + text: string + className?: string + scrambleOnHover?: boolean + autoScramble?: boolean + scrambleInterval?: number +} + +export function ScrambleText({ + text, + className = "", + scrambleOnHover = false, + autoScramble = true, + scrambleInterval = 5000 +}: ScrambleTextProps) { + const [displayText, setDisplayText] = useState(text) + const isScrambling = useRef(false) + const intervalRef = useRef(null) + const animationRef = useRef(null) + + const scrambleChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%&*<>[]{}+=?:~" + + const scramble = () => { + if (isScrambling.current) return + isScrambling.current = true + + let iteration = 0 + const maxIterations = text.length * 3 + + animationRef.current = setInterval(() => { + let result = "" + for (let i = 0; i < text.length; i++) { + if (text[i] === " ") { + result += " " + } else if (i < iteration / 3) { + result += text[i] + } else { + result += scrambleChars[Math.floor(Math.random() * scrambleChars.length)] + } + } + + setDisplayText(result) + iteration++ + + if (iteration >= maxIterations) { + if (animationRef.current) clearInterval(animationRef.current) + setDisplayText(text) + isScrambling.current = false + } + }, 30) + } + + useEffect(() => { + setDisplayText(text) + + if (autoScramble) { + const initialTimeout = setTimeout(scramble, 100) + + intervalRef.current = setInterval(scramble, scrambleInterval) + + return () => { + clearTimeout(initialTimeout) + if (intervalRef.current) clearInterval(intervalRef.current) + if (animationRef.current) clearInterval(animationRef.current) + } + } + }, [text, autoScramble, scrambleInterval]) + + return ( + + {displayText} + + ) +} diff --git a/app/(public)/_components/landing/verification.tsx b/app/(public)/_components/landing/verification.tsx new file mode 100644 index 0000000..66dfb5f --- /dev/null +++ b/app/(public)/_components/landing/verification.tsx @@ -0,0 +1,40 @@ +export function Verification() { + return ( +
+
+

+ Your Web3 history matters. +

+

+ Bring your on-chain reputation, verified skills, NFTs and POAPs to + your profile. No manual forms. No LinkedIn. +

+ +
+ {[ + { label: "On-chain reputation", color: "#6B00C9" }, + { label: "Verified skills", color: "#8B78E6" }, + { label: "NFTs & POAPs", color: "#990070" }, + { label: "Talent Protocol score", color: "#6EE76E" }, + ].map((item) => ( +
+ {item.label} +
+ ))} +
+ +

+ Your identity lives on the protocol. Not on a platform. +

+
+
+ ) +} diff --git a/app/(public)/page.tsx b/app/(public)/page.tsx index b4ba179..443cafd 100644 --- a/app/(public)/page.tsx +++ b/app/(public)/page.tsx @@ -1,10 +1,13 @@ import type { Metadata } from "next" import { Navbar } from "./_components/landing/navbar" import { Hero } from "./_components/landing/hero" +import { Marquee } from "./_components/landing/marquee" import { Features } from "./_components/landing/features" import { Archetypes } from "./_components/landing/archetypes" +import { Verification } from "./_components/landing/verification" +import { HackTheWorld } from "./_components/landing/hack-the-world" +import { ProblemWeSolve } from "./_components/landing/problem-we-solve" import { HowItWorks } from "./_components/landing/how-it-works" -import { EventCallout } from "./_components/landing/event-callout" import { FinalCta } from "./_components/landing/final-cta" import { Footer } from "./_components/landing/footer" @@ -38,13 +41,16 @@ export const metadata: Metadata = { export default function LandingPage() { return ( -
+
+ + + + -