CodeIssuesDiscussionsWikiPull RequestsProjectsCommitsActionsReleasesContributorsPulse● GatesSecuritySettingsDeploymentsPipelineInsightsAgents✨ Explain✨ Ask AI✨ Workspace✨ Spec✨ Tests▓ Debt Map✨ NL Search🏛 Archaeology
Blame · Line-by-line history
landing-2030.tsx
Each line is annotated with the commit that last touched it. Click any SHA to jump to that commit and see the surrounding change.
| 29924bc | 1 | /** |
| 2 | * Landing2030 — the public marketing landing page. | |
| 3 | * | |
| 4 | * A fully self-contained light HTML document (its own <head>, fonts, and CSS) | |
| 5 | * rendered directly from the root route, bypassing the dark app Layout so the | |
| 6 | * marketing surface can be a pristine, Linear/Vercel-grade design without | |
| 7 | * fighting the application chrome. Theme: white, editorial, "site of the | |
| 8 | * future" (2030). Entrance motion is CSS-only and degrades to fully-visible | |
| 9 | * content when JS or animation is unavailable. | |
| 10 | */ | |
| 11 | import type { FC } from "hono/jsx"; | |
| 12 | ||
| 13 | export interface Landing2030Props { | |
| ff0ca55 | 14 | // Reserved for future use. The stat band intentionally shows |
| 15 | // capability metrics rather than live counts so the page reads strong | |
| 16 | // at any scale. | |
| 29924bc | 17 | stats?: { publicRepos?: number; users?: number }; |
| 18 | } | |
| 19 | ||
| 20 | /* ---- small stroke icons (inherit currentColor) ---------------------- */ | |
| 21 | const IconReview: FC = () => ( | |
| 22 | <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.6" | |
| 23 | stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"> | |
| 24 | <path d="M12 3l2.2 4.6L19 8.3l-3.4 3.4.8 4.8L12 14.2 7.6 16.5l.8-4.8L5 8.3l4.8-.7z" /> | |
| 25 | </svg> | |
| 26 | ); | |
| 27 | const IconMerge: FC = () => ( | |
| 28 | <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.6" | |
| 29 | stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"> | |
| 30 | <circle cx="6" cy="6" r="2.4" /><circle cx="6" cy="18" r="2.4" /> | |
| 31 | <circle cx="18" cy="9" r="2.4" /><path d="M6 8.4v7.2M8.3 7.2C13 7.6 15.6 9 15.6 9" /> | |
| 32 | </svg> | |
| 33 | ); | |
| 34 | const IconGate: FC = () => ( | |
| 35 | <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.6" | |
| 36 | stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"> | |
| 37 | <path d="M12 3l7 3v5c0 4.4-3 7.6-7 9-4-1.4-7-4.6-7-9V6z" /><path d="M9 12l2 2 4-4" /> | |
| 38 | </svg> | |
| 39 | ); | |
| 40 | const IconGit: FC = () => ( | |
| 41 | <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.6" | |
| 42 | stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"> | |
| 43 | <circle cx="6" cy="6" r="2.4" /><circle cx="6" cy="18" r="2.4" /> | |
| 44 | <circle cx="18" cy="14" r="2.4" /><path d="M6 8.4v7.2M6 14a8 8 0 008-8h1.8" /> | |
| 45 | </svg> | |
| 46 | ); | |
| 47 | const IconCI: FC = () => ( | |
| 48 | <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.6" | |
| 49 | stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"> | |
| 50 | <path d="M12 3a9 9 0 109 9" /><path d="M12 7v5l3 2" /><path d="M21 3v4h-4" /> | |
| 51 | </svg> | |
| 52 | ); | |
| 53 | const IconIntel: FC = () => ( | |
| 54 | <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.6" | |
| 55 | stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"> | |
| 56 | <path d="M12 3a4 4 0 014 4c1.6.6 2.6 2 2.6 3.8 0 1-.4 2-1 2.7.3.5.4 1.1.4 1.7A3.8 3.8 0 0112 19a3.8 3.8 0 01-6-3.8c0-.6.1-1.2.4-1.7-.6-.7-1-1.7-1-2.7C5.4 9 6.4 7.6 8 7a4 4 0 014-4z" /> | |
| 57 | <path d="M12 3v16" /> | |
| 58 | </svg> | |
| 59 | ); | |
| 60 | ||
| 61 | const FEATURES: { icon: FC; title: string; body: string }[] = [ | |
| 62 | { icon: IconReview, title: "Claude code review", | |
| 63 | body: "Every pull request gets a senior-level review the moment it opens — line-level comments, risk flags, and a verdict, in seconds." }, | |
| 64 | { icon: IconMerge, title: "Merge while you sleep", | |
| 65 | body: "Gates green and review clean? Gluecron merges autonomously. Label an issue at night, wake to a shipped PR." }, | |
| 66 | { icon: IconGate, title: "Push-time gate enforcement", | |
| 67 | body: "Security and quality gates run at the moment of push — not minutes later in CI. Bad code never reaches your branch." }, | |
| 68 | { icon: IconGit, title: "Git-native hosting", | |
| 69 | body: "Full Smart-HTTP git over the wire. Clone, push, fork, and browse — everything you expect from a host, self-owned." }, | |
| 70 | { icon: IconCI, title: "CI that comes built-in", | |
| 71 | body: "No YAML archaeology. Checks, deploys, and post-receive automation are part of the platform, wired from first push." }, | |
| 72 | { icon: IconIntel, title: "Semantic code intelligence", | |
| 73 | body: "A vector-indexed understanding of your whole repo powers search, review, and the agents that act on your behalf." }, | |
| 74 | ]; | |
| 75 | ||
| 76 | const STEPS: { n: string; title: string; body: string }[] = [ | |
| 77 | { n: "01", title: "Label an issue", body: "Drop a label on an issue — or just describe what you want. That's the whole input." }, | |
| 78 | { n: "02", title: "Agents go to work", body: "Claude opens a branch, writes the change, and submits a pull request against your gates." }, | |
| 79 | { n: "03", title: "Reviewed & gated", body: "The PR is reviewed line-by-line and run through push-time security and quality gates." }, | |
| 80 | { n: "04", title: "Merged, autonomously", body: "Green across the board? It merges itself and deploys. You wake up to shipped work." }, | |
| 81 | ]; | |
| 82 | ||
| ff0ca55 | 83 | export const Landing2030Page: FC<Landing2030Props> = () => { |
| 29924bc | 84 | const title = "Gluecron — The git host built for 2030"; |
| 85 | const desc = | |
| 86 | "Gluecron is the AI-native git host. Claude reviews every pull request, gates run at push time, and clean PRs merge while you sleep. Label an issue, walk away, wake up to a merged PR."; | |
| 87 | return ( | |
| 88 | <html lang="en"> | |
| 89 | <head> | |
| 90 | <meta charset="UTF-8" /> | |
| 91 | <meta name="viewport" content="width=device-width, initial-scale=1.0" /> | |
| 92 | <meta name="theme-color" content="#ffffff" /> | |
| 93 | <title>{title}</title> | |
| 94 | <meta name="description" content={desc} /> | |
| 95 | <meta property="og:title" content={title} /> | |
| 96 | <meta property="og:description" content={desc} /> | |
| 97 | <meta property="og:type" content="website" /> | |
| 98 | <meta name="twitter:card" content="summary_large_image" /> | |
| 99 | <link rel="icon" type="image/svg+xml" href="/icon.svg" /> | |
| 100 | <link rel="preconnect" href="https://fonts.googleapis.com" /> | |
| 101 | <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin="" /> | |
| 102 | <link | |
| 103 | rel="stylesheet" | |
| 104 | href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&family=Inter+Tight:wght@500;600;700;800&family=JetBrains+Mono:wght@400;500&display=swap" | |
| 105 | /> | |
| 106 | <style dangerouslySetInnerHTML={{ __html: landing2030Css }} /> | |
| 107 | </head> | |
| 108 | <body> | |
| 109 | {/* ---- nav ---- */} | |
| 110 | <header class="nv" id="nv"> | |
| 111 | <div class="nv-in"> | |
| 112 | <a href="/" class="nv-logo"> | |
| 113 | <span class="nv-mark" aria-hidden="true" /> | |
| 114 | gluecron | |
| 115 | </a> | |
| 116 | <nav class="nv-links" aria-label="Primary"> | |
| 117 | <a href="#features">Product</a> | |
| 118 | <a href="#loop">How it works</a> | |
| 119 | <a href="/pricing">Pricing</a> | |
| 120 | <a href="/explore">Explore</a> | |
| 121 | </nav> | |
| 122 | <div class="nv-cta"> | |
| 123 | <a href="/login" class="btn btn-ghost">Sign in</a> | |
| 124 | <a href="/register" class="btn btn-solid">Start building</a> | |
| 125 | </div> | |
| 126 | </div> | |
| 127 | </header> | |
| 128 | ||
| 129 | {/* ---- hero ---- */} | |
| 130 | <section class="hero"> | |
| 131 | <div class="hero-glow" aria-hidden="true" /> | |
| 132 | <div class="wrap hero-in"> | |
| 133 | <a href="#loop" class="eyebrow rise" style="--d:0ms"> | |
| 134 | <span class="eyebrow-dot" /> The AI-native git host · built for 2030 | |
| 135 | </a> | |
| 136 | <h1 class="display rise" style="--d:60ms"> | |
| 137 | The git host built for <span class="grad">2030</span>. | |
| 138 | </h1> | |
| 139 | <p class="lede rise" style="--d:120ms"> | |
| 140 | Gluecron hosts your code, reviews every pull request with Claude, | |
| 141 | enforces gates at push time, and merges clean work while you sleep. | |
| 142 | Label an issue, walk away, wake up to a merged PR. | |
| 143 | </p> | |
| 144 | <div class="hero-actions rise" style="--d:180ms"> | |
| 145 | <a href="/register" class="btn btn-solid btn-lg">Start building →</a> | |
| 146 | <a href="#loop" class="btn btn-ghost btn-lg">See how it works</a> | |
| 147 | </div> | |
| 148 | <div class="hero-trust rise" style="--d:240ms"> | |
| 149 | Self-hosted · Git-native · Claude-first | |
| 150 | </div> | |
| 151 | ||
| 152 | {/* product card mock */} | |
| 153 | <div class="hero-card rise" style="--d:320ms" aria-hidden="true"> | |
| 154 | <div class="hc-bar"> | |
| 155 | <span class="hc-dot" /><span class="hc-dot" /><span class="hc-dot" /> | |
| 156 | <span class="hc-path">gluecron.com / your-org / api · #128</span> | |
| 157 | </div> | |
| 158 | <div class="hc-body"> | |
| 159 | <div class="hc-pr"> | |
| 160 | <span class="hc-badge hc-merged">✓ Merged</span> | |
| 161 | <span class="hc-prtitle">Fix race condition in token refresh</span> | |
| 162 | </div> | |
| 163 | <div class="hc-review"> | |
| 164 | <span class="hc-ava">C</span> | |
| 165 | <div class="hc-rev-body"> | |
| 166 | <div class="hc-rev-head">Claude review · <em>approved</em></div> | |
| 167 | <div class="hc-rev-text"> | |
| 168 | Mutex now guards the refresh path; the double-fetch under | |
| 169 | contention is resolved. Gates green. Auto-merging. | |
| 170 | </div> | |
| 171 | </div> | |
| 172 | </div> | |
| 173 | <div class="hc-checks"> | |
| 174 | <span class="hc-check ok">● gate: security</span> | |
| 175 | <span class="hc-check ok">● gate: tests</span> | |
| 176 | <span class="hc-check ok">● review: Claude</span> | |
| 177 | <span class="hc-check ok">● deploy: live</span> | |
| 178 | </div> | |
| 179 | </div> | |
| 180 | </div> | |
| 181 | </div> | |
| 182 | </section> | |
| 183 | ||
| 184 | {/* ---- stat band ---- */} | |
| 185 | <section class="stats"> | |
| 186 | <div class="wrap stats-in"> | |
| ff0ca55 | 187 | <div class="stat"><div class="stat-n">< 30s</div><div class="stat-l">to first AI review</div></div> |
| 29924bc | 188 | <div class="stat"><div class="stat-n">24/7</div><div class="stat-l">autonomous merges</div></div> |
| ff0ca55 | 189 | <div class="stat"><div class="stat-n">100%</div><div class="stat-l">push-time gate coverage</div></div> |
| 190 | <div class="stat"><div class="stat-n">Self-owned</div><div class="stat-l">your code, your server</div></div> | |
| 29924bc | 191 | </div> |
| 192 | </section> | |
| 193 | ||
| 194 | {/* ---- features ---- */} | |
| 195 | <section class="sec" id="features"> | |
| 196 | <div class="wrap"> | |
| 197 | <div class="sec-head"> | |
| 198 | <span class="kicker">The platform</span> | |
| 199 | <h2 class="h2">Everything GitHub does. Then everything it doesn't.</h2> | |
| 200 | <p class="sub">A complete git host with code intelligence wired into every step — review, gates, CI, and autonomous merge, native to the platform.</p> | |
| 201 | </div> | |
| 202 | <div class="grid"> | |
| 203 | {FEATURES.map((f) => { | |
| 204 | const Ic = f.icon; | |
| 205 | return ( | |
| 206 | <div class="card"> | |
| 207 | <div class="card-ic"><Ic /></div> | |
| 208 | <h3 class="card-t">{f.title}</h3> | |
| 209 | <p class="card-b">{f.body}</p> | |
| 210 | </div> | |
| 211 | ); | |
| 212 | })} | |
| 213 | </div> | |
| 214 | </div> | |
| 215 | </section> | |
| 216 | ||
| 217 | {/* ---- the loop ---- */} | |
| 218 | <section class="sec sec-alt" id="loop"> | |
| 219 | <div class="wrap"> | |
| 220 | <div class="sec-head"> | |
| 221 | <span class="kicker">The closed loop</span> | |
| 222 | <h2 class="h2">From a label to a shipped PR — untouched by you.</h2> | |
| 223 | <p class="sub">Gluecron closes the loop between intent and production. You set direction; the platform does the round-trip.</p> | |
| 224 | </div> | |
| 225 | <div class="loop"> | |
| 226 | {STEPS.map((s, i) => ( | |
| 227 | <div class="step"> | |
| 228 | <div class="step-n">{s.n}</div> | |
| 229 | <h3 class="step-t">{s.title}</h3> | |
| 230 | <p class="step-b">{s.body}</p> | |
| 231 | {i < STEPS.length - 1 && <span class="step-arrow" aria-hidden="true">→</span>} | |
| 232 | </div> | |
| 233 | ))} | |
| 234 | </div> | |
| 235 | </div> | |
| 236 | </section> | |
| 237 | ||
| 238 | {/* ---- 2030 vision band ---- */} | |
| 239 | <section class="vision"> | |
| 240 | <div class="vision-grid" aria-hidden="true" /> | |
| 241 | <div class="wrap vision-in"> | |
| 242 | <span class="kicker kicker-light">2030</span> | |
| 243 | <h2 class="vh">By 2030, code reviews itself,<br />gates itself, and ships itself.</h2> | |
| 244 | <p class="vsub"> | |
| 245 | The era of babysitting pipelines is ending. Gluecron is built for the | |
| 246 | world that's coming — where engineers set intent and an autonomous | |
| 247 | platform carries it to production, safely, around the clock. We didn't | |
| 248 | bolt AI onto a git host. We rebuilt the git host around it. | |
| 249 | </p> | |
| 250 | <div class="vstats"> | |
| 251 | <div class="vstat"><b>Autonomous</b><span>review → gate → merge → deploy</span></div> | |
| 252 | <div class="vstat"><b>Always on</b><span>your repo never sleeps</span></div> | |
| 253 | <div class="vstat"><b>Self-owned</b><span>your code, your server, your keys</span></div> | |
| 254 | </div> | |
| 255 | </div> | |
| 256 | </section> | |
| 257 | ||
| 258 | {/* ---- differentiator ---- */} | |
| 259 | <section class="sec"> | |
| 260 | <div class="wrap quote-wrap"> | |
| 261 | <p class="quote"> | |
| 262 | “GitHub gives you a place to <em>store</em> code. | |
| 263 | Gluecron gives you a place where code <em>moves on its own.</em>” | |
| 264 | </p> | |
| 265 | </div> | |
| 266 | </section> | |
| 267 | ||
| 268 | {/* ---- final CTA ---- */} | |
| 269 | <section class="cta"> | |
| 270 | <div class="wrap cta-in"> | |
| 271 | <h2 class="cta-h">Start building on the future of git.</h2> | |
| 272 | <p class="cta-sub">Spin up a repository, push a commit, and watch the loop close.</p> | |
| 273 | <div class="hero-actions"> | |
| 274 | <a href="/register" class="btn btn-solid btn-lg">Create your account →</a> | |
| 275 | <a href="/explore" class="btn btn-ghost btn-lg">Explore public repos</a> | |
| 276 | </div> | |
| 277 | </div> | |
| 278 | </section> | |
| 279 | ||
| 280 | {/* ---- footer ---- */} | |
| 281 | <footer class="ft"> | |
| 282 | <div class="wrap ft-in"> | |
| 283 | <div class="ft-brand"> | |
| 284 | <a href="/" class="nv-logo"><span class="nv-mark" aria-hidden="true" />gluecron</a> | |
| 285 | <p class="ft-tag">The AI-native git host. Built for 2030.</p> | |
| 286 | </div> | |
| 287 | <div class="ft-cols"> | |
| 288 | <div class="ft-col"> | |
| 289 | <h4>Product</h4> | |
| 290 | <a href="#features">Features</a> | |
| 291 | <a href="/pricing">Pricing</a> | |
| 292 | <a href="/explore">Explore</a> | |
| 293 | </div> | |
| 294 | <div class="ft-col"> | |
| 295 | <h4>Company</h4> | |
| 296 | <a href="/about">About</a> | |
| 297 | <a href="/login">Sign in</a> | |
| 298 | <a href="/register">Start building</a> | |
| 299 | </div> | |
| 300 | <div class="ft-col"> | |
| 301 | <h4>Account</h4> | |
| 302 | <a href="/login">Log in</a> | |
| 303 | <a href="/register">Register</a> | |
| 304 | <a href="/settings">Settings</a> | |
| 305 | </div> | |
| 306 | </div> | |
| 307 | </div> | |
| 308 | <div class="wrap ft-bottom"> | |
| 309 | <span>© {new Date().getFullYear()} Gluecron</span> | |
| 310 | <span>Self-hosted · Git-native · Claude-first</span> | |
| 311 | </div> | |
| 312 | </footer> | |
| 313 | ||
| 314 | <script dangerouslySetInnerHTML={{ __html: landing2030Js }} /> | |
| 315 | </body> | |
| 316 | </html> | |
| 317 | ); | |
| 318 | }; | |
| 319 | ||
| 320 | export default Landing2030Page; | |
| 321 | ||
| 322 | const landing2030Js = ` | |
| 323 | (function(){ | |
| 324 | var nv = document.getElementById('nv'); | |
| 325 | function onScroll(){ if(!nv) return; nv.classList.toggle('nv-stuck', window.scrollY > 8); } | |
| 326 | window.addEventListener('scroll', onScroll, {passive:true}); onScroll(); | |
| 327 | // additive scroll-reveal: base state is already visible, this only enhances | |
| 328 | if ('IntersectionObserver' in window && !window.matchMedia('(prefers-reduced-motion: reduce)').matches){ | |
| 329 | var io = new IntersectionObserver(function(es){ | |
| 330 | es.forEach(function(e){ if(e.isIntersecting){ e.target.classList.add('seen'); io.unobserve(e.target); } }); | |
| 331 | }, {threshold:0.12}); | |
| 332 | document.querySelectorAll('.card,.step,.stat,.vstat').forEach(function(el){ el.classList.add('reveal'); io.observe(el); }); | |
| 333 | } | |
| 334 | })(); | |
| 335 | `; | |
| 336 | ||
| 337 | const landing2030Css = ` | |
| 338 | :root{ | |
| 339 | --bg:#ffffff; --bg-soft:#fafafb; --ink:#0a0b0d; --ink-2:#3a3d45; | |
| 340 | --muted:#676d78; --line:rgba(13,16,23,.08); --line-2:rgba(13,16,23,.12); | |
| 341 | --brand:#5b5bf6; --brand-2:#7c4dff; --brand-3:#2f6bff; | |
| 342 | --grad:linear-gradient(100deg,#7c4dff 0%,#5b5bf6 45%,#2f6bff 100%); | |
| 343 | --radius:16px; --shadow:0 1px 2px rgba(13,16,23,.04),0 12px 32px rgba(13,16,23,.06); | |
| 344 | --maxw:1140px; | |
| 345 | } | |
| 346 | *{box-sizing:border-box} | |
| 347 | html{scroll-behavior:smooth} | |
| 348 | body{margin:0;background:var(--bg);color:var(--ink); | |
| 349 | font-family:'Inter',-apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif; | |
| 350 | font-size:17px;line-height:1.6;-webkit-font-smoothing:antialiased;text-rendering:optimizeLegibility} | |
| 351 | a{color:inherit;text-decoration:none} | |
| 352 | .wrap{max-width:var(--maxw);margin:0 auto;padding:0 24px} | |
| 353 | .display,.h2,.vh,.cta-h{font-family:'Inter Tight','Inter',sans-serif;letter-spacing:-.02em;font-weight:700} | |
| 354 | .grad{background:var(--grad);-webkit-background-clip:text;background-clip:text;color:transparent} | |
| 355 | ||
| 356 | /* nav */ | |
| 357 | .nv{position:sticky;top:0;z-index:50;backdrop-filter:saturate(180%) blur(12px); | |
| 358 | background:rgba(255,255,255,.72);border-bottom:1px solid transparent;transition:border-color .2s,box-shadow .2s,background .2s} | |
| 359 | .nv-stuck{border-bottom-color:var(--line);box-shadow:0 1px 0 rgba(13,16,23,.02)} | |
| 360 | .nv-in{max-width:var(--maxw);margin:0 auto;padding:14px 24px;display:flex;align-items:center;gap:24px} | |
| 361 | .nv-logo{display:inline-flex;align-items:center;gap:9px;font-family:'Inter Tight',sans-serif;font-weight:700;font-size:19px;letter-spacing:-.02em} | |
| 362 | .nv-mark{width:18px;height:18px;border-radius:6px;background:var(--grad);box-shadow:0 2px 8px rgba(92,91,246,.4);display:inline-block} | |
| 363 | .nv-links{display:flex;gap:26px;margin-left:14px} | |
| 364 | .nv-links a{color:var(--ink-2);font-size:15px;font-weight:500;transition:color .15s} | |
| 365 | .nv-links a:hover{color:var(--ink)} | |
| 366 | .nv-cta{margin-left:auto;display:flex;align-items:center;gap:10px} | |
| 367 | .btn{display:inline-flex;align-items:center;gap:6px;border-radius:10px;font-weight:600;font-size:15px; | |
| 368 | padding:9px 16px;cursor:pointer;transition:transform .12s,box-shadow .2s,background .2s,border-color .2s;border:1px solid transparent;white-space:nowrap} | |
| 369 | .btn:hover{transform:translateY(-1px)} | |
| 370 | .btn-solid{background:var(--ink);color:#fff} | |
| 371 | .btn-solid:hover{box-shadow:0 8px 22px rgba(13,16,23,.18)} | |
| 372 | .btn-ghost{color:var(--ink);border-color:var(--line-2);background:rgba(255,255,255,.6)} | |
| 373 | .btn-ghost:hover{border-color:var(--ink);background:#fff} | |
| 374 | .btn-lg{padding:13px 22px;font-size:16px;border-radius:12px} | |
| 375 | ||
| 376 | /* hero */ | |
| 377 | .hero{position:relative;overflow:hidden;padding:84px 0 40px;text-align:center} | |
| 378 | .hero-glow{position:absolute;inset:-20% 0 auto 0;height:620px;z-index:0;pointer-events:none; | |
| 379 | background:radial-gradient(60% 60% at 50% 0%,rgba(124,77,255,.18),transparent 70%), | |
| 380 | radial-gradient(40% 50% at 75% 10%,rgba(47,107,255,.14),transparent 70%), | |
| 381 | radial-gradient(40% 50% at 25% 10%,rgba(91,91,246,.12),transparent 70%)} | |
| 382 | .hero-in{position:relative;z-index:1;display:flex;flex-direction:column;align-items:center} | |
| 383 | .eyebrow{display:inline-flex;align-items:center;gap:8px;font-size:13.5px;font-weight:600;color:var(--ink-2); | |
| 384 | background:#fff;border:1px solid var(--line-2);border-radius:999px;padding:7px 14px;box-shadow:var(--shadow)} | |
| 385 | .eyebrow-dot{width:7px;height:7px;border-radius:50%;background:var(--grad)} | |
| 386 | .display{font-size:clamp(40px,7vw,76px);line-height:1.02;margin:26px 0 0;max-width:14ch} | |
| 387 | .lede{font-size:clamp(17px,2.2vw,21px);color:var(--muted);max-width:60ch;margin:22px auto 0;font-weight:450} | |
| 388 | .hero-actions{display:flex;gap:12px;flex-wrap:wrap;justify-content:center;margin-top:30px} | |
| 389 | .hero-trust{margin-top:18px;font-size:13px;font-weight:600;letter-spacing:.04em;text-transform:uppercase;color:var(--muted)} | |
| 390 | ||
| 391 | /* hero card */ | |
| 392 | .hero-card{margin:54px auto 0;max-width:760px;width:100%;text-align:left;background:#fff; | |
| 393 | border:1px solid var(--line);border-radius:18px;box-shadow:0 30px 70px -30px rgba(13,16,23,.28),var(--shadow);overflow:hidden} | |
| 394 | .hc-bar{display:flex;align-items:center;gap:7px;padding:12px 16px;border-bottom:1px solid var(--line);background:var(--bg-soft)} | |
| 395 | .hc-dot{width:11px;height:11px;border-radius:50%;background:#dfe1e6} | |
| 396 | .hc-path{margin-left:10px;font-family:'JetBrains Mono',monospace;font-size:12.5px;color:var(--muted)} | |
| 397 | .hc-body{padding:20px} | |
| 398 | .hc-pr{display:flex;align-items:center;gap:12px} | |
| 399 | .hc-badge{font-size:12.5px;font-weight:700;padding:4px 10px;border-radius:999px} | |
| 400 | .hc-merged{background:rgba(91,91,246,.1);color:#5b5bf6} | |
| 401 | .hc-prtitle{font-weight:600;font-size:15.5px} | |
| 402 | .hc-review{display:flex;gap:12px;margin-top:18px;padding:14px;border:1px solid var(--line);border-radius:12px;background:var(--bg-soft)} | |
| 403 | .hc-ava{flex:none;width:30px;height:30px;border-radius:8px;background:var(--grad);color:#fff;font-weight:700; | |
| 404 | display:grid;place-items:center;font-size:14px} | |
| 405 | .hc-rev-head{font-size:13.5px;font-weight:600;color:var(--ink-2)} | |
| 406 | .hc-rev-head em{color:#5b5bf6;font-style:normal} | |
| 407 | .hc-rev-text{font-size:14px;color:var(--muted);margin-top:3px} | |
| 408 | .hc-checks{display:flex;flex-wrap:wrap;gap:8px;margin-top:16px} | |
| 409 | .hc-check{font-family:'JetBrains Mono',monospace;font-size:12px;padding:5px 10px;border-radius:8px;border:1px solid var(--line);color:var(--ink-2)} | |
| 410 | .hc-check.ok{color:#2c8a52}.hc-check.ok::first-letter{color:#2c8a52} | |
| 411 | ||
| 412 | /* stats */ | |
| 413 | .stats{border-top:1px solid var(--line);border-bottom:1px solid var(--line);background:var(--bg-soft)} | |
| 414 | .stats-in{display:grid;grid-template-columns:repeat(4,1fr);gap:24px;padding:40px 24px} | |
| 415 | .stat{text-align:center} | |
| 416 | .stat-n{font-family:'Inter Tight',sans-serif;font-weight:800;font-size:clamp(28px,4vw,40px);letter-spacing:-.02em} | |
| 417 | .stat-l{font-size:13.5px;color:var(--muted);margin-top:4px} | |
| 418 | ||
| 419 | /* sections */ | |
| 420 | .sec{padding:92px 0} | |
| 421 | .sec-alt{background:var(--bg-soft);border-top:1px solid var(--line);border-bottom:1px solid var(--line)} | |
| 422 | .sec-head{max-width:680px;margin:0 auto 52px;text-align:center} | |
| 423 | .kicker{display:inline-block;font-size:13px;font-weight:700;letter-spacing:.08em;text-transform:uppercase; | |
| 424 | color:#5b5bf6;margin-bottom:14px} | |
| 425 | .h2{font-size:clamp(28px,4.4vw,46px);line-height:1.08;margin:0} | |
| 426 | .sub{color:var(--muted);font-size:18px;margin:16px auto 0;max-width:56ch} | |
| 427 | ||
| 428 | /* feature grid */ | |
| 429 | .grid{display:grid;grid-template-columns:repeat(3,1fr);gap:18px} | |
| 430 | .card{background:#fff;border:1px solid var(--line);border-radius:var(--radius);padding:26px;transition:transform .18s,box-shadow .25s,border-color .2s} | |
| 431 | .card:hover{transform:translateY(-3px);box-shadow:var(--shadow);border-color:var(--line-2)} | |
| 432 | .card-ic{width:42px;height:42px;border-radius:11px;display:grid;place-items:center;color:#5b5bf6; | |
| 433 | background:rgba(91,91,246,.09);border:1px solid rgba(91,91,246,.14);margin-bottom:16px} | |
| 434 | .card-ic svg{width:22px;height:22px} | |
| 435 | .card-t{font-size:18px;font-weight:600;margin:0 0 7px;font-family:'Inter Tight',sans-serif;letter-spacing:-.01em} | |
| 436 | .card-b{color:var(--muted);font-size:15px;margin:0;line-height:1.6} | |
| 437 | ||
| 438 | /* loop */ | |
| 439 | .loop{display:grid;grid-template-columns:repeat(4,1fr);gap:18px} | |
| 440 | .step{position:relative;background:#fff;border:1px solid var(--line);border-radius:var(--radius);padding:24px} | |
| 441 | .step-n{font-family:'JetBrains Mono',monospace;font-size:13px;font-weight:600;color:#5b5bf6;margin-bottom:12px} | |
| 442 | .step-t{font-size:17px;font-weight:600;margin:0 0 6px;font-family:'Inter Tight',sans-serif} | |
| 443 | .step-b{color:var(--muted);font-size:14.5px;margin:0} | |
| 444 | .step-arrow{position:absolute;right:-13px;top:50%;transform:translateY(-50%);color:var(--line-2);font-size:20px;z-index:2} | |
| 445 | ||
| 446 | /* vision band */ | |
| 447 | .vision{position:relative;overflow:hidden;padding:104px 0;color:#fff;text-align:center; | |
| 448 | background:radial-gradient(120% 120% at 50% -10%,#2a2350 0%,#15122b 45%,#0a0913 100%)} | |
| 449 | .vision-grid{position:absolute;inset:0;opacity:.5; | |
| 450 | background-image:linear-gradient(rgba(255,255,255,.06) 1px,transparent 1px),linear-gradient(90deg,rgba(255,255,255,.06) 1px,transparent 1px); | |
| 451 | background-size:54px 54px;mask-image:radial-gradient(80% 80% at 50% 0%,#000,transparent 75%)} | |
| 452 | .vision-in{position:relative;z-index:1;display:flex;flex-direction:column;align-items:center} | |
| 453 | .kicker-light{color:#b7a8ff} | |
| 454 | .vh{font-size:clamp(30px,5vw,54px);line-height:1.08;margin:0;letter-spacing:-.02em} | |
| 455 | .vsub{color:rgba(255,255,255,.74);font-size:18px;max-width:62ch;margin:22px auto 0} | |
| 456 | .vstats{display:flex;gap:40px;flex-wrap:wrap;justify-content:center;margin-top:42px} | |
| 457 | .vstat{display:flex;flex-direction:column;gap:3px} | |
| 458 | .vstat b{font-family:'Inter Tight',sans-serif;font-size:19px} | |
| 459 | .vstat span{color:rgba(255,255,255,.6);font-size:13.5px} | |
| 460 | ||
| 461 | /* quote */ | |
| 462 | .quote-wrap{max-width:860px;margin:0 auto;text-align:center} | |
| 463 | .quote{font-family:'Inter Tight',sans-serif;font-weight:600;font-size:clamp(24px,3.6vw,38px); | |
| 464 | line-height:1.25;letter-spacing:-.02em;margin:0} | |
| 465 | .quote em{font-style:normal;background:var(--grad);-webkit-background-clip:text;background-clip:text;color:transparent} | |
| 466 | ||
| 467 | /* cta */ | |
| 468 | .cta{padding:96px 0} | |
| 469 | .cta-in{max-width:720px;margin:0 auto;text-align:center;background:#fff;border:1px solid var(--line); | |
| 470 | border-radius:24px;padding:56px 32px;box-shadow:var(--shadow);position:relative;overflow:hidden} | |
| 471 | .cta-in::before{content:"";position:absolute;inset:-40% 0 auto 0;height:260px; | |
| 472 | background:radial-gradient(50% 60% at 50% 0%,rgba(124,77,255,.16),transparent 70%);pointer-events:none} | |
| 473 | .cta-h{font-size:clamp(28px,4.4vw,44px);margin:0;position:relative} | |
| 474 | .cta-sub{color:var(--muted);font-size:18px;margin:14px 0 28px;position:relative} | |
| 475 | .cta .hero-actions{position:relative} | |
| 476 | ||
| 477 | /* footer */ | |
| 478 | .ft{border-top:1px solid var(--line);background:var(--bg-soft);padding:56px 0 28px} | |
| 479 | .ft-in{display:flex;gap:40px;flex-wrap:wrap;justify-content:space-between} | |
| 480 | .ft-tag{color:var(--muted);font-size:14px;margin:12px 0 0;max-width:30ch} | |
| 481 | .ft-cols{display:flex;gap:64px;flex-wrap:wrap} | |
| 482 | .ft-col{display:flex;flex-direction:column;gap:10px} | |
| 483 | .ft-col h4{font-size:13px;text-transform:uppercase;letter-spacing:.06em;color:var(--muted);margin:0 0 4px;font-weight:700} | |
| 484 | .ft-col a{color:var(--ink-2);font-size:14.5px;transition:color .15s} | |
| 485 | .ft-col a:hover{color:var(--ink)} | |
| 486 | .ft-bottom{display:flex;justify-content:space-between;flex-wrap:wrap;gap:8px; | |
| 487 | margin-top:40px;padding-top:22px;border-top:1px solid var(--line);color:var(--muted);font-size:13px} | |
| 488 | ||
| 489 | /* entrance + reveal */ | |
| 490 | @keyframes rise{from{opacity:0;transform:translateY(14px)}to{opacity:1;transform:none}} | |
| 491 | .rise{animation:rise .7s cubic-bezier(.22,.61,.36,1) backwards;animation-delay:var(--d,0ms)} | |
| 492 | .reveal{opacity:0;transform:translateY(16px);transition:opacity .6s ease,transform .6s cubic-bezier(.22,.61,.36,1)} | |
| 493 | .reveal.seen{opacity:1;transform:none} | |
| 494 | ||
| 495 | /* responsive */ | |
| 496 | @media(max-width:900px){ | |
| 497 | .grid,.loop{grid-template-columns:repeat(2,1fr)} | |
| 498 | .stats-in{grid-template-columns:repeat(2,1fr);gap:28px 16px} | |
| 499 | .step-arrow{display:none} | |
| 500 | .nv-links{display:none} | |
| 501 | } | |
| 502 | @media(max-width:560px){ | |
| 503 | .grid,.loop{grid-template-columns:1fr} | |
| 504 | .hero{padding:56px 0 24px} | |
| 505 | .ft-cols{gap:36px} | |
| 506 | } | |
| 507 | @media(prefers-reduced-motion:reduce){ | |
| 508 | .rise,.reveal{animation:none!important;opacity:1!important;transform:none!important} | |
| 509 | html{scroll-behavior:auto} | |
| 510 | } | |
| 511 | `; |